cn.mybatisboost:mybatis-boost-spring-boot-autoconfigure

Boost your mybatis sql developing experience

License

License

Categories

Categories

Spring Boot Container Microservices Auto Application Layer Libs Code Generators config Configuration MyBatis Data ORM
GroupId

GroupId

cn.mybatisboost
ArtifactId

ArtifactId

mybatis-boost-spring-boot-autoconfigure
Last Version

Last Version

2.3.2
Release Date

Release Date

Type

Type

jar
Description

Description

Boost your mybatis sql developing experience

Download mybatis-boost-spring-boot-autoconfigure

How to add to project

<!-- https://jarcasting.com/artifacts/cn.mybatisboost/mybatis-boost-spring-boot-autoconfigure/ -->
<dependency>
    <groupId>cn.mybatisboost</groupId>
    <artifactId>mybatis-boost-spring-boot-autoconfigure</artifactId>
    <version>2.3.2</version>
</dependency>
// https://jarcasting.com/artifacts/cn.mybatisboost/mybatis-boost-spring-boot-autoconfigure/
implementation 'cn.mybatisboost:mybatis-boost-spring-boot-autoconfigure:2.3.2'
// https://jarcasting.com/artifacts/cn.mybatisboost/mybatis-boost-spring-boot-autoconfigure/
implementation ("cn.mybatisboost:mybatis-boost-spring-boot-autoconfigure:2.3.2")
'cn.mybatisboost:mybatis-boost-spring-boot-autoconfigure:jar:2.3.2'
<dependency org="cn.mybatisboost" name="mybatis-boost-spring-boot-autoconfigure" rev="2.3.2">
  <artifact name="mybatis-boost-spring-boot-autoconfigure" type="jar" />
</dependency>
@Grapes(
@Grab(group='cn.mybatisboost', module='mybatis-boost-spring-boot-autoconfigure', version='2.3.2')
)
libraryDependencies += "cn.mybatisboost" % "mybatis-boost-spring-boot-autoconfigure" % "2.3.2"
[cn.mybatisboost/mybatis-boost-spring-boot-autoconfigure "2.3.2"]

Dependencies

compile (5)

Group / Artifact Type Version
org.springframework.boot : spring-boot-autoconfigure Optional jar
org.springframework.boot : spring-boot-configuration-processor Optional jar
cn.mybatisboost : mybatis-boost-core jar 2.3.2
org.mybatis : mybatis Optional jar 3.4.6
org.mybatis.spring.boot : mybatis-spring-boot-starter Optional jar 1.3.2

Project Modules

There are no modules declared in this project.

MybatisBoost Maven central Build Status Coverage Status

Mybatis SQL开发神器MybatisBoost,为Mybatis带来诸多官方没有的高级特性,包含通用CrudMapperMybatis语法增强字段生成JSON映射智能方法查询无感知分页SQL指标与监控、流式查询(开发中...)等功能,使用MybatisBoost来提升开发效率,轻松编写SQL代码!

使用MybatisBoost的最低要求:

  • JDK 1.8+
  • MyBatis 3.4.4+

快速开始

基于Spring Boot以及mybatis-spring-boot-starter项目的快速开始。

Maven:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>cn.mybatisboost</groupId>
    <artifactId>mybatis-boost-spring-boot-starter</artifactId>
    <version>2.3.3-SNAPSHOT</version>
</dependency>

Gradle:

compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
compile 'cn.mybatisboost:mybatis-boost-spring-boot-starter:2.3.3-SNAPSHOT'

在手动创建SqlSessionFactory Bean的情况下,请确保MybatisBoost的Mybatis Plugin有被加载。

@Bean
public SqlSessionFactory sqlSessionFactory(ObjectProvider<Interceptor[]> interceptorsProvider) {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setPlugins(interceptorsProvider.getIfAvailable()); // 确保加载了所有的Mybatis Plugin
    sessionFactory.setTypeHandlers(new TypeHandler[]{new JsonTypeHandler()}); // 确保加载了JSON映射所需的Mybatis TypeHandler
    ...
}

如果你的数据库Table名称与项目中的POJO类名一致,Table的列名称与POJO属性的名称命名方式也一致的话(大小写忽略),那么恭喜你,你已经成功引入了MybatisBoost,可以跳过下一章《名称映射》的内容。

后续内容将使用术语“表”来代表数据库中的表,“列”来代表数据库表中的列,“POJO”来代表对应的实体类,“属性”和“字段”来代表POJO中的成员变量

