书城项目_第二阶段_注册、登录功能实现(连接数据库)

用户注册和登录的实现:

需求1:用户注册

需求如下:

  1. 访问注册页面
  2. 填写注册信息,提交给服务器
  3. 服务器保存用户
  4. 当用户已经存在——提示用户注册失败,用户名已存在
  5. 当用户名不存在——注册成功

需求2:用户登录

需求如下:

  1. 访问登陆页面
  2. 填写用户名密码后提交
  3. 服务器判断用户是否存在
  4. 如果登陆失败 ——返回用户名或者密码错误信息
  5. 如果登录成功 ——返回登陆成功 信息

项目的三层架构

在这里插入图片描述

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。

在这里插入图片描述
在这里插入图片描述

1、先创建书城需要的数据库和表。

drop database if exists book;
create database book;
use book;
create table t_user(
`id` int primary key auto_increment,
`username` varchar(20) not null unique,
`password` varchar(32) not null,
`email` varchar(200)
);
insert into t_user(`username`,`password`,`email`) values('admin','admin','admin@atguigu.com');
select * from t_user;

2 、编写数据库表对应的 JavaBean 对象。 对象。

package com.atguigu.pojo;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", email='" + email + '\'' +
                '}';
    }

    public User() {
    }

    public User(Integer id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }
}

3、编写工具类 JdbcUtils

3.1 、导入需要的 jar 包(数据库和连接池需要):

在这里插入图片描述

3.2 、在 src 源码目录下编写 jdbc.properties 属性配置文件:
username=root		
password=123456							//自己设的密码
url=jdbc:mysql://localhost:3306/book	//数据库路径
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10
3.3 、编写 JdbcUtils 工具类:
package com.atguigu.utils;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.util.JdbcUtils;

