【Javaweb】JavaEE项目的三层架构 | 快速搭建
逻辑类图

分层的目的是为了解耦。解耦就是为了降低代码的耦合度。方便项目后期的维护和升级。
不同的层有不同的包
web层 com.stguigu.web/servlet/controller
service层 com.atguigu.service Service接口包
com.atguigu.service.impl Service接口实现类
dao持久层 com.atguigu.dao Dao接口包
实体Bean对象 com.atguigu.poio/entity/domain/bean JavaBean类
测试包 com.atguigu.test/junit
工具类 com.atguigu.utils
编码环节
1、先创建项目所需要的数据库和表
DROP DATABASE IF exists javaweb05; CREATE DATABASE javaweb05; use javaweb05; create table t_user(
`id` int primary key auto_increment,
`username` varchar(20) NOT NULL UNIQUE,
`password` varchar(32) not null,
`email` varchar(200)
);

2、编写数据库表对应的JavaBean对象

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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", 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;
}
}
部分代码
3、编写工具类JdbcUtils

private static DruidDataSource dataSource;
static {
try {
Properties properties=new Properties();
// 读取jdbc.properties属性配置文件
InputStream inputStream=JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
// 从源中加载数据
properties.load(inputStream);
// 创建 数据库连接 池
dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
System.out.println(dataSource.getConnection());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection(){
Connection connection=null;
try {
connection=dataSource.getConnection();
}catch (Exception e){
e.printStackTrace();
}
return connection;
}
public static void close(Connection connection){
if(connection!=null){
try {
connection.close();
}catch (SQLException e){
e.printStackTrace();
}
}
}
部分代码
4、编写BaseDao

public abstract class BaseDao {
// 使用DbUtils操作数据库
private QueryRunner queryRunner=new QueryRunner();
/**
* update()方法用来执行,Insert\Update\Delete语句
* @return 如果返回-1,说明执行失败<br>返回其他表示影响的行数
* @author yan
* @create 2023/1/30
**/
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.close(connection);
}
return -1;
}
/*
* 查询返回一个JavaBean的sql语句
*
* @param type 返回的对象类型
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @param <T> 返回的类型的泛型
* @return
* @author yan
* @create 2023/1/30
**/
public <T>T queryForOne(Class<T>type,String sql,Object ... args){
Connection connection=JdbcUtils.getConnection();
try {
queryRunner.query(connection, sql, new BeanHandler<T>(type), args);
}catch (SQLException e){
e.printStackTrace();
}finally {
JdbcUtils.close(connection);
}
return null;
}
/*
* 查询返回多个JavaBean的sql语句
*
* @param type 返回的对象类型
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @param <T> 返回的类型的泛型
* @return
* @author yan
* @create 2023/1/30
**/
public <T>List<T> queryForList(Class<T>type,String sql,Object ... args){
Connection connection=JdbcUtils.getConnection();
try {
queryRunner.query(connection, sql, new BeanHandler<T>(type), args);
}catch (SQLException e){
e.printStackTrace();
}finally {
JdbcUtils.close(connection);
}
return null;
}
/*
* 查询返回多个JavaBean的sql语句
*
* @param type 返回的对象类型
* @param sql 执行的sql语句
* @param args sql对应的参数值
* @return
* @author yan
* @create 2023/1/30
**/
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.close(connection);
}
return null;
}
}
BaseDao
5、编写UserDao测试

public class UserDaoImpl extends BaseDao implements UserDao {
@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);
}
@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());
}
}
UserDaoImpl

6、编写UserService和测试

private UserDao userDao=new UserDaoImpl();
@Override
public void register(User user) {
userDao.saveUser(user);
}
@Override
public User login(User user) {
return userDao.queryUserByUsernameAndPassword(user.getUsername(),user.getPassword());
}
@Override
public boolean existsUsername(String username) {
if(userDao.queryUserByUsername(username)==null){
// 等于null,说明没查到,没查到表示可用
return false;
}
return true;
}
UserServiceImpl
7、编写web层