名称映射

配置名称映射是为了使MybatisBoost能自动地找到POJO对应的表,以及POJO中的属性对应的列。名称映射分为自动映射和手动标注两种方案。

对于表名与POJO类名之间的自动映射,MybatisBoost内置有几个常用的表名映射器,如果内置的表名映射器无法满足你的需求,你也可以基于NameAdaptor接口实现自己的表名映射器。

表名映射器 POJO类名 映射到的表名
NoopNameAdaptor DemoTable DemoTable
TPrefixedNameAdaptor DemoTable T_DemoTable
SnakeCaseNameAdaptor DemoTable demo_table

MybatisBoost默认使用NoopNameAdaptor表名映射器,对应的application.properties配置如下:

mybatisboost.name-adaptor=cn.mybatisboost.core.adaptor.NoopNameAdaptor

对于列名与属性名之间的自动映射,MybatisBoost采用了Mybatis内置的MapUnderscoreToCamelCase功能,默认使用CamelCase命名方式。如果你的数据库列名命名方式为snake_case命名方式,请使用如下的application.properties配置:

mybatis.configuration.map-underscore-to-camel-case=true

除了自动映射方案,MybatisBoost同样提供手动标注的功能。

现在假设你的表名为“DEMO_ThisTable”,你的POJO类名为“ThatTable”,表名和POJO类名之间并无任何联系,则可以使用JPA提供的标准注解进行手动标注。

同样地,主键也可以使用JPA提供的标准注解进行手动标注。

对于列名与POJO属性名之间的映射,MybatisBoost采用约定大于配置的思想,不提供手动标注的功能。

@Table(name = "DEMO_ThisTable")
public class ThatTable {

    @Id // 默认以名称为“id”的字段作为主键,否则需要使用@Id注解手动标注
    private Long myId;
    private String myField;
    ...
}

到此,你已经可以开始使用MybatisBoost了,下面将逐一介绍MybatisBoost的各种功能特性。

基础知识

为了使MybatisBoost生效,你的Mybatis Mapper接口必须直接或间接地继承GenericMapper<T>接口,范型<T>代表此Mapper对应的POJO类。

MybatisBoost提供的所有通用Mapper都继承于GenericMapper<T>接口

通用CrudMapper

继承于CrudMapper<T>接口的Mybatis Mapper接口即自动拥有了CrudMapper接口的所有功能。

CrudMapper接口中的方法使用POJO中所有的属性参与CRUD,但不包括以Selective结尾的方法,这些方法会过滤值为null的属性,即POJO中值为null的属性不参与CRUD。

带有properties参数的方法,可使用properties参数指定参与插入、更新的属性。如果properties参数的第一个字符串为!,则代表排除后续指定的属性,如new String[]{"!", "id"}则代表除“id”以外,其他属性都参与CRUD。

同样地,带有conditionProperties参数的方法,可使用conditionProperties参数指定用于WHERE条件的属性。

CrudMapper中的所有方法如下:

public interface CrudMapper<T> {

    int count(T entity, String... conditionProperties);
    T selectOne(T entity, String... conditionProperties);
    List<T> select(T entity, String... conditionProperties);
    List<T> selectWithRowBounds(T entity, RowBounds rowBounds, String... conditionProperties);
    int countAll();
    List<T> selectAll();
    List<T> selectAllWithRowBounds(RowBounds rowBounds);
    T selectById(Object id);
    List<T> selectByIds(Object... ids);
    int insert(T entity, String... properties);
    int batchInsert(List<T> entities, String... properties);
    int insertSelective(T entity, String... properties);
    int batchInsertSelective(List<T> entities, String... properties);
    int update(T entity, String... conditionProperties);
    int updatePartial(T entity, String[] properties, String... conditionProperties);
    int updateSelective(T entity, String... conditionProperties);
    int updatePartialSelective(T entity, String[] properties, String... conditionProperties);
    int delete(T entity, String... conditionProperties);
    int deleteByIds(Object... ids);
}

如果你不需要CrudMapper接口里的所有方法,可以把CrudMapper接口中你所需的方法复制到你自己的Mybatis Mapper里即可。(需要把方法上的注解也一并复制。)

MySQL CrudMapper

除了通用的CrudMapper,MybatisBoost还提供专用于MySQL的MysqlCrudMapper<T>接口,在CrudMapper的基础上,增加了几个支持MySQL特性的方法。

