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


    JavaEE项目的三层架构
    在这里插入图片描述
    分层的作用
    方便项目后期的维护和升级,以及扩展。
    分层的好处是降低代码的耦合度

    分层后的代码包结构

    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、创建数据库和表

    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对象

    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属性配置文件

    url=jdbc:mysql://localhost:3306/book
    username=root
    password=root
    driverClassName=com.mysql.jdbc.Driver
    initialSize=5
    maxActive=10
    

    JdbcUtils源代码:

    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测试代码:

    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源代码:

    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接口代码:

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

    UserDaoImpl代码:

    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的测试:

    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接口

    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的实现

    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;
    		}		
    	}
    }
    

    测试代码:

    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程序:

    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程序

    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页面的表单:
    在这里插入图片描述

  • 相关阅读:
    python高级 之(三) --- 高阶函数
    python高级 之(二) --- 类装饰器
    python高级 之(一) --- 函数类型
    jQuery
    css
    html
    px2rem
    keep-alive标签
    rem适配方案2(flexible.js)
    媒体查询
  • 原文地址:https://www.cnblogs.com/javawxid/p/12812108.html
Copyright © 2020-2023  润新知