【JavaWeb】书城项目之与数据库交互的登录案例实现

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 【JavaWeb】书城项目之与数据库交互的登录案例实现

 👉引言💎


学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。 热爱写作,愿意让自己成为更好的人............

铭记于心
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉


准备工作


项目源代码

链接pan.baidu.com/s/1Uj3Q9swg…

提取码:1314


首先更改前端页面中的url路径


0a2653c851af460fa595bd959398a8f1.png


三层架构


为什么要使用三层架构


所有和当前业务功能需求相关的代码全部耦合在一起,如果其中有任何一个部分出现了问题,牵一发而动全身,导致其他无关代码也要进行相应的修改。这样的话代码会非常难以维护。

所以为了提高开发效率,需要对代码进行模块化的拆分。整个项目模块化、组件化程度越高,越容易管理和维护,出现问题更容易排查。


三层架构的划分


  • 表述层:又可以称之为控制层,负责处理浏览器请求、返回响应、页面调度
  • 业务逻辑层:负责处理业务逻辑,根据业务逻辑把持久化层从数据库查询出来的数据进行运算、组装,封装好后返回给表述层,也可以根据业务功能的需要调用持久化层把数据保存到数据库、修改数据库中的数据、删除数据库中的数据
  • 持久化层:根据上一层的调用对数据库中的数据执行增删改查的操作


三层架构和数据模型的关系


0eacb84100b54626af849e6b562bf92a.png

模型对整个项目中三层架构的每一层都提供支持,具体体现是使用模型对象封装业务功能数据

其实数据模型就是我们之前学习的JavaBean,也是Java实体类,当然他还有很多其他的名称:

  • POJO:Plain old Java Object,传统的普通的Java对象
  • entity:实体类
  • bean或Java bean
  • domain:领域模型


持久层操作


创建数据库


2d65d23f6d4748949b924e4057485923.png


封装工具类


封装JDBCUtils


将druid连接池与jdbc操作封装成工具类


package com.example.WebGo.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtils {
    private static DataSource dataSource;
    static {
        // 1.创建一个用于存储外部属性文件信息的Properties对象
        Properties properties = new Properties();
        // 2.使用当前类的类加载器加载外部属性文件:jdbc.properties
        InputStream inputStream = com.example.WebGo.utils.JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            // 3.将外部属性文件jdbc.properties中的数据加载到properties对象中
            properties.load(inputStream);
            // 4.创建数据源对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 从数据源中获取数据库连接
     *
     * @return 数据库连接对象
     */
    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return connection;
    }
    /**
     * 释放数据库连接
     *
     * @param connection 要执行释放操作的连接对象
     */
    public static void releaseConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
    }
}


配置文件


driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/WebGo
username=root
password=123456
initialSize=10
maxActive=20
maxWait=10000


封装DButils为Dao基类


import com.example.WebGo.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.time.Clock;
import java.util.List;
public class BaseDao<T> {
   private QueryRunner queryRunner= new QueryRunner();
   public int update(String sql,Object...params){
       try {
           int update = queryRunner.update(JDBCUtils.getConnection(), sql, params);
           return update;
       } catch (SQLException throwables) {
           throwables.printStackTrace();
           throw new RuntimeException();
       }
   }
   public T getBean(Class<T>clasz,String sql,Object...params){
       try {
          return queryRunner.query(JDBCUtils.getConnection(), sql, new BeanHandler<>(clasz),params);
       } catch (SQLException throwables) {
           throwables.printStackTrace();
           throw new RuntimeException();
       }
   }
    public List<T> getBeanList(Class<T>clasz, String sql, Object...params){
        try {
            return queryRunner.query(JDBCUtils.getConnection(), sql, new BeanListHandler<>(clasz),params);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException();
        }
    }
}


实现用户dao类


package com.example.WebGo.dao.impl;
import com.example.WebGo.dao.BaseDao;
import com.example.WebGo.dao.api.Userdao;
import com.example.WebGo.entity.User;
import java.sql.SQLException;
public class Userdaoimpl extends BaseDao<User> implements Userdao {
    @Override
    public User findByUsername(String username) throws SQLException {
        String sql="select user_id userId,user_name username,user_pwd userPwd,email from t_user where user_name=?";
        User user = getBean(User.class,sql,username);
        return user;
    }
    @Override
    public void addUser(User user) throws SQLException {
        String sql="insert into t_user (user_name,user_pwd,email) values (?,?,?)";
       update(sql,user.getUserName(),user.getUserPwd(),user.getEmail());
    }
}


