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页面的表单: