书城项目第二阶段

 

目录

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

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

三、编写工具类 JdbcUtils

3.1 配置文件

3.2 编写 JdbcUtils 工具类

四、编写 BaseDao

五、编写 UserDao 和测试

六、编写 UserService 和测试

七、编写 web 层

7.1、实现用户注册的功能

7.2 用户登录功能的实现



javaEE项目的三层架构:

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

. 项目阶段二:用户注册和登陆的实现。
 
需求 1 :用户注册
需求如下:
1 )访问注册页面
2 )填写注册信息,提交给服务器
3 )服务器应该保存用户
4 )当用户已经存在 ---- 提示用户注册 失败,用户名已存在
5 )当用户不存在 ----- 注册成功
 
需求 2 :用户登陆
需求如下:
1 )访问登陆页面
2 )填写用户名密码后提交
3 )服务器判断用户是否存在
4 )如果登陆失败
---
返回用户名或者密码错误信息
5 )如果登录成功
---
返回登陆成功 信息
 
 
思路分析:
1.先根据用户信息创建数据库book
2. 编写数据库表对应的 JavaBean 对象,这一步是为了后面增删改查以对象的方式提供结果,包含了ORM思想。
3.创建连接数据库的工具类JdbcUtils。工具类JdbcUtils中包括创建数据库连接池与数据库建立连接,断开连接这三个方法,用到了druid数据库连接池。
Dao持久层:
4.创建操作数据库的工具类BaseDao,只有这个类是直接操作数据库的。里面主要包括三个方法,获取一条数据,获取多条数据,获取一个数据,这些方法都是通过DBUtils这个类实现的。里面用到了反射和泛型。
5.创建UserDao接口,和其实现类,这两个类是根据用户需求创建的,包括两个需求注册和登录,注册需要根据用户名查询这个用户是否注册过,因为用户名是唯一的,调用上面操作数据库的类BaseDao中的查询一条数据的方法,如果没有在数据库中找到,返回null,可以注册,调用上面操作数据库的类BaseDao中的插入数据的方法,向数据库中保存数据,如果找到了说明已经注册过。登录需要根据用户名和密码查询这个用户是否在数据库存在,如果存在就登陆成功,如果不存在就登陆失败。因此一共有三个方法,一个是根据用户名查询用户是否注册过,一个是保存用户信息到数据库,一个是根据用户名和密码查询数据库中是否有用户信息,没有的话就是输入错误。这三个方法都是与数据库之间的操作,只返回数据库中的信息,具体的逻辑实现要通过Service业务层实现。
Service业务层:
6.创建UserService接口和实现类,主要是调用UserDao去实现业务逻辑和保存数据到数据库,包括上面说的三个业务逻辑。
Web层:
创建两个类,RegistServlet类和LoginServlet类,用于接收web页面用户传来的信息,然后调用UserService中的方法去实现具体的功能。主要用到了Tomcat  Web 服务器。
搭建书城项目开发环境:

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

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) VALUE('admain','admain','admain@qq.com');
SELECT * FROM t_user;

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

javabean对象的理解:https://www.zhihu.com/question/19773379

大体意思就是为了不破坏代码的向后兼容性,就写一个类把一些公共属性等封装起来,用set或get方法得到,即使修改其中的代码,用户还是通过set或get方法得到其中的值。

特点:

1、所有属性为private
2、提供默认构造方法
3、提供getter和setter
4、实现serializable接口

package pojo;

public class User {

    private int id;
    private String username;
    private String password;
    private String email;

    //有参构造器
    public User(int id, String username, String password, String email) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
    }

    //无参构造器
    public User() {
    }

    //get,set方法
    public int getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getEmail() {
        return email;
    }

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

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

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

    public void setEmail(String email) {
        this.email = email;
    }
    //重写toString方法


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

三、编写工具类 JdbcUtils

需要一些jar包,包括mysql数据库驱动,数据库连接池。
 

3.1 配置文件

username=root
password=730136
url=jdbc:mysql://localhost:3306/book
driverClassName=com.mysql.jdbc.Driver

initialSize=5
maxActive=10

3.2 编写 JdbcUtils 工具类

