【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 ...
随机推荐
- [jenkins]连接git仓库
连接gitlab 在jenkins添加全局凭据,类型为"ssh username with private key",填写git用户名和ssh私钥信息(注意是git客户端所在机器的 ...
- [prometheus]配置alertmanager和钉钉告警
目录 prometheus发起告警的逻辑 节点 配置alertmanager 配置钉钉告警插件 配置supervisor守护进程 关联prometheus和alertmanager prometheu ...
- nflsoj 选数1 2 3
5711 取数-1 状态表示:1维 集合:前 \(i\) 个数里面所有的选法和 属性:所有的选法和的最大值 状态计算:选或不选 选:\(f(i-1)+a_i\) 不选:\(f(i-1)\) #incl ...
- Badusb制作,远程别人电脑
Badusb制作 插一下U盘黑一台电脑,插了我的U盘你可就是我的脑了,(▽) 理论准备 我们要用它就应该知道他的工作原理是怎么样的,方便我们去发散思维去使用它. Badusb的原理是利用HID(Hum ...
- 获得lazada商品详情 API 返回值说明
item_get-获得lazada商品详情 注册开通 lazada.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) se ...
- WPF学习 - 自定义窗体(二)
上一篇文章写了如何创建自定义窗体:使用 WindowChrome 或者 WindowStyle="None"这两种方式.本文将讲述如何设置窗体的效果(以阴影效果为例),以及在效果模 ...
- 全局安装oh-my-zsh保姆教程
我的系统是CentOS 7.6,按流程走完后可以实现系统内所有用户都默认使用zsh且插件配置共享省去重复编写配置或软连接的烦恼 1 安装git yum -y install git 2 安装zsh y ...
- 大模型时代,如何快速开发AI应用
本文分享自华为云社区 <[云享问答]第3期:大模型时代,如何快速开发AI应用>,作者:华为云社区精选. 大模型快速普及应用的当下,AI浪潮汹涌而至,对于开发者来说,开发一款属于自己的AI应 ...
- IP协议:连接你我,掌握互联网的关键
IP 基本认识 在之前的章节中,我们已经详细介绍了应用层和传输层的相关概念和原理,了解了进程之间如何进行可靠的数据传输.我们知道,传输层的头部包含了进程所使用的端口信息,这是为了确保数据能够正确地传递 ...
- C51单片机开发
C51单片机开发笔记 定时器 C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器 或者计数器使用. 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信 ...