项目基本框架:
分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
-
测试包
com.ftn.test/junit -
工具类
com.atguigu.utils -
实体bean对象
com.ftn.pojo/entity/domain/bean: JavaBean类 -
dao持久层
com.ftn.dao: Dao接口包
com.ftn.daoImpl: Dao接口实现类 -
service层
com.ftn.service: Service接口包
com.ftn.serviceImpl: Service接口实现类 -
web层
com.ftn.web: 实现功能的servlet类
package com.ftn.pojo;
public class User {
private Integer id;
private String username;
private String password;
private String email;
public User() {
}
public User(Integer id, String username, String password, String email) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", email='" + email + ''' +
'}';
}
}
第四步:编写工具类 JdbcUtils
将获取数据库的连接以及关闭数据库的连接(放回数据库连接池)操作封装为一个工具类
(在这里有一个需要注意的点:druid的配置文件druid.proerties需要放置在resource文件夹中,不然无法读取到它)
package com.ftn.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtils {
private static DataSource dataSource;
static {
Properties properties = new Properties();
try {
InputStream resourceAsStream = JdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(resourceAsStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close(ResultSet set, PreparedStatement statement,Connection connection){
try {
if (set!=null){
set.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
第五步:编写BasicDao
将数据库的update操作和query操作封装至BasicDao类中
package com.ftn.dao; import com.ftn.utils.JdbcUtils; 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 java.sql.Connection; import java.sql.SQLException; import java.util.List; public abstract class BasicDao第六步:编写UserDao及UserDaoImpl{ private QueryRunner queryRunner = new QueryRunner(); public int query_update(String sql,Object... args){ Connection connection = null; try { connection = JdbcUtils.getConnection(); return queryRunner.update(connection,sql,args); } catch (SQLException e) { throw new RuntimeException(e); }finally { JdbcUtils.close(null,null, connection); } } public List query_multi(String sql, Class clazz, Object... args){ Connection connection = null; try { connection = JdbcUtils.getConnection(); return queryRunner.query(connection,sql,new BeanListHandler (clazz),args); } catch (SQLException e) { throw new RuntimeException(e); }finally { JdbcUtils.close(null,null,connection); } } public T query_single(String sql,Class clazz,Object... args){ Connection connection = null; try { connection = JdbcUtils.getConnection(); return queryRunner.query(connection,sql,new BeanHandler (clazz),args); } catch (SQLException e) { throw new RuntimeException(e); }finally { JdbcUtils.close(null,null,connection); } } public Object query_scalar(String sql,Object... args){ Connection connection = null; try { connection = JdbcUtils.getConnection(); return queryRunner.query(connection,sql,new ScalarHandler<>(),args); } catch (SQLException e) { throw new RuntimeException(e); }finally { JdbcUtils.close(null,null,connection); } } }
UserDao接口需要实现的功能:
- 通过用户名查找用户
- 通过用户名和密码查找用户
- 保存用户到数据库
package com.ftn.dao;
import com.ftn.pojo.User;
public interface UserDao {
public User queryUserByUsername(String username);
public User queryUserByUsernameAndPassword(String username,String password);
public int saveUser(User user);
}
UserDaoImpl
package com.ftn.daoImpl; import com.ftn.dao.BasicDao; import com.ftn.dao.UserDao; import com.ftn.pojo.User; public class UserDaoImpl extends BasicDao第七步:编写UserService和UserServiceImplimplements UserDao { @Override public User queryUserByUsername(String username) { String sql = "select id,username,password,email from t_user where username=?"; return query_single(sql,User.class,username); } @Override public User queryUserByUsernameAndPassword(String username, String password) { String sql = "select id,username,password,email from t_user where username=? and password=?"; return query_single(sql,User.class,username,password); } @Override public int saveUser(User user) { String sql = "insert into t_user(`username`,`password`,`email`) values(?,?,?)"; return query_update(sql,user.getUsername(),user.getPassword(),user.getEmail()); } }
UserService接口需要实现的功能:
- 注册
- 登录
- 检查用户名是否可用
package com.ftn.service;
import com.ftn.pojo.User;
public interface UserService {
public void registUser(User user);
public User login(User user);
public boolean existsUsername(String username);
}
UserServiceImpl
package com.ftn.serviceImpl;
import com.ftn.dao.UserDao;
import com.ftn.daoImpl.UserDaoImpl;
import com.ftn.pojo.User;
import com.ftn.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) {
return userDao.queryUserByUsername(username)!=null;
}
}
第八步:实现用户注册的功能
(使用base标签加相对路径的方式来设置路径)
使用Post请求更安全
package com.ftn.web;
import com.ftn.pojo.User;
import com.ftn.service.UserService;
import com.ftn.serviceImpl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class RegistServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
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)){
// 可用
// 4、调用Service保存到数据库
userService.registUser(new User(null,username,password,email));
// 5、跳到注册成功页面regist_success.html
request.getRequestDispatcher("/pages/user/regist_success.html").forward(request,response);
}else {
// 不可用
System.out.println("用户名已存在");
request.getRequestDispatcher("/pages/user/regist.html").forward(request,response);
// 跳回注册页面
}
}else {
// 不正确
System.out.println("验证码错误");
request.getRequestDispatcher("/pages/user/regist.html").forward(request,response);
// 跳回注册页面
}
}
}
第九步:用户登录功能的实现
package com.ftn.web;
import com.ftn.pojo.User;
import com.ftn.service.UserService;
import com.ftn.serviceImpl.UserServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1,获取请求的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
// 2,调用Userservice.login()处理业务userservice.Login()登录
UserService userService = new UserServiceImpl();
// 3,根据Login()方法返回结果判断登录是否成功
if (userService.login(new User(null,username,password,null))!=null){
// 成功
request.getRequestDispatcher("/pages/user/login_success.html").forward(request,response);
// 跳到成功页面Login_success.html
}else {
// 失败
System.out.println("用户未注册,请先注册");
request.getRequestDispatcher("/pages/user/login.html").forward(request,response);
// 跳回登录页面
}
}
}



