目标
通过本章节介绍可以让开发者通过数据表生成CRUD代码
操作示例
1. 首先切换到工程目录下
先进行登录
pai login
2. 根据提示帮助,选择语句。
查看生成代码帮助
pai code -h
根据表结构生成代码
语法:
pai code [参数]
参数:
-h,--help 使用帮助
-t,--table <arg> 表名
-n,--name <arg> 工程名称(默认当前目录名称)
-o,--output <arg> 文件保存绝对路径(默认当前路径)
示例:
pai code -t user
pai code -t user -n pai-demo
生成代码
pai code -n pai-demo-one -t cars
3. 到这里代码已经自动生成了
我们使用idea打开该项目,打开src目录,相比刚创建的工程,部分增加的代码都是根据你的表结构所自动生成的。
以下是项目创建好后大致的src目录结构:
├─main
│ ├─java
│ │ └─cn
│ │ └─flyrise
│ │ └─pai
│ │ └─demoone
│ │ │ Application.java
│ │ ├─config
│ │ ├─controller
│ │ │ CarsController.java
│ │ ├─dao
│ │ │ CarsMapper.java
│ │ ├─exception
│ │ │ BusinessErrors.java
│ │ │ DemoOneBizException.java
│ │ ├─model
│ │ │ ├─po
│ │ │ │ CarsPO.java
│ │ │ └─vo
│ │ │ CarsVO.java
│ │ │
│ │ └─service
│ │ │ ICarsService.java
│ │ └─impl
│ │ CarsServiceImpl.java
│ │
│ └─resources
│ └─mapper
│ CarsDao.xml
代码结构解析
model 领域模型层
model
包分为po
、vo
两个包
po
目录来对应数据库的表的对象vo
目录是用于对外暴露的对象
例如请求的对象放vo而不要放po对象,返回值同样。
下面用一个简单的例子说明,例如一个请假表中有个审核字段 state
{0 发起 1同意 2拒绝},但是我们在写接口的时候并不会传递该值,因为发起的时候该状态就是0,而调用了同意的接口该状态才会变为1,拒绝依此类推。这就意味着我们写发起接口的时候不会有 state
该字段,所以我们用VO做为参数的时候可以吧 state
字段给去掉。
编写 model 实体
PO Model 规范
- 一个
PO
对应一张数据表 - 使用
@TableId('id')
注解标注主键 - 实体继承 BaseEntity,BaseEntity 包含(create_by:创建人,create_time:创建时间,update_by:更新人,update_time:更新时间)
- 使用
@Table (javax.persistence.Table)
映射表名 - 使用
@TableField (javax.persistence.TableField)
映射字段名 - 属性上写注释/** 注释 */
- 非数据库字段使用
@Transient
注解标注,如果页面用到的非数据库字段比较多,建议使用 DTO 封装数据。 - 所有属性均为private属性,每一个属性需要生成对应的 getter、setter 方法。
- 不使用基本类型,全部使用基本类型的包装类,如
Long
对应数据库中的INTEGER
,而不是使用long
。 - 数字类型主键统一采用
Long
。金额、数量 等精度严格浮点类型采用BigDecimal
(注意:BigDecimal 在计算、比较方面的特殊性)
VO Model 规范
- 使用
@ApiModel
注解说明实体含义,在 Swagger 文档上就可以看到实体说明。 - 实体字段使用
@ApiModelProperty
说明字段含义,在 Swagger 文档上可以看到字段说明。 - 所有属性均为private属性,每一个属性需要生成对应的 getter、setter 方法。
- 不使用基本类型,全部使用基本类型的包装类,如
Long
对应数据库中的INTEGER
,而不是使用long
。 - 数字类型主键统一采用
Long
。金额、数量 等精度严格浮点类型采用BigDecimal
(注意:BigDecimal 在计算、比较方面的特殊性)
基础设施层(dao,mapper)
Mapper 接口类
- mapper 接口类即为传统意义上的 DAO,但与 interface 不同,mapper 本身就是对数据访问的具体实现,所以属于供应方的服务实现层。创建在 项目模块 的
xxx.dao
包下。 - 每一个 mapper 接口类封装了对数据库表的操作,每一个 mapper 对应一个 实体 类,命名为 实体 类名尾缀替换为 Mapper 。
- 基础的 CRUD 操作不需要再次实现,通过继承
BaseMapper< PO >
类实现。其中 PO 为 对应 实体 的泛型。 - 复杂的数据库操作需要定义具体的接口方法
mapper.xml
- Mapper的xml文件 是数据库的的具体映射,与 Mapper 接口同级,创建在 项目模块 resources 目录下的 mapper 目录下。
- Mapper的xml文件,与 Mapper 接口对应。所以命名与 Mapper 接口类相同。
- Mapper的xml文件非必须,由于继承BaseMapper类后基本的 CRUD 不需要进行配置,所以只有CRUD操作时不需要创建对应的 xml 文件。
- 对于自定义的数据库方法,需要创建对应的 mapper.xml 文件。
- Mapper的xml 中的操作 id 对应 Mapper 接口类的方法名。
应用层(service)
service介绍
service
调用领域对象或服务来解决问题,应用层Service主要有以下特性:
- 负责事务处理,所以事务的注解可以在这一层的service中使用。
- 只处理非业务逻辑,重点是调度业务处理流程。业务逻辑处理一定要放在领域层处理。
- 不做单元测试,只做验收测试。
service 实现类介绍
ServiceImpl
实现类
- Service 接口的具体实现通过服务实现层提供,所以属于供应方的服务实现层。创建在项目模块的
xxx.service.impl
包下。 @Service
标识为Service实现类@Transactional
声明式事务管理
API 展现层
Controller介绍
Controller
负责对Model
的处理,创建在项目模块的xxx.controller
包下。- 需要通过
@Controller
指定该类为一个Controller
类。 - 使用Restful风格,使用
Post
、Delete
、Put
、Get
,使用不同的方法对资源进行操作,分别对应 添加、删除、修改、查询
Controller 类相关标签
@RestController
是一个组合注解,是@ResponseBody
和@Controller
的组合。@ApiOperation
显示在swagger ui上的接口注释,同时与该接口对应的权限表中的描述字段对应@Api(tags = "打卡API")
,在类上对类进行说明,显示在 Swagger 文档上@ApiImplicitParams
,在方法上对方法参数进行说明,显示在 Swagger 文档上@ApiParam
在方法参数上对参数进行说明,显示在 Swagger 文档上@GetMapping
是@RequestMapping(mathod = RequestMethod.GET)
的缩写,处理get请求@PostMapping
处理post请求@PutMapping
处理put请求@DeleteMapping
处理delete请求
建议URI规范
每个URI代表一种资源或者资源集合,因此,建议只包含名词,不包含动词。
那么,如何告诉服务器端我们需要进行什么样的操作?CRUD?
答案是由HTTP动词表示。
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
- DELETE(DELETE):从服务器删除资源。
举个例子
- GET /zoos:列出所有动物园
- POST /zoos:新建一个动物园
- GET /zoos/ID:获取某个指定动物园的信息
- PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息)
- PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息)
- DELETE /zoos/ID:删除某个动物园
- GET /zoos/ID/animals:列出某个指定动物园的所有动物
- DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物
文档更新时间: 2023-02-28 09:24 作者:欧阳少海