第二十七章:JavaEE项目的三层架构

版权声明:作者:java_wxid https://blog.csdn.net/java_wxid/article/details/83747446

作者:java_wxid

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','[email protected]');    
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", "[email protected]"));
	}
	@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", "[email protected]"));
	}
	@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页面的表单:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/java_wxid/article/details/83747446
今日推荐