mybatis
目录mp 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大4部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击
mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
使用
1. insert
1.1 insert后的id自动回填
1.2 主键策略(@TableId(type = IdType.AUTO))等
2. update
2.1 根据Id更新操作
注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?
User user = new User();
user.setId(1L);
user.setAge(28);
int result = userMapper.updateById(user);
2.2 自动填充
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:
@TableField(fill = FieldFill.INSERT)
@TableField(fill = FieldFill.INSERT_UPDATE)
前提是实现元对象处理器接口 MetaObjectHandler
2.3 乐观锁
主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
丢失更新问题,只有一个人能更新成功,其他人更新失败。
需要安装乐观锁插件
public class MybatisPlusConfig {
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
3. select
3.1 selectById
3.2 selectBatchIds(Arrays.asList(1, 2, 3))
3.3 selectByMap(map) map中的key对应的是数据库中的列名。例如数据库user_id,实体类是userId,这时map的key需要填写user_id
3.4 分页
- 配置分页插件
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
4. delete
4.1 deleteById
4.2 deleteBatchIds(Arrays.asList(8, 9, 10))
4.3 deleteByMap(map)
4.4 逻辑删除
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
// 设置默认值
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("deleted", 0, metaObject);
}
// 逻辑删除插件
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断
5. 性能分析插件
输出每条 SQL 语句及其执行时间
/**
* SQL 执行性能分析插件
* 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
// 环境设置:dev、test、prod
spring.profiles.active=dev
5. 条件构造器
适用于复杂条件查询
1、ge、gt、le、lt、isNull、isNotNull
2、eq、ne
3、between、notBetween
4、allEq
5、like、notLike、likeLeft、likeRight
6、in、notIn、inSql、notinSql、exists、notExists
queryWrapper.inSql("id", "select id from user where id < 3");
7、or、and
嵌套or、嵌套and
queryWrapper..or(i -> i.eq("name", "李白").ne("age", 20))
.or().between("age", 20, 30);
最终结果 OR ( name = ? AND age <> ? )
8、orderBy、orderByDesc、orderByAsc
queryWrapper.orderByDesc("id");
9、last
直接拼接到 sql 的最后
10、==指定要查询的列==
queryWrapper.select("id", "name");
11、set、setSql
update使用
lombok注解
Lombok 的目的是减少代码的重复编写,并提供比较好的解决方案。
@EqualsAndHashCode
该注解使用在类上,该注解在类级别注释会同时生成 equals 和 hashCode。
存在继承关系需要设置 callSuper 参数为 true
@Data
结合了 @ToString,@EqualsAndHashCode, @Getter 和 @Setter。虽然方便,但是没有与其他注解相同的控制粒度
@RequiredArgsConstructor
该注解使用在类上,使用类中所有带有 @NonNull 注解的或者带有 final 修饰的成员变量生成对应的构造方法
@Value
这个注解用在 类 上,会生成含所有参数的构造方法,get 方法,此外还提供了 equals、hashCode、toString 方法。
@Synchronized
一般情况下建议锁定一个专门用于此目的的独立锁,而不是允许公共对象进行锁定。该注解也是为了达到该目的。