MyBatisPlus
自动填充
@TableField(fill = FieldFill.INSERT) 插入的时候填充
@TableField(fill = FieldFill.INSERT_UPDATE)插入和更新的时候填充
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
public class User {
//@TableId(type = IdType.ID_WORKER) //mp自带策略,生成19位值,数字类型使用这种策略,比如long
//@TableId(type = IdType.ID_WORKER_STR) //mp自带策略,生成19位值,字符串类型使用这种策略
private Long id;
private String name;
private Integer age;
private String email;
//create_time
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//update_time
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;//版本号
@TableLogic
private Integer deleted;
}
通过实现MetaObjectHandler实现insertFill和updateFill方法来实现自动填充
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实现添加操作,这个方法执行
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
this.setFieldValByName("version",1,metaObject);
}
//使用mp实现修改操作,这个方法执行
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
import com.soyoungboyy.mpdemo1010.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User> {
}
测试方法:
//添加操作
@Test
public void addUser() {
User user = new User();
user.setName("岳不群1");
user.setAge(70);
user.setEmail("lucy@qq.com");
// user.setCreateTime(new Date());
// user.setUpdateTime(new Date());
int insert = userMapper.insert(user);
System.out.println("insert:"+insert);
}
//修改操作
@Test
public void updateUser() {
User user = new User();
user.setId(1231103936770154497L);
user.setAge(120);
int row = userMapper.updateById(user);
System.out.println(row);
}
乐观锁
丢失更新:两个事务,后一个提交的事务操作覆盖了上一个事务操作。
悲观锁:独占,串行。
乐观锁:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
乐观锁的具体实现:
(1)数据库中添加version字段
ALTER TABLE `user` ADD COLUMN `version` INT
(2)实体类添加version字段
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
(3)元对象处理器接口添加version的insert默认值
@Override
public void insertFill(MetaObject metaObject) {
......
this.setFieldValByName("version", 1, metaObject);
}
说明:
支持的数据类型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime整数类型下 newVersion = oldVersion + 1``newVersion
会回写到 entity
中仅支持 updateById(id)
与 update(entity, wrapper)
方法在 update(entity, wrapper)
方法下, wrapper
不能复用!!!
配置类:
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@Configuration
@MapperScan("com.soyoungboyy.mybatis_plus.mapper")
public class MpConfig{
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
测试类:
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement
@Configuration
@MapperScan("com.soyoungboyy.mybatis_plus.mapper")
public class MpConfig{
/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
分页
分页插件:
@Configuration
@MapperScan({"com.atguigu.mpdemo1010.mapper"})
public class MpConfig {
public MpConfig() {
}
@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()); //上一页
}
通过多个id批量查询
完成了动态sql的foreach的功能
@Test
public void testSelectBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
简单的条件查询
通过map封装查询条件
@Test
public void testSelectByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
逻辑删除
- 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
- 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
ALTER TABLE `user` ADD COLUMN `deleted` boolean
实体类添加deleted 字段
并加上 @TableLogic 注解 和 @TableField(fill = FieldFill.INSERT) 注解
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
在MpConfig中配置逻辑删除插件
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
添加的时候输入未删除默认值
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
...
this.setFieldValByName("deleted", 0, metaObject);
}
}
application.properties 加入配置
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
性能分析
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
SQL 性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题
1、配置插件
(1)参数说明
参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
参数:format: SQL是否格式化,默认false。
(2)在 MpConfig中配置
/**
* 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;
}
Spring Boot 中设置dev环境
#环境设置:dev、test、prod
spring.profiles.active=dev
可以针对各环境新建不同的配置文件application-dev.properties
、application-test.properties
、application-prod.properties
也可以自定义环境名称:如test1、test2
执行如下代码的性能信息:
//逻辑删除
@Test
public void testDeleteById2(){
int result = userMapper.deleteById(1264167376490725378L);
System.out.println(result);
}
实现复杂的查询操作
//mp实现复杂查询操作
@Test
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);
}