针对数据库客操作,我们需要借助ORM来完成数据库访问。
本章讨论如何创建一个数据库访问组件。
1.组件命名
考虑到orm的场景比较场景,且比较重要。我们将orm组件纳入到starter的组件类型里。
命名为frame-orm-starter
2.技术选型:mybatis + mybatis plus
考虑到mybatis已有现有springboot集成的组件,我们引入如下依赖:
XML
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
3.核心类和方法实现
本组件的主要逻辑,其实就是MP(mybatis-plus)已经帮我我们实现的逻辑。
本组件对普通的mybatis处理,做了一些功能增强:如分页、逻辑删除、全局乐观锁、自动填充等。
具体方法见mybatis-plus官网说明。如自动填充的配置:
XML
mybatis-plus:
global-config:
db-config:
logic-delete-field: isDeleted # 全局逻辑删除的实体字段名
logic-delete-value: Y # 逻辑已删除值
logic-not-delete-value: N # 逻辑未删除值
创建一个配置类:包含如下内容:
3.1 定义插件(如分页)
java
@Bean
public PaginationInnerInterceptor paginationInnerInterceptor() {
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor();
// 设置最大单页限制数量,-1 不受限制
paginationInterceptor.setMaxLimit(200L);
paginationInterceptor.setDbType(DbType.MYSQL);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setOptimizeJoin(true);
return paginationInterceptor;
}
3.2 装配插件拦截器
java
/**
* 定义MP插件主体 MybatisPlusInterceptor
* 使用多个功能插件需要注意顺序关系,建议使用如下顺序
* 分页,乐观锁
* sql 性能规范,防止全表更新与删除
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//分页插件
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor());
//乐观锁
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
4.扩展特性
如果mybatis-plus默认的mapper方法无法满足我们的需要,还可以基于DefaultSqlInjector 进行扩展 定制的SQL 注入器。实现更多方法。如批量修改、批量添加等。
思考题:
一般情况下,公司都要求数据库表设计时,有统一的字段。比如创建时间、修改时间、创建人、修改人等。那么这些通用字段就可以通过框架规范来处理。
比如定义一个通用的BasePO 类 。业务实现的所有PO 类都要继承此基类。
java
@Data
public class BasePO implements Serializable {
private static final long serialVersionUID = -33333333L;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date modifyTime;
/**
* 创建人
*/
private String creator;
/**
* 修改人
*/
private String modifier;
}
那么问题来了,这个类是要放在frame-base里呢?还是放在frame-orm-starter组件中?欢迎大家留言讨论。