Mybatisplus
导入依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--lombok用来简化实体类--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>
**注意:**引入 MyBatis-Plus
之后请不要再次引入 MyBatis
以及 MyBatis-Spring
,以避免因版本差异导致的问题。
配置文件变化
在 application.properties
配置文件中添加 MySQL 数据库的相关配置:
mysql5
#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus
mysql8以上(spring boot 2.1)
**注意:**driver和url的变化
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
注意:
1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为Spring Boot 2.1 集成了 8.0版本的jdbc驱动,这个版本的 jdbc 驱动需要添加这个后缀,否则运行测试用例报告如下错误:
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more
2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,之前的 com.mysql.jdbc.Driver 已经被废弃,否则运行测试用例的时候会有 WARN 信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K5986CNT-1611036596455)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118190725238.png)]
使用说明
1.导入依赖
2.编写数据库连接配置
3.编写mapper继承BaseMapper并添加@Repository让spring容器识别
4.主启动类进行扫描@MapperScan(“com.atguigu.mpdemo1010.mapper”)
主键策略
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dUyIgHO6-1611036596458)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118191602545.png)]
1. 数据库自增长序列或字段
2. UUID
3. UUID的变种
4. Redis生成ID
当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
可以使用Redis集群来获取更高的吞吐量。假如一个集群中有5台Redis。可以初始化每台Redis的值分别是1,2,3,4,5,然后步长都是5。各个Redis生成的ID为:
A:1,6,11,16,21
B:2,7,12,17,22
C:3,8,13,18,23
D:4,9,14,19,24
E:5,10,15,20,25
5. Twitter的snowflake算法(雪花算法)
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
6. 利用zookeeper生成唯一ID
主键是数字 VS 字符串
@TableId(type = IdType.ID_WORKER) //mp自带策略,生成19位值,数字类型使用这种策略,比如long
//@TableId(type = IdType.ID_WORKER_STR) //mp自带策略,生成19位值,字符串类型使用这种策略
时间自动填充
第一步
实体类中进行注解的添加
//create_time
@TableField(fill = FieldFill.INSERT)
private Date createTime;//update_time
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
第二步
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBk013TR-1611036596461)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118200532206.png)]
创建类,实现接口MetaObjectHandler,实现接口里面的方法
package com.atguigu.mpdemo1010.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class MyMetaObjectHandler implements MetaObjectHandler {//使用mp实现添加操作,这个方法执行@Overridepublic void insertFill(MetaObject metaObject) {this.setFieldValByName("createTime",new Date(),metaObject);this.setFieldValByName("updateTime",new Date(),metaObject);this.setFieldValByName("version",1,metaObject);}//使用mp实现修改操作,这个方法执行@Overridepublic void updateFill(MetaObject metaObject) {this.setFieldValByName("updateTime",new Date(),metaObject);}
}
数据库中的字段VS实体类
数据库中: create_time
实体类中: creanteTime
乐观锁
version自动填充和时间一样或者在数据库中设置默认值
第一步
@Version
private Integer version;//版本号
第二步
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crGLmfQE-1611036596466)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118212859965.png)]
自定义一个配置类在里面添加乐观锁插件
//乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {return new OptimisticLockerInterceptor();
}
并且把mapperscan从启动类弄到配置类
注意:乐观锁必须先查再改,否则乐观锁无效
分页
第一步
配置分页插件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0ZReWsf-1611036596469)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118214406225.png)]
/*** 分页插件*/
@Bean
public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();
}
编写代码
@Test
public void testPage() {//1 创建page对象//传入两个参数:当前页 和 每页显示记录数Page<User> page = new Page<>(1,3);//调用mp分页查询的方法//调用mp分页查询过程中,底层封装//把分页所有数据封装到page对象里面userMapper.selectPage(page,null);//通过page对象获取分页数据System.out.println(page.getCurrent());//当前页System.out.println(page.getRecords());//每页数据list集合System.out.println(page.getSize());//每页显示记录数System.out.println(page.getTotal()); //总记录数System.out.println(page.getPages()); //总页数System.out.println(page.hasNext()); //下一页System.out.println(page.hasPrevious()); //上一页}
逻辑删除
第一步
@TableLogic
private Integer deleted;
第二步
application.properties中进行配置(1为删除状态,0为不删除状态)(默认的配置不用修改)
在配置类中配置插件和上面一样
//逻辑删除插件
@Bean
public ISqlInjector sqlInjector() {return new LogicSqlInjector();
}
注意:
添加了逻辑删除后查询等操作会自动拼接deleted=0进行拼接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oO2CCa4-1611036596470)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118215717249.png)]
性能分析插件
查找慢SQL
第一步
配置类进行配置,同上
/*** SQL 执行性能分析插件* 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长** 三种环境* * dev:开发环境* * test:测试环境* * prod:生产环境*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行performanceInterceptor.setFormat(true);return performanceInterceptor;
}
第二步
application.properties中进行配置
#环境设置:dev、test、prod
spring.profiles.active=dev
条件查询Wrapper
一般用querywrapper(功能比较强大)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6CmwEtTX-1611036596471)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118220450433.png)]
public void testSelectQuery() {//创建QueryWrapper对象QueryWrapper<User> wrapper = new QueryWrapper<>();//通过QueryWrapper设置条件//ge、gt、le、lt//查询age>=30记录//第一个参数字段名称,第二个参数设置值
// wrapper.ge("age",30);//eq、ne//wrapper.eq("name","lilei");//wrapper.ne("name","lilei");//between//查询年龄 20-30// wrapper.between("age",20,30);//like//wrapper.like("name","岳");//orderByDesc// wrapper.orderByDesc("id");//last,在最后拼上//wrapper.last("limit 1");//指定要查询的列wrapper.select("id","name");List<User> users = userMapper.selectList(wrapper);System.out.println(users);}