public class RegisterServlet extends HttpServlet {
private UserService userService = new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String email = req.getParameter("email");
String code = req.getParameter("code");
//2、检查验证码是否正确 ---- 正确===写死,要求验证码为123
if ("123".equalsIgnoreCase(code)) {
//3、检查用户名是否可用 ----可用
if (userService.existsUsername(username)) {
// 不可用
System.out.println("用户名[" + username + "]已存在!");
// 跳回注册页面
req.getRequestDispatcher("/register/register.html").forward(req, resp);
} else {
// 可用
//4、调用Service保存到数据库
userService.register(new User(null, username, password, email));
//5、跳到注册成功页面 register_success.html
req.getRequestDispatcher("/register/registersuccess.html").forward(req, resp);
}
//6、否则跳回注册页面
} else {
System.out.println("验证码[" + code + "]错误");
req.getRequestDispatcher("/register/register.html").forward(req, resp);
}
}
}
RegisterServlet
7.2IDEA中Debug调试的使用
Debug调试代码,首先需要两个元素:断点+Debug启动器
1、断点,只需要在代码需要停的行的左边上单击,就可以添加和取消
2、Debug启动Tomcat运行代码

调试工具栏:

让代码往下执行一行
可以进入当前方法体内(自己写的代码,非框架源码)
强制进入当前方法体内
跳出当前方法体外
停在光标所在行,相当于是个临时断点
变量窗口
可以查看当前方法范围内所有有效的变量

方法调用栈窗口
1、可以查看当前线程有哪些方法的调用信息
2、下面的调用上面的方法

其他常用调试相关按钮

7.3用户登录功能的实现

利用断点进行测试
信息错误时

信息正确时