测试


0a2653c851af460fa595bd959398a8f1.png0eacb84100b54626af849e6b562bf92a.png


封装MD5Utils加密工具类


由于下面登录时 我们需要对用户输入的密码信息 进行加密处理,所以在这里实现一个MD5工具类的封装,该代码直接复制粘贴即可,无需过多关注

public class MD5Util {
    /**
     * 针对明文字符串执行MD5加密
     * @param source
     * @return
     */
    public static String encode(String source) {
        // 1.判断明文字符串是否有效
        if (source == null || "".equals(source)) {
            throw new RuntimeException("用于加密的明文不可为空");
        }
        // 2.声明算法名称
        String algorithm = "md5";
        // 3.获取MessageDigest对象
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 4.获取明文字符串对应的字节数组
        byte[] input = source.getBytes();
        // 5.执行加密
        byte[] output = messageDigest.digest(input);
        // 6.创建BigInteger对象
        int signum = 1;
        BigInteger bigInteger = new BigInteger(signum, output);
        // 7.按照16进制将bigInteger的值转换为字符串
        int radix = 16;
        String encoded = bigInteger.toString(radix).toUpperCase();
        return encoded;
    }
}


业务逻辑层操作


开发中对业务代码返回值的介绍


  • 方法的返回值应该对应这个方法本身的业务功能
  • 写操作:没有返回值
  • 读操作:有返回值,返回值就是查询的结果
  • 方法执行是否成功
  • 成功:不抛异常
  • 失败:抛异常
  • 最好失败便是抛异常,不要返回布尔类型


登录与注册的业务逻辑处理


public class UserServiceimpl implements UserService {
  private Userdao userdao= new Userdaoimpl();
   @Override
    public void doRegister(User userForm) throws Exception {
       User user = userdao.findByUsername(userForm.getUserName());
       if(user!=null){
            throw new RuntimeException("用户名已存在");
       }
       String olduserPwd=userForm.getUserPwd();
       String encode = MD5Util.encode(olduserPwd);
       userForm.setUserPwd(encode);
       userdao.addUser(userForm);
   }
    @Override
    public User doLogin(User parameterUser) throws Exception {
        //1. 调用dao层的方法根据用户名查询用户信息
        User loginUser = userdao.findByUsername(parameterUser.getUserName());
        //2. 判断loginUser是否为空
        if (loginUser != null) {
            //说明用户名正确,那么接下来校验密码
            //parameterUser中的密码是用户输入的密码,我们对其进行MD5加密,完之后跟loginUser中的密码(数据库中的密码)进行比对
            String encodePwd = MD5Util.encode(parameterUser.getUserPwd());//加密之后的用户输入的密码
            String dbPwd = loginUser.getUserPwd();//数据库中的密码
            if (dbPwd.equals(encodePwd)) {
                //说明密码正确,登录成功,返回loginUser对象
                return loginUser;
            }else {
                //密码错误
                throw new RuntimeException("密码错误");
            }
        }
        throw new RuntimeException("用户名错误");
    }
}


表现层(接收请求并响应)


0a2653c851af460fa595bd959398a8f1.png

public class RigisterServlet extends HttpServlet {
    UserService userService = new UserServiceimpl();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");
        Map<String, String[]> map = request.getParameterMap();
        map.forEach((a,b)->{
            for(String str:b)
            { System.out.println(a+"="+b);}
        });
        User user = new User();
        try {
            BeanUtils.populate(user, map);
            System.out.println(user);
            userService.doRegister(user);
            response.sendRedirect(request.getContextPath() + "/pages/user/regist_success.html");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().write("注册失败!!!" + e.getMessage());
        }
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

0eacb84100b54626af849e6b562bf92a.png

public class LoginServlet extends HttpServlet {
UserService userService=  new UserServiceimpl();
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");
      User user = new User();
      Map<String, String[]> map = request.getParameterMap();
      try {
          BeanUtils.populate(user,map);
          User User = userService.doLogin(user);
          response.sendRedirect(request.getContextPath()+"/pages/user/Login_success.html");
      } catch (Exception e) {
          e.printStackTrace();
          response.getWriter().write("登陆失败!!!"+e.getMessage());
      }
  }
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
  }
}
复制代码


案例效果


登陆


2d65d23f6d4748949b924e4057485923.png2e9b90b2ca334476abebe75bafe6eeaa.png



