MybatisPlus

基本配置

spring boot 添加依赖

<dependency>  <groupId>com.baomidou</groupId>  <artifactId>mybatis-plus-boot-starter</artifactId>  <version>3.1.2</version></dependency>

定义mapper接口

public interface UserMapper extends BaseMapper<User> { }

继承 com.baomidou.mybatisplus.core.mapper.BaseMapper 接口后,无需编写 mapper.xml 文件,即可获得CRUD功能

定义实体类

@TableName("sys_user")public class User {    @TableId    private Long id;    @TableField("nickname")    private String name;    private Integer age;    private String email;}

MybatisPlus的注解

使用

@AutowiredUserMapper userMapper;@Testpublic void test(){    User user = new User();    user.setUsername("root");    user.setPassword("123");    user.setAge(15);    user.setCreateTime(LocalDate.now());    assertEquals(1,userMapper.insert(user));}

查询

普通查询

条件构造器查询

@Test  public void test2(){      QueryWrapper<User> queryWrapper = new QueryWrapper<>();      queryWrapper.like("username","roo")              .lt("age",50);      var list = userMapper.selectList(queryWrapper);      assertEquals(2,list.size());      assertEquals("root",list.get(0).getUsername());      assertEquals("rood",list.get(1).getUsername());  }

AbstractWrapper

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类

QueryWrapper

相比 AbstractWrapper 多了select接口

LambdaQueryWrapper

LambdaQueryWrapper<FzWarn> lqw = new LambdaQueryWrapper<FzWarn>()        .eq(FzWarn::getSspt, "10");// 等价于new QueryWrapper<FzWarn>()        .eq("sspt", "10");

好处是可以利用编译期的类型检查,避免写错字段

UpdateWrapper

相比 AbstractWrapper 多了 set 接口, 用来描述要更新哪些字段为什么值

自定义SQL

@Select("select * from mysql_data ${ew.customSqlSegment}")List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
List<MysqlData> getAll(Wrapper ew);
<select id="getAll" resultType="MysqlData">    SELECT * FROM mysql_data ${ew.customSqlSegment}</select>

注解查询

public interface UserMapper extends BaseMapper<User> {  @Select("SELECT * FROM user ")  List<User> selectAll();}

分页查询

@Beanpublic PaginationInterceptor paginationInterceptor(){    return new PaginationInterceptor();}
@Testpublic void test4(){    Page<User> page = new Page<>(1,2);    var list = userMapper.selectPage(page,null).getRecords();    assertEquals(2,list.size());  }

更新

@Testpublic void test5(){    UpdateWrapper<User> wrapper = new UpdateWrapper<User>().eq("username","root");    User user = new User();    user.setPassword("5678");    userMapper.update(user, wrapper);}

删除

UpdateWrapper<User> wrapper = new UpdateWrapper<User>()    .eq("username","root");userMapper.delete(wrapper);

AR模式

@Datapublic class User extends Model<User> {    private String username;    private String password;    private Integer age;    private LocalDate createTime;}
@Test    public void test6(){        User user = new User();        user.setUsername("20190716");        user.setPassword("123");        user.setCreateTime(LocalDate.now());        user.setAge(111);        assertTrue(user.insert());    }

主键策略

@KeySequence(value = "SEQ_ORACLE_STRING_KEY", clazz = String.class)public class YourEntity {    // 必须使用 INPUT    @TableId(value = "ID_STR", type = IdType.INPUT)    private String idStr;}/* DB2KeyGeneratorH2KeyGeneratorKingbaseKeyGeneratorOracleKeyGeneratorPostgreKeyGenerator实现 com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator 接口自定义主键策略*/@Beanpublic IKeyGenerator keyGenerator() {    return new H2KeyGenerator();}

逻辑删除

mybatis-plus:  global-config:    db-config:      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)      logic-delete-value: 1 # 逻辑已删除值(默认为 1)      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
@TableLogicprivate Integer deleted;

字段类型映射器

实现 org.apache.ibatis.type.TypeHandler 接口

@Data@Accessors(chain = true)// 使用映射器,就必须开启 autoResultMap = true@TableName(autoResultMap = true)public class User {    ...    // json    @TableField(typeHandler = JacksonTypeHandler.class)    private OtherInfo otherInfo;}
<result column="other_info" jdbcType="VARCHAR" property="otherInfo" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />

自动填充

public class User {    @TableField(.. fill = FieldFill.INSERT)    private String createTime;    @TableField(.. fill = FieldFill.UPDATE)    private String updateTime;    ....}

自定义填充处理器:

@Slf4j@Componentpublic class MyMetaObjectHandler implements MetaObjectHandler {    @Override    public void insertFill(MetaObject metaObject) {        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)        // 或者        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)        // 或者        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)    }    @Override    public void updateFill(MetaObject metaObject) {        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)        // 或者        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)        // 或者        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)    }}

填充策略:

SQL注入器

自定义方法则需要继承 com.baomidou.mybatisplus.core.injector.AbstractMethod 实现

具体可以参考 com.baomidou.mybatisplus.core.injector.DefaultSqlInjector 这个类的源代码

SQL分析打印

具体配置

数据安全

配置安全

# 加密配置 mpw: 开头紧接加密内容( 非数据库配置专用 YML 中其它配置也是可以使用的 )spring:  datasource:    url: mpw:qRhvCwF4GOqjessEB3G+a5okP+uXXr96wcucn2Pev6Bf1oEMZ1gVpPPhdDmjQqoM    password: mpw:Hzy5iliJbwDHhjLs1L0j6w==    username: mpw:Xb+EgsyuYRXw7U7sBJjBpA==

主要是通过16位随机AES密钥对原始内容进行加密:

// 生成 16 位随机 AES 密钥String randomKey = AES.generateRandomKey();// 随机密钥加密String result = AES.encrypt(data, randomKey);

指定密钥:

# Jar 启动参数( idea 设置 Program arguments , 服务器可以设置为启动环境变量 )--mpw.key=d1104d7c3b616f0b

字段加解密

@FieldEncryptprivate String email;

字段脱敏

@FieldSensitive("testStrategy")private String username;

自定义脱敏策略:

@Configurationpublic class SensitiveStrategyConfig {    /**     * 注入脱敏策略     */    @Bean    public ISensitiveStrategy sensitiveStrategy() {        // 自定义 testStrategy 类型脱敏处理        return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");    }}

跳过脱敏处理:

RequestDataTransfer.skipSensitive();

插件

Mybatis 要自定义插件需要实现 org.apache.ibatis.plugin.Interceptor

而MybatisPlus 在较新的版本中,使用自己的接口:com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor 这个接口的扩展点更加齐全

MP自带的一些插件: