JavaEE三层架构
JavaEE主要分为三层架构:
-
控制层:也称作Web层或视图层,用于获取浏览器请求,并反馈响应信息的一层
-
业务层:用于处理业务,通过控制层获取请求参数后传递给业务层,业务层执行完对应的业务后传递数据给控制层,再由控制层反馈给客户端
-
持久层:用于与数据库这种可以将数据持久保存的程序做交互,完成数据的CRUD,将持久层与数据库交互后的结果反馈给服务层,服务层处理完相应的业务后,反馈给控制层,控制层就会根据实际需求将获取到的结果回传给客户端或浏览器
如图所示
书城项目实现三层架构
-
创建Web项目
-
创建项目包
创建完成后如图所示
-
创建数据库表
-
为数据库表创建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
package com.carl.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:TODO * @date :2021/10/5 23:53 * @month_name :10月 * @week : */ public class JdbcUtils { private static DataSource dataSource; static { //加载配置文件 Properties pro = new Properties(); try { pro.load(new FileReader("resource/druid.properties")); //获取配置文件信息 dataSource = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws Exception { //创建连接对象 Connection conn = dataSource.getConnection(); return conn; } public void close(Connection conn){ try { if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } }
导包:
数据库连接驱动
方法一:Maven配置<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency>
方法二:
-
web目录下创建lib目录
-
为lib目录创建依赖,成为jar依赖目录
-
将下载好的jar包复制到lib目录下即可
-
为了使用test进行测试,还需要导入两个jar包:
-
创建DAO操作数据库
package com.carl.dao.impl; import com.alibaba.druid.sql.visitor.functions.If; import com.carl.utils.JdbcUtils; import com.sun.org.apache.bcel.internal.generic.NEW; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; 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; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:为了复用代码一般设置为抽象类 * BaseDao主要用于编写一些通用的增删改查--使用DbUtils包 * @date :2021/10/6 12:11 * @month_name :10月 * @week : */ public abstract class BaseDao { private QueryRunner qr=new QueryRunner(); /** * @Description: 修改数据(增删改) * @Param: String sql,Object...args * @return: int */ public int update(String sql,Object...args) throws Exception { Connection conn = JdbcUtils.getConnection(); int i = qr.update(conn, sql, args); JdbcUtils.close(conn); if (i>0) { return i; }else{ return -1; } } /** * @Description: 查询一条数据 * @Param: String sql, Class<T> clazz, Object...args * @return: <T> T */ public <T> T queryForOne(String sql, Class<T> clazz, Object...args) throws Exception { Connection conn = JdbcUtils.getConnection(); T query = qr.query(conn, sql, new BeanHandler<T>(clazz), args); JdbcUtils.close(conn); return query; } /** * @Description: 查询多条数据 * @Param: String sql, Class<T> clazz, Object...args * @return: List */ public <T> List<T> queryForList(String sql, Class<T> clazz, Object...args) throws Exception { Connection conn = JdbcUtils.getConnection(); List<T> query = qr.query(conn, sql, new BeanListHandler<T>(clazz), args); JdbcUtils.close(conn); return query; } /** * @Description: 查询一列数据 * @Param: String sql, Object...args * @return: Object */ public Object queryForSingleValue(String sql, Object...args) throws Exception { Connection conn = JdbcUtils.getConnection(); Object query = qr.query(conn, sql, new ScalarHandler(), args); JdbcUtils.close(conn); return query; } }
package com.carl.dao; import com.carl.pojo.User; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:根据数据库表创建对应的DAO,用于针对业务进行具体的增删改查操作 * @date :2021/10/6 12:11 * @month_name :10月 * @week : */ public interface UserDao { public User queryUserByUsername(String username) throws Exception; public int saveUser(User user) throws Exception; public User queryUserByUserAndPass(String username,String password) throws Exception; }
package com.carl.dao.impl; import com.carl.dao.UserDao; import com.carl.pojo.User; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:实现UserDao接口,利用BaseDao中的通用增删改查,实现具体的sql操作 * @date :2021/10/6 13:22 * @month_name :10月 * @week : */ public class UserDaoImpl extends BaseDao implements UserDao{ @Override public User queryUserByUsername(String username) throws Exception { String sql="select* from t_user where username=?"; return queryForOne(sql, User.class, username); } @Override public int saveUser(User user) throws Exception { String sql="insert into t_user(username,`password`,email) values(?,?,?)"; int i = update(sql, user.getUsername(), user.getPassword(), user.getEmail()); return i; } @Override public User queryUserByUserAndPass(String username,String password) throws Exception { String sql="select* from t_user where username=? and password=?"; return queryForOne(sql,User.class, username,password); } }
-
编写Service业务层
package com.carl.service; import com.carl.pojo.User; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:注册登录的业务 * @date :2021/10/6 13:51 * @month_name :10月 * @week : */ public interface UserService { /** * 注册用户 * @param user * @return 返回true表示用户名存在,返回false表示用户名不存在,可以创建 */ public void register(User user) throws Exception; public boolean existUsername(String username) throws Exception; public User login(User user) throws Exception; }
package com.carl.service.impl; import com.carl.dao.UserDao; import com.carl.dao.impl.UserDaoImpl; import com.carl.pojo.User; import com.carl.service.UserService; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:TODO * @date :2021/10/6 13:51 * @month_name :10月 * @week : */ public class UserServiceImpl implements UserService { UserDaoImpl userDao=new UserDaoImpl(); @Override public void register(User user) throws Exception { userDao.saveUser(user); } @Override public boolean existUsername(String username) throws Exception { User user = userDao.queryUserByUsername(username); if (user == null) { return false; }else{ return true; } } @Override public User login(User user) throws Exception { return userDao.queryUserByUserAndPass(user.getUsername(), user.getPassword()); } }
至此服务器到数据库的连接及操作完成。
-
前端页面设计–此处省略前端页面的编写
-
编写Controller层 完成登录和注册
package com.carl.controller; import com.carl.pojo.User; import com.carl.service.UserService; import com.carl.service.impl.UserServiceImpl; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author :Carl_蔡先生 * @version :JDK1.8 * @description:注册Servlet:获取注册页面的资源请求,完成注册响应 * @date :2021/10/6 14:08 * @month_name :10月 * @week : */ public class RegisterServlet extends HttpServlet { UserService us=new UserServiceImpl(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求设置编码 req.setCharacterEncoding("UTF-8"); //获取浏览器请求中表单信息 String username = req.getParameter("username"); String password = req.getParameter("password"); String email = req.getParameter("email"); String code = req.getParameter("code"); //将获取的注册信息封装到Bean类中 User user = new User(null,username,password,email); //注册码验证 if ("6n6np".equalsIgnoreCase(code)) { System.out.println("验证成功"); try { //用户名验证 if (!us.existUsername(user.getUsername())) { //存储到数据库 us.register(user); //请求转发--登录成功页面 req.getRequestDispatcher("html/regist_success.html").forward(req,resp); }else{ resp.getWriter().write("用户已存在"); req.getRequestDispatcher("html/regist.html").forward(req,resp); } } catch (Exception e) { e.printStackTrace(); } }else{ System.out.println("验证失败"); req.getRequestDispatcher("html/regist.html").forward(req,resp); } } }
-
配置web.xml
<servlet> <servlet-name>BookService</servlet-name> <servlet-class>com.carl.controller.RegisterServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BookService</servlet-name> <url-pattern>/regist_success</url-pattern> </servlet-mapping>
-
登录页面逻辑相似
至此三层架构完成