用户名检测


4cebaac233b3433da32a72337a77fc60.png

image.png


注册



0a2653c851af460fa595bd959398a8f1.png0eacb84100b54626af849e6b562bf92a.png

🌹写在最后💖: 路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹


相关文章
|
15天前
|
SQL 数据库
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
SQL Server附加数据库出现错误823,附加数据库失败。数据库没有备份,无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有:数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面、断电或者文件系统问题导致页面丢失。
82 12
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
|
9天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
11天前
|
Java 关系型数据库 MySQL
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术的房屋租赁系统,旨在通过自动化和信息化手段提升房屋管理效率,优化租户体验。系统采用JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Layui和Spring Boot 2.0等技术栈,实现了高效的房源管理和便捷的租户服务。通过该系统,房东可以轻松管理房源,租户可以快速找到合适的住所,双方都能享受数字化带来的便利。未来,系统将持续优化升级,提供更多完善的服务。
毕设项目&课程设计&毕设项目:springboot+jsp实现的房屋租租赁系统(含教程&源码&数据库数据)
|
17天前
|
Oracle 关系型数据库 数据库
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
打开oracle数据库报错“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。 数据库没有备份,无法通过备份去恢复数据库。用户方联系北亚企安数据恢复中心并提供Oracle_Home目录中的所有文件,急需恢复zxfg用户下的数据。 出现“system01.dbf需要更多的恢复来保持一致性”这个报错的原因可能是控制文件损坏、数据文件损坏,数据文件与控制文件的SCN不一致等。数据库恢复工程师对数据库文件进一步检测、分析后,发现sysaux01.dbf文件损坏,有坏块。 修复并启动数据库后仍然有许多查询报错,export和data pump工具使用报错。从数据库层面无法修复数据库。
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
|
2天前
|
Java 关系型数据库 数据库连接
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第3天】Spring Boot项目中数据库连接问题可能源于配置错误或依赖缺失。YAML配置文件的格式不正确,如缩进错误,会导致解析失败;而数据库驱动不匹配、连接字符串或认证信息错误同样引发连接异常。解决方法包括检查并修正YAML格式,确认配置属性无误,以及添加正确的数据库驱动依赖。利用日志记录和异常信息分析可辅助问题排查。
22 10
|
5天前
|
Oracle 关系型数据库 数据库
Oracle数据恢复—异常断电导致Oracle数据库数据丢失的数据恢复案例
Oracle数据库故障: 机房异常断电后,Oracle数据库启库报错:“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。数据库没有备份,归档日志不连续。用户方提供了Oracle数据库的在线文件,需要恢复zxfg用户的数据。 Oracle数据库恢复方案: 检测数据库故障;尝试挂起并修复数据库;解析数据文件。
|
1天前
|
Java 关系型数据库 MySQL
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第4天】本文分析了Spring Boot应用在连接数据库时可能遇到的问题及其解决方案。主要从四个方面探讨:配置文件格式错误、依赖缺失或版本不兼容、数据库服务问题、配置属性未正确注入。针对这些问题,提供了详细的检查方法和调试技巧,如检查YAML格式、验证依赖版本、确认数据库服务状态及用户权限,并通过日志和断点调试定位问题。
|
6天前
|
存储 数据挖掘 数据库
服务器数据恢复—raid磁盘故障导致数据库数据损坏的数据恢复案例
存储中有一组由3块SAS硬盘组建的raid。上层win server操作系统层面划分了3个分区,数据库存放在D分区,备份存放在E分区。 RAID中一块硬盘的指示灯亮红色,D分区无法识别;E分区可识别,但是拷贝文件报错。管理员重启服务器,导致离线的硬盘上线开始同步数据,同步还没有完成就直接强制关机了,之后就没有动过服务器。
|
10天前
|
存储 数据库 Python
python的对象数据库ZODB的使用(python3经典编程案例)
该文章介绍了如何使用Python的对象数据库ZODB来进行数据存储,包括ZODB的基本操作如创建数据库、存储和检索对象等,并提供了示例代码。
16 0
|
10天前
|
JSON NoSQL 数据库
和SQLite数据库对应的NoSQL数据库:TinyDB的详细使用(python3经典编程案例)
该文章详细介绍了TinyDB这一轻量级NoSQL数据库的使用方法,包括如何在Python3环境中安装、创建数据库、插入数据、查询、更新以及删除记录等操作,并提供了多个编程案例。
24 0
下一篇
无影云桌面