import javax.sql.rowset.JdbcRowSet;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtile {
    private static DruidDataSource dataSource;
    static{
        try {
            Properties properties=new Properties();
//          读取jdbc.properties属性配置文件
            InputStream inputStream= JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//            从流中加载数据
            properties.load(inputStream);
//            创建数据连接池
            dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//    获取数据库连接池中的连接
    public static Connection getConnection(){
        Connection conn=null;
        try {
            conn=dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
//    关闭连接,返回数据库连接池
    public static void close(Connection conn){
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

4、编写 BaseDao

4.1 、导入 DBUtils 的 的 jar 包

在这里插入图片描述

4.2 、编写 BaseDao:
package com.atguigu.dao.impl;

import com.atguigu.utils.JdbcUtile;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public abstract class BaseDao {
	// 使用 DbUtils 操作数据库
    private QueryRunner queryRunner=new QueryRunner();

	/**
	* update() 方法用来执行: Insert\Update\Delete 语句
	*
	* @return 如果返回 -1, 说明执行失败 <br/> 返回其他表示影响的行数
	*/
    public int update(String sql,Object...args){
        Connection connection= JdbcUtile.getConnection();
        try {
            return queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtile.close(connection);
        }
        return -1;
    }

	/**
	* 查询返回一个 javaBean 的 sql 语句
	*
	* @param type 返回的对象类型
	* @param sql 执行的 sql 语句
	* @param args sql 对应的参数值
	* @param <T> 返回的类型的泛型
	* @return
	*/
    public<T> T  queryForOne(Class<T> type,String sql,Object...args){
        Connection con=JdbcUtile.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtile.close(con);
        }
        return null;
    }
	
	/**
	* 查询返回多个 javaBean 的 sql 语句
	*
	* @param type 返回的对象类型
	* @param sql 执行的 sql 语句
	* @param args sql 对应的参数值
	* @param <T> 返回的类型的泛型
	* @return
	*/
    public <T> List<T> queryForList(Class<T> type, String sql, Object...args){
        Connection con=JdbcUtile.getConnection();
        try {
            return queryRunner.query(con,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtile.close(con);
        }
        return null;
    }
	
	/**
	* 执行返回一行一列的 sql 语句
	* @param sql 执行的 sql 语句
	* @param args sql 对应的参数值
	* @return
	*/
    public Object queryForSingleValue(String sql,Object...args){
        Connection conn=JdbcUtile.getConnection();
        try {
           return  queryRunner.query(conn,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtile.close(conn);
        }
        return null;
    }
}

5 、编写 UserDao 和测试

UserDao 接口:
package com.atguigu.dao;

import com.atguigu.pojo.User;

public interface UserDao {

//    根据用户名查询用户信息
    public User queryUserByUsername(String username);
    //    根据用户名和密码查询用户信息
    public User queryUserByUsernameAndPassword(String username,String password);
//    保存用户信息
    public int saveUser(User user);
}

UserDaoImpl 实现类:
package com.atguigu.dao.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.pojo.User;

public class UserDaoImpl extends BaseDao implements UserDao {
    @Override
    public User queryUserByUsername(String username) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=?";
        return queryForOne(User.class,sql,username);
    }

    @Override
    public User queryUserByUsernameAndPassword(String username, String password) {
        String sql="select `id`,`username`,`password`,`email` from t_user where username=? and password=?";
        return queryForOne(User.class,sql,username,password);
    }

    @Override
    public int saveUser(User user) {
        String sql="insert into t_user(`username`,`password`,`email`) values(?,?,?)";
        return update(sql,user.getUsername(),user.getPassword(),user.getEmail());
    }
}

6 、编写 UserService 和测试

UserService 接口:
package com.atguigu.service;

import com.atguigu.pojo.User;

public interface UserService {
		/**
		* 注册用户
		* @param user
		*/
         public void registUser(User user);
		/**
		* 登录
		* @param user
		* @return 如果返回 null ,说明登录失败,返回有值,是登录成功
		*/
         public User login(User user);
		/**
		* 检查 用户名是否可用
		* @param username
		* @return 返回 true 表示用户名已存在,返回 false 表示用户名可用
		*/
         public boolean existsUsername(String username);
         
}

UserServiceImpl 实现类:
package com.atguigu.service.impl;

import com.atguigu.dao.UserDao;
import com.atguigu.dao.impl.UserDaoImpl;
import com.atguigu.pojo.User;
import com.atguigu.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
//    注册
    @Override
    public void registUser(User user) {
        userDao.saveUser(user);
    }
//登录
    @Override
    public User login(User user) {
        return userDao.queryUserByUsernameAndPassword(user.getUsername(),user.getPassword());
    }
//是否已经存在
    @Override
    public boolean existsUsername(String username) {
        if(userDao.queryUserByUsername(username)==null){
            return false;
        }
        return true;
    }
}

7 、编写 web 层

7.1 、实现用户注册的功能
7.1.1 、图解用户注册的流程:

在这里插入图片描述

7.1.2 、修改 regist.html 和 regist_success.html 页面

1、添加 base 标签

<!-- 写 base 标签,永远固定相对路径跳转的结果 -->
<base href="http://localhost:8080/book">

2、修改 base 标签对页面中所有相对路径的影响(浏览器 F12,哪个报红,改哪个)

<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-1.7.2.js"></script>

3、修改注册表单的提交地址和请求方式

7.1.3 、编写 RegistServlet 程序
public class RegistServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
		// 1 、获取请求的参数
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		String email = req.getParameter("email");
		String code = req.getParameter("code");
		
		// 2 、检查 验证码是否正确 === 写死 , 要求验证码为 :abcde
		if ("abcde".equalsIgnoreCase(code)) {	
		// 3 、检查 用户名是否可用
			if (userService.existsUsername(username)) {
				System.out.println(" 用户名[" + username + "] 已存在!");
		// 跳回注册页面
				req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
			} else {
		// 可用
		// 调用 Sservice 保存到数据库
				userService.registUser(new User(null, username, password, email));
		// 跳到注册成功页面 regist_success.html
				req.getRequestDispatcher("/pages/user/regist_success.html").forward(req, resp);
			}
		} else {
			System.out.println(" 验证码[" + code + "] 错误");
			req.getRequestDispatcher("/pages/user/regist.html").forward(req, resp);
		}
	}
}
7.2、用户登录功能的实现
7.2.1、图解用户登录

在这里插入图片描述

7.2.2 、修改 login.html 页面和 login_success.html 页面
7.2.3 、LoginServlet 程序
public class LoginServlet extends HttpServlet {
	private UserService userService = new UserServiceImpl();
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
		// 1 、获取请求的参数
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		// 调用 userService.login() 登录处理业务
		User loginUser = userService.login(new User(null, username, password, null));
		// 如果等于 null, 说明登录 失败 !
		if (loginUser == null) {
			// 跳回登录页面
			req.getRequestDispatcher("/pages/user/login.html").forward(req, resp);
		} else {
			// 登录 成功
			// 跳到成功页面 login_success.html
			req.getRequestDispatcher("/pages/user/login_success.html").forward(req, resp);
		}
	}
}

  • 2
    点赞
  • 10
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺利毕业啊

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值