使用数据库连接池获取连接:

注意:1.创建数据库连接池时,用静态代码块创建,因为我们不想每次获取连接的时候都创建一个新的数据库连接池。因为druid连接池没有直接创建连接池的类,所以需要通过一个工厂类来创建连接池。

          2.声明一个空的连接,用于关闭连接时判断是否有连接创建成功。

 
package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtils {

    //先创建一个数据库连接池,用静态代码块创建,因为我们不想每次获取连接的时候都创建一个新的数据库连接池
    private static DataSource source;
    static {

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

    }

    //共有两个方法

    //方法一:获取数据库连接池中的连接

    /**
     * @return 返回值就是获取成功,返回null就是获取失败
     */
    public static Connection getConnection() {

        Connection conn = null;
        try {
            conn = source.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();
            }
        }
    }

}

四、编写 BaseDao

basedao类是一个操作数据库的具体实现类

package dao.daoimpl;

import org.apache.commons.dbutils.DbUtils;
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 utils.JdbcUtils;

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

/**
 * 主要用于操作数据库
 */
public abstract class BaseDao {

    //使用DBUtils操作数据库
    private QueryRunner queryRunner = new QueryRunner();

    /**
     * 用来执行:Insert\Update\Delete 语句
     * @return 如果返回-1,说明执行失败,返回其他表示影响的行数
     */
    public int update(String sql, Object ...args) {

        Connection conn = JdbcUtils.getConnection();

        try {
            return queryRunner.update(conn, sql, args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(conn);
        }

        return -1;
    }


    /**
     *查询返回一个 javaBean 的 sql 语句
     * @param sql 执行的 sql 语句
     * @param t 返回的对象类型,new BeanHandler<>(t)里面需要一个Class类的参数,比如Customer.class
     * @param args
     * @param <T> 返回的类型的泛型
     * @return
     */
    public <T> T queryForOne(String sql, Class<T> t, Object ...args) {

        Connection conn = JdbcUtils.getConnection();
        BeanHandler<T> handler = new BeanHandler<>(t);
        try {
            Object query = queryRunner.query(conn, sql, handler, args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(conn);
        }

        return null;
    }


    /**
     * 查询返回多个 javaBean 的 sql 语句
     * @param sql
     * @param t
     * @param args
     * @return
     */
    public <T>List<T> queryForList(String sql, Class<T> t, Object ...args) {
        Connection conn = JdbcUtils.getConnection();
        BeanListHandler<T> handler = new BeanListHandler<T>(t);
        try {
            return queryRunner.query(conn, sql, handler, args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(conn);
        }
        return null;

    }

    /**
     * 执行返回一行一列的 sql 语句
     * @param sql
     * @param args
     * @return
     */
    public Object queryForSingleValue(String sql, Object ...args) {
        Connection conn = JdbcUtils.getConnection();
        ScalarHandler handler = new ScalarHandler();
        try {
            return queryRunner.query(conn, sql, handler, args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DbUtils.closeQuietly(conn);
        }
        return null;
    }
}

、编写 UserDao 和测试

userdao是一个需求接口

package dao;

import pojo.User;

public interface UserDao {

    //注册需要的方法
    /**
     * 根据用户输入的姓名查询是否用户在数据库中的信息
     * @param username
     * @return 如果返回null,说明没有这个用户,反之则有
     */
    public User queryUserByUsername(String username);

    /**
     * 保存用户信息
     * @param user
     * @return
     */
    public int saveUser(User user);

    //登录需要的方法

    /**
     * 根据用户名和密码查询用户信息
     * @param username
     * @param password
     * @return 返回null说明用户名或密码错误
     */
    public User queryUserByUsernameAndPassWord(String username, String password);
}

userdaoimpl是对userdao的实现类

package dao;

import dao.daoimpl.BaseDao;
import 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(sql, User.class, username);
    }

    @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());
    }

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

userdaotest是测试类

package test;

import dao.UserDao;
import dao.UserDaoImpl;
import org.junit.Test;
import pojo.User;


public class UserDaoTest {