public class LoginServlet extends HttpServlet {
private UserService userService=new UserServiceImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、获取请求的参数
String username= req.getParameter("username");
String password= req.getParameter("password");
//2、调用userService.login()登录处理业务
User loginUser= userService.login(new User(null,username,password,null));
//3、根据login()方法返回结果判断登录是否成功
// 如果等于null,说明登录 失败!
if(loginUser==null){
// 跳回登陆页面
req.getRequestDispatcher("/register/login.html").forward(req,resp);
}else {
// 登陆成功
// 跳到成功页面login_success.html
req.getRequestDispatcher("/register/login_success.html").forward(req,resp);
}
}
}
LoginServlet
【Javaweb】JavaEE项目的三层架构 | 快速搭建的更多相关文章
- Web项目的三层架构和MVC架构异同
http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了.因为它们都在逻辑 ...
- JavaWeb基础—MVC与三层架构
一.MVC的概念 MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...
- CS通用项目系统搭建——三层架构第一天
CS通用项目:使用三层架构进行搭建 三层架构: 表现层(UI(User Interface)):展示给用户的层面,包含窗体控件数据等信息. 业务逻辑层(BLL(Business Logic Layer ...
- ATM购物车项目 三层架构
目录 项目开发流程 项目需求 三层架构 (重点) 实际案例 展示层 核心逻辑层 数据处理层 ATM项目 项目开发流程 # 1.项目需求分析 产品经理(客户) 架构师 开发经理 1.架构师 开发经理提前 ...
- 从MVC和三层架构说到SSH整合开发
相信很多人都认同JavaWeb开发是遵从MVC开发模式的,遵从三层架构进行开发的,是的,大家都这么认同.但是相信大家都会有过这样一个疑问,if(MVC三层模式==三层架构思想)out.println( ...
- winform学习日志(十九)----------真正三层架构之登录
摘要:一:三层构架的基础知识在项目开发的过程中,有时把整个项目分为三层架构,其中包括:表示层(UI).业务逻辑层(BLL)和数据访问层(DAL).三层的作用分别如下: 表示层:为用户提供交互操作界面, ...
- SSH和三层架构的MVC模式的对应关系
1.MVC(Model-View-Controller)设计模式: 首先让我们了解下MVC(Model-View-Controller)的概念: MVC全名是Model View Controller ...
- MVC设计模式与三层架构
三层架构分别是:表示层(Web层).业务逻辑层(BLL层)和数据访问层(DAL层). (1)表示层负责: a.从用户端收集信息 b.将用户信息发送到业务服务层做处理 c.从业务服务层接收处理结果 d. ...
- 三层架构下的EntityFramework codefirst
好久没写博客了,今天研究了EF框架的CodeFirst模式,从字面意思可以看出,代码优先.所谓代码优先,与以往的添加ado.net不同,主要是编写代码生成数据库和数据表,生成数据实体映射.个人感觉这种 ...
- Spring-Data-JPA尝鲜:快速搭建CRUD+分页后台实例
前言:由于之前没有接触过Hibernate框架,但是最近看一些博客深深被它的"效率"所吸引,所以这就来跟大家一起就着一个简单的例子来尝尝Spring全家桶里自带的JPA的鲜 Spr ...
随机推荐
- RR有幻读问题吗?MVCC能否解决幻读?
幻读是 MySQL 中一个非常普遍,且面试中经常被问到的问题,如果你还搞不懂什么是幻读?什么是 MVCC?以及 MySQL 中的锁?那么请好好收藏和阅读本篇文章,因为它非常重要. RR 隔离级别 在 ...
- 通过python,将excel中的数据写入二维列表
需求:读取Excel表中数据,每行数据放在一个列表中,再把所有列表都存入到一个列表中,形成二维列表. 实现方法:导入可在Python处理Excel表格数据的模块. excel表: 方法一:xlwing ...
- Electron-builder打包和自动更新
Electron-builder打包和自动更新 前言 文本主要讲述如何为 electron 打包出来软件配置安装引导和结合 github 的 release 配置自动更新. electron-buil ...
- [kubernetes]二进制部署k8s集群-基于containerd
0. 前言 k8s从1.24版本开始不再直接支持docker,但可以自行调整相关配置,实现1.24版本后的k8s还能调用docker.其实docker自身也是调用containerd,与其k8s通过d ...
- Zimbra禁止接收带有加密的文件邮件 提醒病毒(Heuristics.Encrypted.PDF)
最近碰到一个国际性大客户,一定要发送经过加密的文件,因为是合约相关的文件,对方公司有这方面要求.但是Zimbra默认是禁止接收加密的文件 - 'Block encrypted archives',这样 ...
- 【LaTeX】语法(更新中)
目录 长度 空行 空格 超链接 数学公式 段落中(隐式) 单独成段(显式) 居中,左对齐,右对齐 居中 左对齐 右对齐 参考文献配置 TODO 参考资料 中文支持参考环境配置中的 内容,在这里不做重复 ...
- (2023.8.28)Hi铁布衫-CM Ver 0.001 - Cracked-writeup
Hi铁布衫-CM Ver 0.001 WriteUp 本文作者:XDbgPYG(小吧唧) 发布时间:2023年8月28日 内容概要:Hi铁布衫-CM Ver 0.001 WriteUp 收集信息 有一 ...
- [Python] 今天开始学习Python3了, 纪念一下
#! /usr/bin/env python3 import time print("你好, 请告诉我你的名字.") name = input("名前: ") ...
- MySQL 分表查询
分表是一种数据库分割技术,用于将大表拆分成多个小表,以提高数据库的性能和可管理性.在MySQL中,可以使用多种方法进行分表,例如基于范围.哈希或列表等.下面将详细介绍MySQL如何分表以及分表后如何进 ...
- Solution -「HNOI 2016」最小公倍数(lacks of code)
Description Link. 给出一个带权无向图,边权为 \(2^{a}\cdot3^{b}\) 形式. 给出 \(q\) 组形如 \(u,v,a,b\) 的询问,问 \(u,v\) 中是否存在 ...