目录
1.在springboot项目中添加mybatis-plus依赖
简介:
mybatis-plus是一个mybatis的增强工具,只是在mybatis的基础上只做了增强,不做改变,为简化开发而生,提高效率而生.
特性:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
springboot整合mybatis-plus
1.在springboot项目中添加mybatis-plus依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!-- 数据库链接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
<scope>runtime</scope>
</dependency>
如果只是用mybatis-plus 只添加这两个个依赖就可以了 如果需要使用代码生成工具,还需要添加下面的依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<!-- mybatis-plus-generator使用的默认的模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.0-alpha5</version>
<scope>test</scope>
</dependency>
<!-- 下面的依赖非必须 如果生成代码时需要开启lombok与swagger支持 那么导入一下依赖 否则注解会报错 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
2.配置mybatis-plus参数
配置文件application.properties中添加如下配置(未配置连接池信息)
## 数据源配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/blogs?characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
## mybatis-plus 配置
# 控制台打印sql
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# mapper.xml路径
mybatis-plus.mapper-locations=classpath:mapper/*.xml
# 实体类路径
mybatis-plus.type-aliases-package=com.monster.blog.pojo
3.启动类修改
@SpringBootApplication
@MapperScan("com.monster.blog.mapper")
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
在启动类上添加 @MapperScan注解 指向mapper接口的包
代码层面:
1.Mapper接口需要继承BaseMapper<T>
public interface SystemInfoMapper extends BaseMapper<SystemInfo> {}
2.service继承IService<T>
public interface CommentsService extends IService<Comments> {}
3.serviceImpl除了实现service,还需要继承ServiceImpl<TMapper, T>
@Service
public class CommentsServiceImpl extends ServiceImpl<CommentsMapper, Comments> implements CommentsService {}
完成以上的内容,基本上就可以欢快的使用mybatis-plus操作数据库了
关于mybatis-plus插件与特性
1. 主键自动生成
一般在实体类的主键字段上配置的注解是@TableId来标识这个字段是主键字段,value对应数据库字段名,type则表示主键生成的策略,它包含以下策略:
// 数据库ID自增 这里需要注意的是数据库的该字段必须是自增的 否则会报错
// 如果手动设置ID 是没有用的 还是会走数据库的自增
IdType.AUTO
// 该类型为未设置主键类型,
// 如果没有设置id 但是数据库设置了自增 则按照数据库自增
// 如果没有设置ID 数据库也没有设置自增 则随机产生了一个全局唯一id
// 如果设置了id 则按照设置的值插入
IdType.NONE
// 用户输入ID
// 如果数据库未设置自增,且不输入ID 则会报错
// 如果数据库设置了自增,不输入ID则走数据库自增
// 数据库设置了自增,且手动输入了ID 则插入自己设置的ID
// 该类型可以通过自己注册自动填充插件进行填充
IdType.INPUT
// 分配ID (主键类型为number或string)
// 自己设置了id 则不再生成雪花ID
// 自己未设置ID 生成全局唯一ID
// 默认实现是雪花算法
IdType.ASSIGN_ID
// 分配UUID (主键类型为 string)
// uuid替换了-
// 自己设置了id 则不再生ID(uuid)
// 自己未设置ID 生成全局唯一ID(uuid)
IdType.ASSIGN_UUID
// 弃用 被IdType.ASSIGN_ID替换
IdType.ID_WORKER
// 弃用 被IdType.ASSIGN_ID替换
IdType.ID_WORKER_STR
// 弃用 被IdType.ASSIGN_UUID替换
IdType.UUID
2.支持 ActiveRecord 模式
这个模式需要实体类继承Model即可
实体: extend Model 这个Moldel是mybatis包下的,别导错包
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="Comments对象", description="")
public class Comments extends Model implements Serializable {
@ApiModelProperty(value = "主键ID")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
@ApiModelProperty(value = "评论时间")
private Date writedate;
}
使用:
@Test
public void addTest() {
Comments comments = new Comments();
comments.setWritedate(new Date());
// 直接用对象进行插入
comments.insert();
}
Model中继承的部分方法截图
对象只要继承了Model,这些方法都可以直接用对象来实现
3.代码生成器.
4.内置分页插件
mybati-plus内置了分页插件,使用也很简单,只需要注册分页插件即可使用 (只能注册一个 否则会给你拼接2个limit到sql里面)
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisConfig {
//注册Mybatis-Plus分页插件
// 旧版
// @Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
// 新版
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 注意数据库的类型 这里使用的mysql
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
使用
1.mybatis-plus封装好的分页查询
@Test
public void addTest() {
// 构建分页参数对象
// 1.表示第一页 10表示查10调数据
Page<Comments> page = new Page<>(1, 10);
// 构建查询条件对象
QueryWrapper<Comments> wrapper = new QueryWrapper();
wrapper.eq("id","10");
commentsMapper.selectPage(page, wrapper);
// 如果没有查询条件 这里的wrapper可以传null
commentsMapper.selectPage(page, null);
}
2.在实际的开发过程中,我们自定义的sql比较多 所以大部分的情况下,我们都是需要在我们自己写的sql中添加分页,mybatis-plus也是支持的
2.1首先我们在mappe中添加一个接口,接口中的参数,需要添加一个分页对象page
public interface CommentsMapper extends BaseMapper<Comments> {
/**
*
* @param page 分页对象
* @param o 查询参数对象
* @return 返回值可以是list,也可以直接是个page
*/
List<Comments> selectAllComments(Page<Comments> page, Object o);
}
2.2在xml中添加这个查询的方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.monster.blog.mapper.CommentsMapper">
<select id="selectAllComments" resultType="com.monster.blog.pojo.Comments">
select * from comments
</select>
</mapper>
测试:
@Test
public void addTest() {
// 1.表示第一页 10表示查10调数据
Page<Comments> page = new Page<>(1, 10);
//我们自己写的sql也可以添加分页,只需要向上面的selectPage一样 传入一个分页参数page
commentsMapper.selectAllComments(page, null);
}
查询结果:
5. 内置性能分析插件
注册性能分析插件 IllegalSQLInnerInterceptor
@Configuration
public class MybatisConfig {
// mybatis-plus插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件 注意数据库的类型 这里使用的mysql
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// sql 性能规范插件
interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());
return interceptor;
}
}
关于性能分析插件的描述,在源码中的描述如下
个人觉得要加这玩意就要在项目刚开始的时候加,做了一半或者完成了才加会让你想死
比如:mybatis-plus自带的分页查询 如果最后生成的sql查询没带where条件就会报错
@Test
public void addTest() {
// 1.表示第一页 10表示查10调数据
Page<Comments> page = new Page<>(1, 10);
// 构建查询条件对象
QueryWrapper<Comments> wrapper = new QueryWrapper();
wrapper.eq("id","10");
//commentsMapper.selectPage(page, wrapper);
// 如果没有查询条件 这里的wrapper可以传null
commentsMapper.selectPage(page, null);
//我们自己写的sql也可以添加分页,只需要向上面的selectPage一样 传入一个分页参数page
//commentsMapper.selectAllComments(page, null);
}
上面mybatis-plus自带的selectPage 没有条件的时候生成的sql是没有where条件的 这时候执行先查询就会报一个非法sql的错误
3.2.0版本以后去掉了PerformanceInterceptor 之前的性能分析插件可以设置最大执行时间,通过设置这个时间我们能筛选出执行效率极差的sql 但是在3.2.0以后去掉了这个插件
6.自动填充
阿里巴巴开发手册: 所有的数据库表,gmt_create,gmt_modified都要配上 而且需要自动化
方式一就是设置数据库字段默认值为当前时间 且为自动更新
创建时间设置默认值为CURRENT_TIMESTAMP 系统当前时间
更新时间也设置为系统当前时间,并且勾选自动更新
方式二 代码级别的
首先不需要设置数据库的自动更新与默认时间
实体类需要添加注解
编写一个处理器来处理这个注解
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入操作处理
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
// 更新操作处理
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
7.乐观锁
首先在实体类中 锁字段加上注解
然后注册乐观锁组件
@Configuration
public class MybatisConfig {
// mybatis-plus插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件 注意数据库的类型 这里使用的mysql
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// sql 性能规范插件
interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
这里更新历史数据,如果version是后面才加的字段,已有的历史数据如果该字段为null 更新的时候不会添加varsion条件
8.逻辑删除
实体类中逻辑删除字段添加注解@TableLogic
application.properties 添加逻辑删除的配置项
# 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
mybatis-plus.global-config.db-config.logic-delete-field=deleted
# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
上面的配置中 如果未删除是0 已删除是1 则可只配置逻辑删除的字段名称即可
官网给的配置就是上面的配置 但是在3.4.0版本中 我并没有在application.properties中添加上面的配置,实际删除的时候 依然会走逻辑删除 大胆猜测一下,估计只要实体类配置了tablelogic注解就会生效把