# 代码
## 概述
修改代码架构, 使用Mapstruct和Lombok解决setter(),getter()以及查询结果到dto的转换
[Mapstruct文档](http://https://mapstruct.org/documentation/1.5/reference/html/#Preface "Mapstruct文档") [Lombok简单介绍](https://cloud.tencent.com/developer/article/1698734 "Lombok简单介绍")
一个控制层可以依赖多个应用
一个应用层只有一个仓库和多个服务
仓库由一个或多个DAO组成
每一层的方法都需要描述输入输出信息
## 控制层
**总体代码**
控制层只存在将请求参数转换成命令和调用应用方法的代码, 如图

**注释**
在方法的注释中应该描述输入和输出的数据, 接口的功能
**输入输出**
控制层应该输入DTO输出DTO
**与应用的关系**
一个控制可以依赖多个应用
**输入校验**
不在dto上使用注释控制输入数据限制, 而是在值对象的构造方法中判断
## 应用层
**总体代码**
应用层只包含流程代码, 不应出现业务代码(具体逻辑,控制语句,循环语句)
具体的业务代码由服务层和实体完成
应用层应该明确职责, 如用户的增删查改与用户行为应该独立分为两个应用
**注释**
在方法的注释中描述输入和输出的数据, 接口的功能
**输入输出**
应用层接受命令类型输入,如:command,query,event, 输出DTO类型
**与仓库的关系**
一个应用使用一个仓库
## 服务层
**总体代码**
具体的业务逻辑,单个服务的功能应该要单一,如新增用户时对用户名的唯一校验需要一个服务, 可以使前后台共用一个服务校验
**与仓库的关系**
服务不允许依赖仓库, 通过方法传参的形式传入仓库调用仓库方法
**与其他服务的关系**
允许服务层之间相互依赖,
## 仓库层
**总体代码**
不应出现业务逻辑
**注释**
在方法的注释中应该描述输入和输出的数据, 接口的功能
**与DAO的关系**
依赖一个或多个DAO, 只依赖应用或服务需要用到的DAO
包括redis,mogodb等
## DAO层
**总体代码**
原来的mapper层前后台所使用的sql应该独立避免,逻辑混乱
**注释**
在方法的注释中应该描述输入和输出的数据, 接口的功能
## 目录结构
```
root
|
|____controler 控制层
|
|____types 类型
| |
| |____dto 请求或响应数据对象
| |
| |____cmd 命令出查询外的请求
| |
| |____query 查询请求
| |
| |____event 事件
|
|____exception 异常
| |
| |____handle 异常处理
|
|____application 应用层
| |
| |____assembler 转换层
|
|____domain 领域层
| |
| |____entity 实体
| |
| |____vo 值对象
|
|____facade 装饰层
|
|____service 服务层
|
|____repository 仓库层
|
|____convert 转换层
|
|____mapper/dao 接口层
|
|____do 数据对象
```
## 实体与仓库的创建
### 实体
区分实体与值对象的关键在于是否有状态
实体必须包含主键
主键接口
```
import java.io.Serializable;
public interface Id extends Serializable {
long serialVersionUID = 1L;
}
```
实体接口
```
public interface Entity<id extends Id>{
id getId();
}
```
### 仓库
仓库接口
```
// 其中的实体表示仓库属于哪个领域, 仓库能查询的字段应该被包含在实体内
public interface Repo<entity extends Entity<id>, id extends Id> {
// 常用方法
entity findById(id id);
entity save(entity entity);
}
```
# SQL
所有列表SQL都需要倒序