1. 原型设计
1.1 系统登录页面
1.2 系统登录成功页面
1.3 菜单展示页面
2. 项目分层架构图
- 开放接口层:可直接封装 Service 方法暴露成 RPC (远程过程调用)接口;也可通过
Web 封装成 http 接口;同时也可进行网关安全控制、流量控制等。 - 终端显示层:负责各个端的模板渲染并显示。当前主要是 thymeleaf 渲染,JS 渲
染,移动端展示等。 - Web 请求处理层:主要是对访问控制进行转发,请求参数校验,响应结果处理等
- Service 层:相对具体的业务逻辑服务层(核心业务,扩展业务)。
- Manager 层:通用业务处理层,它有如下特征:
1) 对第三方平台封装的层,预处理返回结果及转化异常信息;
2) 对 Service 层通用能力的下沉,如缓存方案、中间件通用处理;
3) 与 DAO 层交互,对多个 DAO 的组合复用。 - DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase 等进行数据交互。
- 外部接口或第三方平台:包括其它部门 RPC 开放接口,基础平台,其它公司的HTTP 接口
3. 基本环境搭建
3.1 数据库初始化
3.2 Idea初始化
- 统一工作区编码(UTF-8)
- 统一 JDK 版本(JDK1.8)
- 统一 MAVEN 配置(3.6.3)
3.3 创建项目
3.3.1 各项目模块关系设计
3.3.2 创建parent父工程
3.3.2.1 删除src等多余文件
3.3.2.2 打包成pom
3.3.2.3 导入依赖jar包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>15-dbpms-parent</name>
<description>Demo project for Spring Boot</description>
<packaging>pom</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.3.3 创建common子工程
3.3.3.1 pom.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>15-dbpms-common</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
3.3.4 创建admin子工程
3.3.4.1 pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-admin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>15-dbpms-admin</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.cy</groupId>
<artifactId>15-dbpms-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
3.3.4.2 修改application配置文件
#server port
server:
port: 80
#spring
spring:
main:
banner-mode: off
datasource:
url: jdbc:mysql:///dbms?serverTimezone=GMT%2B8&characterEncoding=utf8
username: root
password: root
thymeleaf:
cache: false
prefix: classpath:/templates/modules/
aop:
proxy-target-class: true
task:
execution:
pool:
core-size: 8
max-size: 256
keep-alive: 60000
queue-capacity: 256
thread-name-prefix: db-service-thread-
#mybatis
mybatis:
mapper-locations: classpath:/mapper/*/*.xml
#log
logging:
level:
com.cy: debug
4. 首页初始化
4.1 定义页面初始资源
- 将 js、css、images 相关资源拷贝到项目 static 目录
- 将 pages 目录下的资源拷贝到项目的 templates 的 modules 目录
4.2 创建页面 Controller
说明: 此controller会作为项目中所有页面访问的入口
@Controller
@RequestMapping("/")
public class PageController{
@RequestMapping("doIndexUI")
public String doIndex(){
return "starter";
}
}
4.3 访问首页测试
- 启动tomcat,输入: http:localhost/doIndexUI,访问首页,出现如下页面则访问成功
5. 总结
5.1 FAQ分析
- 项目是如何进行分层设计? --基于spring-MVC实现
- 页面是如何进行设计? – 基于BootStrap,使用AdminLTE进行页面实现.网址(adminlte.io)
- 客户端向服务端发起一个请求,服务端处理请求过程?
5.2 BUG分析
- 解决方案:
- 检查 url 是否正确(是否有对应的映射)
- 检查 controller 的包是否正确以及是否有对应的注解(例如@Controller)进行描述
- 解决方案:
- 假如 starter 是模板,检查响应页面是否存在.
- 检查配置文件中视图的前缀、后缀是否正确
- 检查配置文件中的配置是否与对应的目录是一致.
5.3 在common类中添加公共类(Pojo,Exception,Json,Utils)
- 何为序列化,反序列化?(I/O)-类似生活中拼图
- 序列化:将对象转换为字节的过程
- 反序列化:将字节转换为对象的过程
- 序列化的应用场景
- 将内存中的对象直接存储到文件
- 将内存中的对象通过网络进行传输
- serialVersionUID,是序列化/反序列化时的唯一标识,当类的结构发生变化时,只要serialVersionUID不变,JVM底层都认为它是同一个类。
- 序列化实现
- ObjectOutputStream (序列化)–>writeObject
- ObjectInputStream (反序列化)–>readObject
5.3.1 响应标准对象设计类
说明:响应标准对象设计,用于封装服务端响应到客户端的数据
package com.cy.pj.common.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
public class JsonResult implements Serializable {
private static final long serialVersionUID = -4971076199594828397L;//ResultResult
private Integer state=1;
private String message="ok";
private Object data;
public JsonResult(String message){
this.message=message;
}
public JsonResult(Object data){
this.data=data;
}
public JsonResult(Throwable e){
this.state=0;
this.message=e.getMessage();
}
}
5.3.2 全局异常处理类
package com.cy.pj.common.web;
import com.cy.pj.common.pojo.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public JsonResult doHandleRuntimeException(RuntimeException e){
log.error("exception {}",e.getMessage());
e.printStackTrace();
return new JsonResult(e);
}
}
5.3.3 自定义业务层异常处理类
- 自定义业务层异常 (一般是继承RuntimeException)
- 通过自定义异常,对项目中业务业务异常进行更好的定位和分析
package com.cy.pj.common.exception;
public class ServiceException extends RuntimeException{
public ServiceException() {
}
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
public ServiceException(Throwable cause) {
super(cause);
}
}
5.3.4 自定义数据层异常处理类
package com.cy.pj.common.exception;
public class DaoException extends RuntimeException {
public DaoException() {
}
public DaoException(String message) {
super(message);
}
public DaoException(String message, Throwable cause) {
super(message, cause);
}
public DaoException(Throwable cause) {
super(cause);
}
}
5.3.5 封装分页信息类
package com.cy.pj.common.pojo;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
/**用于封装分析信息的pojo对象*/
//泛型<T>:方便后期进行自定义类型
public class PageObject<T> implements Serializable {
private static final long serialVersionUID = -3130527491950235344L;
/**总记录数*/
private Integer rowCount;
/**当前页记录*/
private List<T> records;
/**总页数*/
private Integer pageCount;
/**页面大小-每页最多显示的记录数*/
private Integer pageSize;
/**当前页码值*/
private Integer pageCurrent;
public PageObject(Integer rowCount, List<T> records, Integer pageSize, Integer pageCurrent) {
this.rowCount = rowCount;
this.records = records;
this.pageSize = pageSize;
this.pageCurrent = pageCurrent;
this.pageCount=rowCount/pageSize;
if(rowCount%pageSize!=0)this.pageCount++;
}
}