public interface MysqlCrudMapper<T> extends CrudMapper<T> {

    int save(T entity, String... properties);
    int saveSelective(T entity, String... properties);
    int batchSave(List<T> entity, String... properties);
    int batchSaveSelective(List<T> entity, String... properties);
    int replace(T entity, String... properties);
    int replaceSelective(T entity, String... properties);
    int batchReplace(List<T> entity, String... properties);
    int batchReplaceSelective(List<T> entity, String... properties);
}

其中,save方法使用的是MySQL的“ON DUPLICATE KEY UPDATE”特性,replace方法使用的是“REPLACE INTO”特性。

Mybatis语法增强

为了使SQL的编写变得更简单,MybatisBoost提供了数个Mybatis和SQL语法增强的功能,包括自动参数映射、INSERT语法增强、UPDATE语法增强、表名变量、空值检测和集合参数映射。每个增强都可以单独使用,也可以联合使用。

自动参数映射

Mybatis设计之中的一个不合理之处,在于舍弃了JDBC原生的参数占位符(即?)。显而易见的是,简单的SQL语句根本没有必要使用Mybatis的#{variable}语法去做多余的映射,这种麻烦在编写INSERT和UPDATE语句的时候尤为明显。

为此,MybatisBoost恢复了JDBC原生的参数占位符功能,MybatisBoost会自动按照参数的声明顺序做出正确的映射。

@Update("UPDATE table SET column1 = ? WHERE condition1 = ?")
int update(String a, String b);

自动参数映射目前还不支持嵌套属性,即不支持自动映射到对象中的属性

INSERT语法增强

MybatisBoost提供了更为简洁的INSERT语法,使得SQL的编写变得更为简单。

@Insert("INSERT *")
int insertOne1(T entity); // 插入一条记录,插入所有字段

@Insert("INSERT column1, column2, column3")
int insertOne2(T entity); // 插入一条记录,只插入column1、column2、column3三个字段

@Insert("INSERT NOT column4, column5")
int insertOne3(T entity); // 插入一条记录,插入除了column4、column5以外的所有字段

@Insert("INSERT *")
int insertMany(List<T> entities); // 批量插入,插入POJO中的所有字段

UPDATE语法增强

同样地,MybatisBoost提供了更为简洁的UPDATE语法。

@Update("UPDATE SET *")
int update1(T entity); // 更新所有字段

@Update("UPDATE SET column1, column2, column3")
int update2(T entity); // 只更新column1、column2、column3三个字段

@Update("UPDATE SET NOT column4, column5")
int update3(T entity); // 更新除了column4、column5以外的所有字段

@Update("UPDATE SET column1, column2 WHERE condition1 = ?")
int update3(String a, String b, String c); // 更新column1、column2两个字段,并且条件是“condition1 = c”

表名变量

在编写SQL语句时,SQL中的表名可使用#t代替,MybatisBoost会自动替换成正确的表名。

此功能不仅简化了表名的编写,还使得SQL语句具有了可重用性。

SELECT * FROM #t

空值检测

现有一条SQL语句如下:

SELECT * FROM Post WHERE id = #{id} AND Name != #{name}

假设传入的id参数和name参数都为null,则SQL会自动重写为如下的形式:

SELECT * FROM Post WHERE id IS NULL AND Name IS NOT NULL

集合参数映射

使用MybatisBoost之前,集合参数的映射方法:

<select>
    SELECT * FROM Post WHERE id IN
    <foreach item="item" index="index" collection="list"
             open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

使用MybatisBoost之后,集合参数的映射方法就如同普通参数一样:

SELECT * FROM Post WHERE id IN #{list}

字段生成

在执行INSERT语句前,MybatisBoost会检查待插入的POJO,如果发现其中的字段被标记了JPA的@GeneratedValue注解,则会调用相应的ValueGenerator<T>自动填充字段。

以下示例中,“id”字段使用了内置的UuidGenerator生成器生成主键:

public class Post {

    @GeneratedValue(generator = "cn.mybatisboost.generator.UuidGenerator")
    private String id;
    ...
}

目前,MybatisBoost提供了一个UuidGenerator生成器和Snowflake算法的实现,你也可以基于ValueGenerator<T>接口实现自己的字段生成器。

JSON映射