    UserDao userDao = new UserDaoImpl();
    @Test
    public void queryUserByUsername() {

        if (userDao.queryUserByUsername("admin1234") == null) {
            System.out.println("用户名可用!");
        } else {
            System.out.println("用户名已存在!");
        }
    }

    @Test
    public void saveUser() {
        System.out.println( userDao.saveUser(new User("wzg168", "123456", "wzg168@qq.com")) );
    }

    @Test
    public void queryUserByUsernameAndPassWord() {
        if(userDao.queryUserByUsernameAndPassWord("admin", "admin") == null){
            System.out.println("用户名或密码错误,登陆失败");
        }else {
            System.out.println("查询成功");
        }
    }

}

六、编写 UserService 和测试

userService接口,里面写了需要实现的各种业务:

package service;


import pojo.User;

public interface UserService {

    //一共有三个业务,登录,注册,查询用户名是否可用

    /**
     * 注册用户
     * @param user
     */
    public void registUser(User user);

    /**
     * 登录
     * @param user
     * @return
     */
    public User login(User user);


    /**
     * 检查用户名是否可用
     * @param username
     * @return 返回true表示用户名已存在,false表示用户名可用
     */
    public boolean existsUsername(String username);

}
UserServiceImpl 实现类,用来实现userService接口中的业务,里面创建一个userDaoImpl对象用来处理对数据库的操作,因为userServiceImpl无法直接对数据库进行操作。
package service.serviceimpl;

import dao.UserDao;
import dao.UserDaoImpl;
import pojo.User;
import 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;
    }
}
UserService 测试:
package test;

import org.junit.Test;
import pojo.User;
import service.UserService;
import service.serviceimpl.UserServiceImpl;

public class UserServiceTest {

    UserService userService = new UserServiceImpl();

    @Test
    public void registeUser() {
        userService.registUser(new User("b168", "666666", "bbj168@qq.com"));
    }

    @Test
    public void login() {
        System.out.println(userService.login(new User("wzg168", "123456", "wzg168@qq.com")));
    }

    @Test
    public void existsUsername() {
        if (userService.existsUsername("wzg16888")) {
            System.out.println("用户名已存在!");
        } else {
            System.out.println("用户名可用!");
        }
    }
}

七、编写 web

7.1、实现用户注册的功能

图解用户注册的流程:

修改 regist.html regist_success.html 页面中的路径,可以加入Base标签,构成相对路径。同时也要修改表单的提交的路径,修改为registeServer,这样表单中的数据就会提交到http://localhost:8080/book/registeServer这个资源路径下,然后在web.xml配置文件中找到RegistServer这个类中。

注意:web部分一定要放到web这个目录下,因为Tomcat访问工程的路径就是在其webapps文件夹下,在idea中要放到web目录下。

package web;

import pojo.User;
import service.UserService;
import service.serviceimpl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RegistServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 1、获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String code = request.getParameter("code");

        // 2、检查 验证码是否正确 === 写死,要求验证码为:abcde
        if ("abcde".equalsIgnoreCase(code)) {

            // 3、检查用户名是否可用
            if (userService.existsUsername(username)) {
                System.out.println("用户名[" + username + "]已存在!");
                // 跳回注册页面
                //请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到 IDEA 代码的 web 目录
                request.getRequestDispatcher("/pages/user/regist.html").forward(request, response);

            } else { // 可用
                // 调用 Sservice 保存到数据库
                userService.registUser(new User(username, password, email));
                // 跳到注册成功页面regist_success.html
                request.getRequestDispatcher("/pages/user/regist_success.html").forward(request, response);
            }
        } else {
            System.out.println("验证码[" + code + "]错误");
            request.getRequestDispatcher("/pages/user/regist.html").forward(request, response);
        }
    }


}

7.2 用户登录功能的实现

loginServlet类

package web;

import pojo.User;
import service.UserService;
import service.serviceimpl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //1.获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //2.调用userService
        User user = userService.login(new User(username, password, null));
        if (user == null) { //用户名或密码错误,返回登录界面

            request.getRequestDispatcher("/pages/user/login.html").forward(request,response);

        }else {

            request.getRequestDispatcher("/pages/user/login_success.html").forward(request,response);
        }
    }


}

其他同7.2

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值