单一架构案例
本章节将以创建一个单一架构的业务系统,从搭建到部署的过程,演示Maven项目
完整代码gitee地址:https://gitee.com/reportories/maven_study_all_in_one.git
一、创建工程,引入依赖
1.架构
①架构的概念
架构其实就是项目的结构,只是因为架构是一个更大的词,通常来形容比较大规模事物的结构。
②单一架构
单一架构也叫all-in-one的结构,就是所有的代码、配置文件、各种资源都在同一个工程
- 一个项目包含一个工程
- 导出一个war包
- 放在一个Tomcat上运行
2.创建工程
3. 引入依赖
①搜索依赖信息的网站
【1】 到哪找?
【2】怎么选择?
- 确定技术选型:确定我们项目中要使用哪些技术
- 到网站去搜索具体技术的依赖信息
- 确定这个技术使用哪个版本的依赖
- 考虑因素1:看是否有别的技术要求这里必须使用某一个版本
- 考虑因素2:如果没有硬性要求,那么选择较高版本或者下载量的版本
- 在实际使用中检验所有依赖信息是否都正常可用
tips:
确定技术选型、组件依赖列表,项目划分模块等操作都是属于架构设计的范围。
- 项目本身所属行业的基本特点
- 项目具体的功能需求
- 项目预计访问压力程度
- 项目预计将来需要扩展的功能
②持久化层所需依赖
首先确保自己本机已经安装了mysql数据库,安装过程不再赘述。
mysql依赖
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
druid依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
③表示层所需依赖
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
④辅助功能所需依赖
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
⑤最终完整依赖信息
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
4.建包
package功能 | package名称 |
---|---|
主包 | com.sr.maven |
子包【实体类】 | com.sr.maven.entity |
子包 【servlet基类包】 | com.sr.maven.servlet.base |
子包 【servelet模块包】 | com.sr.maven.servlet.module |
子包 【servlet接口包】 | com.sr.maven.servlet.api |
子包 【servlet实现类包】 | com.sr.maven.servlet.imp |
子包 【Dao接口包】 | com.sr.maven.dao.api |
子包 【Dao实现类包】 | com.sr.maven.dao.imp |
子包【Filter过滤器包】 | com.sr.maven.filter |
子包 【异常类包】 | com.sr.maven.exception |
子包 【工具类包】 | com.sr.maven.util |
子包 【测试类包】 | com.sr.maven.test |
二、搭建环境:持久化层
1.数据建模
①物理建模
在mysql数据库运行sql语句,进行物理建模,建表
CREATE DATABASE db_imperial_court;
USE db_imperial_court;
CREATE TABLE t_emp (
emp_id INT PRIMARY KEY auto_increment,
emp_name CHAR ( 100 ) NOT NULL,
emp_position CHAR ( 100 ) NOT NULL,
login_account CHAR ( 100 ) NOT NULL UNIQUE,
login_password CHAR ( 100 ) NOT NULL
);
INSERT INTO t_emp ( emp_name, emp_position, login_account, login_password )
VALUES# 16540504
( '爱新觉罗.玄烨', 'emperor', 'xiaoxuanzi1654', '25325c896624D444B2E241807DCAC988' ),
( '纳兰明珠', 'minister', 'brightba771635', '25325c896624D444B2E241807DCAC988' ),
( '赫舍里.索额图', 'minister', 'tutu1636', '25325c896624D444B2E241807DCAC988' );
CREATE TABLE t_memorials (
memorials_id INT PRIMARY KEY auto_increment,
memorials_title CHAR ( 100 ) NOT NULL,
memorials_content VARCHAR ( 5000 ) NOT NULL,
memorials_emp INT NOT NULL,
memorials_create_time CHAR ( 100 ),
feedback_time CHAR ( 100 ),
feedback_content VARCHAR ( 1000 ),
memorials_status INT NOT NULL
);
INSERT INTO t_memorials ( memorials_title, memorials_content, memorials_emp, memorials_create_time, feedback_time, feedback_content, memorials_status )
VALUES# 16540504
( '浙江巡抚奏钱塘江堤决口疏', '皇上啊,不好了!钱塘江发大水啦!堤坝冲毁啦!您看咋弄啊!', 2, '1690-05-07', NULL, NULL, 0 ),
( '左都御史参鳌拜圈地口疏', '皇上啊,鳌拜这厮不是东西啊!占老百姓的地呀,还打人呀!您看咋弄啊', 3, '1690-04-14', NULL, NULL, 0 ),
( '督察员参吴三桂不臣疏', '皇上啊,不好了!吴三桂那孙子想造反!', 2, '1693-11-18', NULL, NULL, 0 ),
( '兵部奏准噶尔犯境疏', '皇上啊,不好了!噶尔丹要打过来了!', 3, '1693-11-18', NULL, NULL, 0 );
②逻辑建模
【1】Emp实体类
package com.sr.maven.entity;
public class Emp {
private Integer empId;
private String empName;
private String empPosition;
private String loginAccount;
private String loginPassword;
public Emp() {
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpPosition() {
return empPosition;
}
public void setEmpPosition(String empPosition) {
this.empPosition = empPosition;
}
public String getLoginAccount() {
return loginAccount;
}
public void setLoginAccount(String loginAccount) {
this.loginAccount = loginAccount;
}
public String getLoginPassword() {
return loginPassword;
}
public void setLoginPassword(String loginPassword) {
this.loginPassword = loginPassword;
}
}
【2】Memorials实体类
public class Memorials {
private Integer memorialsId;
private String memorialsTitle;
private String memorialsContent;
private String memorialsContentDigest;
private Integer memorialsEmp;
private String memorialsEmpEmpName;
private String memorialsCreateTime;
private String feedbackTime;
private String feedbackContent;
private Integer memorialsStatus;
public Memorials() {
}
public Integer getMemorialsId() {
return memorialsId;
}
public void setMemorialsId(Integer memorialsId) {
this.memorialsId = memorialsId;
}
public String getMemorialsTitle() {
return memorialsTitle;
}
public void setMemorialsTitle(String memorialsTitle) {
this.memorialsTitle = memorialsTitle;
}
public String getMemorialsContent() {
return memorialsContent;
}
public void setMemorialsContent(String memorialsContent) {
this.memorialsContent = memorialsContent;
}
public String getMemorialsContentDigest() {
return memorialsContentDigest;
}
public void setMemorialsContentDigest(String memorialsContentDigest) {
this.memorialsContentDigest = memorialsContentDigest;
}
public Integer getMemorialsEmp() {
return memorialsEmp;
}
public void setMemorialsEmp(Integer memorialsEmp) {
this.memorialsEmp = memorialsEmp;
}
public String getMemorialsEmpEmpName() {
return memorialsEmpEmpName;
}
public void setMemorialsEmpEmpName(String memorialsEmpEmpName) {
this.memorialsEmpEmpName = memorialsEmpEmpName;
}
public String getMemorialsCreateTime() {
return memorialsCreateTime;
}
public void setMemorialsCreateTime(String memorialsCreateTime) {
this.memorialsCreateTime = memorialsCreateTime;
}
public String getFeedbackTime() {
return feedbackTime;
}
public void setFeedbackTime(String feedbackTime) {
this.feedbackTime = feedbackTime;
}
public String getFeedbackContent() {
return feedbackContent;
}
public void setFeedbackContent(String feedbackContent) {
this.feedbackContent = feedbackContent;
}
public Integer getMemorialsStatus() {
return memorialsStatus;
}
public void setMemorialsStatus(Integer memorialsStatus) {
this.memorialsStatus = memorialsStatus;
}
}
2.数据库连接信息
编写自己的数据库配置
driverClassName=com.mysql.cj.jdbc.Driver
url= jdbc:mysql://localhost:3306/db_imperial_court?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username=自己的账户
password=自己的密码
initialSize=10
maxActive=20
maxWait=10000
3.获取数据库连接
①创建JDBCUtils工具类
首先先放出完整的工具类内容,下面进行分步骤的添加解释
package com.sr.maven.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* 功能1:从数据源获取数据库链接
* 功能2:将数据源获取到数据库连接绑定到本地线程 ThreadLocal
* 功能3:释放线程时和本地超线程解除绑定
*/
public class JDBCUtils {
//数据源成员变量,设置为静态资源,保证大对象的单例性,同时保证静态方法中可以访问
private static DataSource dataSource;
//由于ThreadLocal对象需要作为绑定数据时K-v对中的key,所以需要保证唯一性
//加static声明为静态资源可保证唯一性
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
//在静态代码块中初始化数据源
static {
try {
//从jdbc.properties中读取链接数据库的信息
//为了保证程序代码的可移植性,需要基于一个确定的基准来读取这个文件
//确定的基准,类路径的根目录,resource目录下的内容经过构建后打包操作会确定放在 WEB-INF/classes目录下。
//WEB-INF/classes 目录存放编译好的*.class字节码文件,所以这个目录我们就称之为类路径
//类路径无论是在本地运行还是在服务器端运行都是一个确定的路径
//具体操作代码
//1.获取当前类的类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
//2.通过类加载器对象从类路径根目录下读取文件
InputStream stream = classLoader.getResourceAsStream("jdbc.properties");
//3.使用Properties类封装属性文件中的数据
Properties properties = new Properties();
properties.load(stream);
//4.根据Properties对象(已经封装了数据库连接信息)来创建数据源对象
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
//为了避免在真正抛出异常后,catch块捕捉获取到异常掩盖问题
//这里将所捕获的异常封装为运行时异常继续抛出去
throw new RuntimeException(e);
}
}
public static Connection getConnection() {
Connection connection;
try {
//1.尝试从当前线程检查是否已存在绑定的Connection对象
connection = threadLocal.get();
//2.检查Connection对象是否为null
if (connection == null) {
connection = dataSource.getConnection();
//绑定到当前线程
threadLocal.set(connection);
}
}catch (SQLException e){
e.