JSON映射功能可以自动地将嵌套对象序列化成JSON保存到数据库中,同样地,也可以自动地将数据库中的JSON反序列化成嵌套对象。

class Post {

    private String id;
    private Article article;
    private List<Article> articleList;
    private Map<String,Article> articleMap;
    ...
}

class Article extends JsonType {

    private String id;
    private String name;
    ...
}

在插入Project对象时,article、articleList、articleMap三个字段会自动序列化成JSON字符串。相反地,在查询Project对象时,数据库中的JSON字符串会反序列化成相应的嵌套对象。

嵌套对象必须继承于JsonType

智能方法查询

简单的SQL语句千篇一律,能否不再编写那些显而易见的SQL语句呢?答案是肯定的。

public interface PostMapper extends GenericMapper<Post> {

    @org.apache.ibatis.annotations.Mapper
    List<Post> selectByPostIdAndPostDateBw(int a, Date b, Date c);
}

以上代码片段是一个简单的方法查询,MybatisBoost会自动识别并生成对应的SQL语句。

SELECT * FROM #t WHERE PostId = ? AND PostDate BETWEEN ? AND ?

只要以Mybatis的@Mapper注解标记的方法,MybatisBoost都会智能的生成相应SQL语句,让你的双手解放于编写千篇一律的简单SQL语句。

下面我们就以“selectByPostIdAndPostDateBw”为例来分析下如何编写智能方法查询,分解后的单词如下:select By PostId And PostDate Bw。其中“select”称为“方法词”,“By”称为“辅助词”,“PostId”和“PostDate”为POJO中的属性,“And”和“Bw”(BETWEEN的缩写)为SQL关键字,其中,方法词和辅助词都是必须的,其他的为可选项。

目前支持的方法词:select、count、delete。

目前支持的关键字:

关键字 缩写 对应的SQL片段
And And AND
Or Or OR
Is Is = ?
Equals E = ?
Between Bw BETWEEN ? AND ?
NotBetween Nbw NOT BETWEEN ? AND ?
LessThan Lt < ?
LessThanEqual Lte <= ?
GreaterThan Gt > ?
GreaterThanEqual Gte >= ?
After Af > ?
Before Bf < ?
IsNull N IS
IsNotNull Nn IS NOT NULL
IsEmpty E = ''
IsNotEmpty Ne != ''
Like L LIKE ?
NotLike Nl NOT LIKE ?
OrderBy Ob ORDER BY
Not Not != ?
In In IN
NotIn Ni NOT IN ?
IsTrue T = TRUE
IsFalse F = FALSE
Asc Asc ASC
Desc Desc DESC

同时,智能查询方法还支持分页功能:

public interface PostMapper extends GenericMapper<Post> {

    @Mapper
    List<Post> selectAllOffset10Limit100();

    @Mapper
    List<Post> selectTop3();

    @Mapper
    Post selectFirst();
}

无感知分页

Mybatis本身其实已经提供了分页功能,可惜它的实现并不优雅。为此,MybatisBoost在使用方法不变的前提下,透明的修改了实现,做到了真正的物理分页

List<T> selectAll(RowBounds rowBounds); // RowBounds内含offset和limit字段

目前暂时只支持MySQL和PostgreSQL数据库,后续支持敬请期待

SQL指标与监控

默认情况下不开启SQL指标与监控功能。话不多说,直接上配置,简单易懂。

# 开启SQL指标与监控功能
mybatisboost.metric.enabled=true
# 在日志中打印SQL和执行时间
mybatisboost.showQuery=true

# 以下配置为可选配置

# 打印SQL时是否同时打印SQL参数
mybatisboost.showQueryWithParameters=boolean
# 慢SQL阈值(默认情况下,慢SQL会打印在日志中)
mybatisboost.slowQueryThresholdInMillis=long
# 慢SQL回调处理器(参数一为SQL语句,参数二为执行时间ms),可编写代码实现一些自定义逻辑,比如报警
mybatisboost.slowQueryHandler=Class<? extends BiConsumer<String, Long>>

欢迎使用

光看文档太抽象?mybatis-boost-test模块下有各种使用case,敬请参考。

MybatisBoost中没有你想要的功能?亦或是MybatisBoost有BUG?欢迎各位提出issues!

Versions

Version
2.3.2
2.3.1
2.3.0
2.2.2
2.2.1
2.2.0
2.1.3
2.1.2
2.1.1
2.1.0
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.2.1
1.2.0
1.1.10
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5