Web阶段:第十一章:JavaEE项目的三层架构

2022-09-28 11:01:19 浏览数 (1)

JavaEE项目的三层架构

分层的作用 方便项目后期的维护和升级,以及扩展。 分层的好处是降低代码的耦合度

分层后的代码包结构

代码语言:javascript复制
Dao持久层的包		com.dao		放dao层的接口
            com.dao.impl	放dao层的实现类
Service业务层		com.service	放Service层的接口
            com.service.impl放Service层的实现类
web层			com.servlet	放web层的实现类
bean层			com.pojo	JavaBean对象	com.entity	com.domain	
测试层			com.test	测试
工具层			com.utils	工具类层

步骤: 1、创建数据库和表

代码语言:javascript复制
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@qq.com');    
select * from t_user;

2、创建对应的JavaBean对象

代码语言:javascript复制
public class User {

    private Integer id;
    private String username;
    private String password;
    private String email;

3、编写工具类 JdbcUtils类 === 使用数据库连接池 getConnection() 获取连接 closeConnection() 关闭连接

1、导入jar包: druid-1.1.9.jar mysql-connector-java-5.1.7-bin.jar

2、创建config源码目录,添加jdbc.properties属性配置文件

代码语言:javascript复制
url=jdbc:mysql://localhost:3306/book
username=root
password=root
driverClassName=com.mysql.jdbc.Driver
initialSize=5
maxActive=10

JdbcUtils源代码:

代码语言:javascript复制
public class JdbcUtils {
    // 阿里数据库连接池
    private static DataSource dataSource;
    static {
        try {
            Properties properties = new Properties();
            properties.load(JdbcUtils.class.getClassLoader()
                    .getResourceAsStream("jdbc.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    /**
     * 返回数据库连接对象
     * @return
     */
    public static Connection getConnection() {
        Connection connection = null;  
        try {
            connection = dataSource.getConnection();
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
        }    
        return connection;
    }   
    /**
     * 释放 连接
     * 
     * @param connection
     */
    public static void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

JdbcUtils测试代码:

代码语言:javascript复制
public class JdbcUtilsTest {

    @Test
    public void test1() throws Exception {
        for (int i = 0; i < 100; i  ) {
            Connection connection = JdbcUtils.getConnection();
            System.out.println( connection );
            JdbcUtils.closeConnection(connection);
        }
    }
}

4、去编写Dao层(包含测试) BaseDaoImpl源代码:

代码语言:javascript复制
public class BaseDaoImpl { 
    private QueryRunner queryRunner = new QueryRunner();
    /**
     * 执行insert,update,delete语句
     * @param sql
     * @param args
     * @return -1表示执行失败
     */
    public int update(String sql, Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection, sql, args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(connection);
        }
        return -1;
    }    
    /**
     * 查询一条记录 
     * @param type
     * @param sql
     * @param args
     * @return
     */
    public <T> T queryForOne(Class<T> type, String sql, Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.query(connection, sql, new BeanHandler<T>(type),
                    args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(connection);
        }
        return null;
    }    
    /**
     * 查询返回多个对象的情况
     * 
     * @param type
     * @param sql
     * @param args
     * @return
     */
    public <T> List<T> queryForList(Class<T> type, String sql, Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.query(connection, sql, new BeanListHandler<T>(
                    type), args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(connection);
        }
        return null;
    }    
    /**
     * 查询返回单个列的情况
     * 
     * @param sql
     * @param args
     * @return
     */
    public Object queryForSingleValue(String sql, Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner
                    .query(connection, sql, new ScalarHandler(), args);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.closeConnection(connection);
        }
        return null;
    }
}

UserDao接口 saveUser 保存用户 queryUserByUsername 根据用户名查询用户 queryUserByUsernameAndPassword 根据用户名和密码查询用户

UserDao接口代码:

代码语言:javascript复制
public interface UserDao {
    // 保存用户
    public int saveUser(User user); 
    // 根据用户名查询用户
    public User queryUserByUsername(String username);
    // 根据用户名和密码查询用户
    public User queryUserByUsernameAndPassword(String username, String password);
}

UserDaoImpl代码:

代码语言:javascript复制
public class UserDaoImpl extends BaseDaoImpl implements UserDao {
    @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 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);
    }
}

UserDao的测试:

代码语言:javascript复制
public class UserDaoTest {

