项目结构
下面对每个包对应的逻辑和功能做简要说明
com.bupt.dao:里面是进行数据库操作的相关接口。接口相当于一种规范,增加了系统的可测试性和健壮性,无论之后的daoImpl中的实现代码如何改变,只要接口不改变就不会影响程序的运行,降低了程序的耦合度,便于进行单元测试。
com.bupt.dao.impl:里面是上面数据库相关操作接口的实现类。
com.bupt.entity:里面是要在数据库中操作的对象实体,比如用户对象,可以看作数据库中的一张表,用户表或是地址表之类的。他们在数据库中所在的表不同,但是都有一个主键id(userId,addressId...),所以他们要统一的继承抽象类IdEntity,这个类里只有一个id,项目的逻辑更加清晰,代码更少。
com.bupt.service:里面是根据项目的要求不同进行的一些服务操作,比如判断用户表中有没有重复的用户名之类的。尽管UserDaoImpl中,我们也可以写相应的实现方法,但是这个服务层是有存在的意义的,如果没有这个服务层,那么servlet就要直接调用UserDaoImpl中的方法,但是UserDaoImpl中的方法只是执行了数据库的查询或是插入操作,如果有更加复杂的操作,那么就无法满足,强行满足要求就要在impl类中写大量复杂的实现,而且servlet中就要多次调用daoImpl中的方法,导致servlet无法明显的体现出自身要执行的功能,这样模糊的servlet可能就要导致客户端执行一个注册功能就要多次请求不同的servlet来完成,所以service层的存在使得整个项目的层次更加清晰。
com.bupt.servlet:里面是客户端进行相应请求要访问的servlet类。
com.bupt.util:里面是连接数据库所需的ConnectionFactory工厂类,其中的dburl等参数是从配置文件dbconfig.properties中读取的。需要jdbc的jar包,复制进来并引用。
下面贴代码
UsreDao
package com.bupt.dao;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.bupt.entity.User;
//数据库中用户表相关的操作接口
public interface UserDao {
public void insert(Connection conn, User user) throws SQLException;
public ResultSet get(Connection conn, User user) throws SQLException;
}
package com.bupt.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.bupt.dao.UserDao;
import com.bupt.entity.User;
//数据库中有关用户表的接口实现
public class UserDaoImpl implements UserDao {
@Override
public void insert(Connection conn, User user) throws SQLException {
String sql = "INSERT INTO user(username,password,email) VALUES (?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, user.getUserName());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.execute();
}
@Override
public ResultSet get(Connection conn, User user) throws SQLException {
String sql = "SELECT * FORM user WHERE username=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, user.getUserName());
return ps.executeQuery();
}
}
package com.bupt.entity;
//Id实体抽象类,其他实体类的父类
public abstract class IdEntity {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package com.bupt.entity;
//用户实体,因为之后每个实体在数据表中都有主键id属性,所以他们都继承了IdEntity抽象类
public class User extends IdEntity {
private String userName;
private String password;
private String email;
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;
}
}
package com.bupt.service;
import java.sql.Connection;
import java.sql.ResultSet;
import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;
//验证用户登录是否成功
//有三个不同的返回情况
//return 1:登录成功
//return 2:密码错误
//return 3:无此用户
public class CheckUserPermissionService {
public static int checkPermission(User user) {
Connection conn = null;
boolean hasUser = false;
try {
UserDao us = new UserDaoImpl();
conn = ConnectionFactory.getInstance().makeConnection();
conn.setAutoCommit(false);
ResultSet rs = us.get(conn, user);
if (rs.next()) {
hasUser = true;
if(user.getPassword().equals(rs.getString("password"))){
return 1;
}
}
if(hasUser == true){
return 2;
}
} catch (Exception e) {
e.printStackTrace();
try {
conn.rollback();
} catch (Exception e2) {
e2.printStackTrace();
}
} finally {
try {
conn.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
return 3;
}
}
package com.bupt.service;
import java.sql.Connection;
import java.sql.ResultSet;
import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;
//查找数据库用户表中有没有相同的用户名
public class CheckUserService {
public static boolean check(User user) {
Connection conn = null;
try {
UserDao us = new UserDaoImpl();
conn = ConnectionFactory.getInstance().makeConnection();
conn.setAutoCommit(false);
ResultSet rs = us.get(conn, user);
if (rs.next()) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
try {
conn.rollback();
} catch (Exception e2) {
e2.printStackTrace();
}
} finally {
try {
conn.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
return false;
}
}
package com.bupt.service;
import java.sql.Connection;
import com.bupt.dao.UserDao;
import com.bupt.dao.impl.UserDaoImpl;
import com.bupt.entity.User;
import com.bupt.util.ConnectionFactory;
//将建立好的实体用户插入到数据库中
/*
* 尽管UserDaoImpl中也有相应的插入数据的实现方法,但是这个服务类有存在的意义,
* 如果没有这个服务类,那么servlet就要直接调用UserDaoImpl中的方法,
* 但是UserDaoImpl中的方法只是执行了数据库的查询或是插入操作,如果有更加复杂的操作,那么就无法满足,
* servlet中就要多次调用daoImpl中的方法,导致servlet无法明显的体现出自身要执行的功能,
* 这样模糊的servlet可能就要导致客户端执行一个注册功能就要多次请求不同的servlet来完成,
* 所以service层使得整个项目的层次更加清晰
*/
public class InsertUserService {
public static void insert(User user) {
Connection conn = null;
try {
UserDao us = new UserDaoImpl();
conn = ConnectionFactory.getInstance().makeConnection();
conn.setAutoCommit(false);
us.insert(conn, user);
System.out.println("插入新用户成功");
} catch (Exception e) {
e.printStackTrace();
try {
conn.rollback();
} catch (Exception e2) {
e2.printStackTrace();
}
} finally {
try {
conn.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
}
}
package com.bupt.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.bupt.entity.User;
import com.bupt.service.CheckUserPermissionService;
//客户端进行登录时要请求的servlet
//url-pattern: /login
//login success:登录成功
//password error:密码错误
//no user:无此用户
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 5290609484927130100L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("username");
String password = req.getParameter("password");
User user = new User();
user.setUserName(userName);
user.setPassword(password);
int result = CheckUserPermissionService.checkPermission(user);
PrintWriter pw = resp.getWriter();
if (result == 1) {
pw.print("login success");
} else if (result == 2) {
pw.print("password error");
} else {
pw.print("no user");
}
pw.close();
}
}
package com.bupt.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.bupt.entity.User;
import com.bupt.service.CheckUserService;
import com.bupt.service.InsertUserService;
//客户端进行注册时要请求的servlet
//url-pattern: /register
//"register success":注册成功
//"username repeat":用户名重复
public class RegisterServlet extends HttpServlet {
private static final long serialVersionUID = 3971678149369992198L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
User user = new User();
user.setUserName(userName);
user.setPassword(password);
user.setEmail(email);
boolean flag = CheckUserService.check(user);
PrintWriter pw = resp.getWriter();
if (flag == false) {
InsertUserService.insert(user);
pw.println("register success");
} else {
pw.print("username repeat");
}
pw.close();
}
}
package com.bupt.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
//提供数据库连接的连接工厂类,driver,dburl,user,password等属性由dbconfig.properties得到
public class ConnectionFactory {
private static String driver;
private static String dburl;
private static String user;
private static String password;
private static final ConnectionFactory factory = new ConnectionFactory();
private Connection conn;
static {
Properties prop = new Properties();
try {
InputStream inputStream = ConnectionFactory.class.getClassLoader()
.getResourceAsStream("dbconfig.properties");
prop.load(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
driver = prop.getProperty("driver");
dburl = prop.getProperty("dburl");
user = prop.getProperty("user");
password = prop.getProperty("password");
}
public ConnectionFactory() {
}
public static ConnectionFactory getInstance() {
return factory;
}
public Connection makeConnection() {
try {
Class.forName(driver);
conn = DriverManager.getConnection(dburl, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
driver=com.mysql.jdbc.Driver
dburl=jdbc\:mysql\://localhost\:3306/study?useSSL=false
user=root
password=root
Study
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
login
com.bupt.servlet.LoginServlet
login
/login
register
com.bupt.servlet.RegisterServlet
register
/register