【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 ...
随机推荐
- 2023-08-14:用go语言写算法。给出两个长度相同的字符串 str1 和 str2 请你帮忙判断字符串 str1 能不能在 零次 或 多次 转化 后变成字符串 str2 每一次转化时,你可以将
2023-08-14:用go语言写算法.给出两个长度相同的字符串 str1 和 str2, 请你帮忙判断字符串 str1 能不能在 零次 或 多次 转化 后变成字符串 str2, 每一次转化时,你可以 ...
- centos7关闭防火墙后只有22端口可以telnet的解决方法
1.问题描述 防火墙已经关闭 22端口可以telnet 其他端口无法telnet 2.解决方法 注意:下列命令要用root账号/权限执行 2.1.开启防火墙 systemctl start firew ...
- stencilJs学习之构建 Drawer 组件
前言 在之前的学习中,我们已经掌握了 stencilJs 中的一些核心概念和基础知识,如装饰器 Prop.State.Event.Listen.Method.Component 以及生命周期方法.这些 ...
- 获得lazada商品详情 API 返回值说明
item_get-获得lazada商品详情 注册开通 lazada.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) se ...
- iOS日志获取
IOS日志获取 崩溃日志存放目录: /var/mobile/Library/Logs/CrashReporter
- Asp-Net-Core开发笔记:FrameworkDependent搭配docker部署
前言 之前我写过一篇使用 docker 部署 AspNetCore 应用的文章,这种方式搭配 CICD 非常方便, build 之后 push 到私有的 dockerhub ,在生产服务器上 pull ...
- 如何理解SpringBoot的Starter
Starter是SpringBoot的四大核心功能特性之一,除此之外,SpringBoot还有自动装配,Actuator监控等特性 SpringBoot里面的这些特性,都是为了让开发者在开发基于Spr ...
- 使用GPU搭建支持玛雅(Maya)和Adobe AI,DW,PS的职校云计算机房
背景 学校为职业学校,计算机教室需要进行Maya.Adobe Illustrator.Adobe Dreamweaver.Adobe PhotoShop等软件的教学.每个教室为35用户.资源需求为4核 ...
- 4399 Flash游戏专用浏览器, 无需安装Flash插件
目前所有的主流浏览器都已经不再支持Flash了,即使有一些国内浏览器还支持flash,但只能安装国内特供版Flash Player. 但问题的关键在于,这个国内特供版跟 Adobe 海外发行的版本是两 ...
- HTML一键打包IPA(苹果IOS应用)工具 网站打包 APP
工具简介 HTML一键打包IPA(苹果应用)工具可以把本地HTML项目或者网站打包为一个苹果应用IPA文件,无需编写任何代码,支持在苹果设备上安装运行. 该软件已经被GDB苹果网页一键打包工具取代,详 ...