    private static UserDao userDao;
    /**
     * 被标注了@BeforeClass注解的方法会在所有方法执行之前执行,做一些初始化工作。
     * @throws Exception
     */
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        userDao = new UserDaoImpl();
    }
    @Test
    public void testSaveUser() {
        userDao.saveUser(new User(null, "wzg168", "123456", "wzg168@qq.com"));
    }
    @Test
    public void testQueryUserByUsername() {
        System.out.println(userDao.queryUserByUsername("username"));
        System.out.println(userDao.queryUserByUsername("wzg168"));
    }
    @Test
    public void testQueryUserByUsernameAndPassword() {
        System.out.println(userDao.queryUserByUsernameAndPassword("wzg168",
                "1234"));
        System.out.println(userDao.queryUserByUsernameAndPassword("wzg168",
                "123456"));
    }
}

5、去编写Service层(包含业务)

Service接口 login 登录 regist 注册 existsUsername 检查用户名是否存在

UserService接口

代码语言:javascript复制
public interface UserService {
    /**
     * 登录
     * @param username
     * @param password
     * @return
     */
    public User login(String username, String password);    
    /**
     * 注册
     * @param user
     */
    public void regist(User user);   
    /**
     * 检查用户名是否存在
     * 
     * @param username
     * @return
     */
    public boolean existsUsername(String username);
}

UserServiceImpl的实现

代码语言:javascript复制
public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();
    @Override
    public User login(String username, String password) {
        return userDao.queryUserByUsernameAndPassword(username, password);
    }
    @Override
    public void regist(User user) {
        userDao.saveUser(user);
    }
    @Override
    public boolean existsUsername(String username) {
        User user = userDao.queryUserByUsername(username);
        // 用户没有查到,说明,用户名不存在
        if (user == null) {
            // 用户名可用
            return false;
        } else {
            // 用户名已存在
            return true;
        }		
    }
}

测试代码:

代码语言:javascript复制
public class UserServiceTest {   
    private static UserService userService;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        userService = new UserServiceImpl();
    }
    @Test
    public void testLogin() {
        System.out.println( userService.login("admin", "admin") );
        System.out.println( userService.login("admin", "123456") );
    }  
    @Test
    public void testRegist() {
        userService.regist(new User(null, "aaa168", "123456", "aaa@qq.com"));
    }
    @Test
    public void testExistsUsername() {
        if (userService.existsUsername("admin1")) {
            System.out.println("用户名已存在!");
        } else {
            System.out.println("用户名可用!");
        }
    }
}

6、编写web层 用户注册功能实现: RegistServlet程序:

代码语言:javascript复制
public class RegistServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    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");
        // 比较验证码是否正确 写死比较abcde
        if ("abcde".equalsIgnoreCase(code)) {
            // 验证码正确
            // 比较用户名是否可用
            boolean existsUsername = userService.existsUsername(username);
            if (existsUsername) {
                // 说明用户名已存在!!!
                System.out.println("注册失败【"   username   "】用户名已存在!!");
                // 转发中的斜杠表示到http://ip:port/工程名/ 映射到代码的WebContent目录
                request.getRequestDispatcher("/pages/user/regist.html")
                        .forward(request, response);
            } else {
                // 2、调用Service方法处理业务
                userService.regist(new User(null, username, password, email));
                System.out.println("用户注册成功!");
                // 转发中的斜杠表示到http://ip:port/工程名/ 映射到代码的WebContent目录
                request.getRequestDispatcher("/pages/user/regist_success.html")
                        .forward(request, response);
            }
        } else {
            // 验证码不正确
            System.out.println("验证码不正确:"   code);
            // 转发中的斜杠表示到http://ip:port/工程名/ 映射到代码的WebContent目录
            request.getRequestDispatcher("/pages/user/regist.html").forward(
                    request, response);
        }
    }
}

所有页面都要统一加上base标签: 1、<base href=“http://localhost:8080/book/” /> 2、去掉页面中原相对路径前面的…/…/

修改regist.html页面中表单: 修改请求的地址和请求的方式为post

如何在Eclipse中使用Debug调试功能 调试代码需要有断点 debug运行模式

在你需要让代码停下来的所在行,找到左边行号双击,就可以出现如下图所示的断点标记。

debug启动Tomcat服务器。

当出现如下窗口,选中yes

让代码往下执行一行。

让代码进入到当前方法体内执行。

跳出当前方法外

直接终止程序(服务器也停止)

让代码继续执行,直到遇到下一个断点才停止。 大纲窗口

变量窗口:

断点窗口:

方法(调用)栈窗口 1、下一行,调用上一行方法 2、快速切换当前方法

用户登录功能实现: LoginServlet程序

代码语言:javascript复制
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    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、调用Service处理业务
        // userService.login( user );
        User user = userService.login(username, password);
        if (user == null) {
            // 登录失败
            // login.html
            request.getRequestDispatcher("/pages/user/login.html").forward(
                    request, response);
        } else {
            // 登录成功
            // login_success.html
            request.getRequestDispatcher("/pages/user/login_success.html")
                    .forward(request, response);
        }
    }
}

修改login.html页面的表单:

0 人点赞