springboot整合mybatis-plus
- 导入依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
lombok插件可简化javabean书写
2.配置数据库数据源和后面使用到的相关配置
spring.datasource.username=root
spring.datasource.password=18756232770lmh
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#mp中逻辑删除状态默认设置
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
#springboot环境
spring.profiles.active=dev
3.编写实体类
package com.lmh.mpdemp.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
@TableName("mybatis1")//对应数据表名
public class User {
//@TableId(type = IdType.ID_WORKER)生成19位值数字类型:Long
//@TableId(type = IdType.ID_WORKER_STR)生成19位字符类型
@TableId(type = IdType.ID_WORKER)//主键增长策略
private Long id;
private String name;
private Integer age;
private String email;
//自动填充
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
//乐观锁
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
//逻辑删除控制字段
//默认0为可查,1为以被逻辑删除
@TableLogic
@TableField(fill = FieldFill.INSERT)//也可以在数据库控制默认值为0
private Integer deleted;
}
其中@Data是lombok注解简化javabean书写,要使用该方法,需先下载插件,在setting里的plugins里下载,并导入依赖
4.主键增长的使用
@TableId
@TableId(type = IdType.ID_WORKER)生成19位值数字类型:Long
@TableId(type = IdType.ID_WORKER_STR)生成19位字符类型
不写默认为ID_WORKER
还有UUID:生成唯一ID的
AUTO:主键自动增长+1
5.编写Mapper并在主配置类上写上@MapperScan(要扫描的包路径)
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.lmh.mpdemp.domain.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserMapper extends BaseMapper<User> {
}
泛型写要mp操作的javabean数据类型,BaseMapper里面封装了很多方法
6.功能拓展(createTime,updateTime)自动填充
编写自动填充处理器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实现添加操作,执行该方法
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
this.setFieldValByName("version",1,metaObject);
this.setFieldValByName("deleted",0,metaObject);
}
//使用mp实现修改操作,执行该方法
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
要使用@Component把处理器加入spring管理
使用步骤:
在需要自动填充的数据上加上@TableField(fill =
FieldFill.INSERT)
其中FieldFill后有很多场景:
INSERT:当mp插入该数据时方法调用
INSERT_UPDATE:当mp插入和修改时该方法执行
7.乐观锁
在数据库表加一个version字段,该字段记录版本,修改一次版本字段增加一次,是的多个同时操作该条记录是只能有一个成功的,其原理是:在修改前,先查询,看版本对不对应,不对应则无法修改成功
步骤:
1.写配置类加入乐观锁插件
@MapperScan("com.lmh.mpdemp.mapper")
@Configuration
public class MyConfig {
/**
* 乐观锁插件
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
2.实体类上属性上标记@Version
//乐观锁
@Version
@TableField(fill = FieldFill.INSERT)
private Integer version;
8.分页查询
添加分页插件
/**
* 分页查询插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
测试:
//分页查询
@Test
public void testFindByPage(){
//创建page对象
//传入两个参数,current:当前页 size:每页显示记录数
Page<User> page=new Page<>(1,1);
//调用mp分页查询的方法
//把分页所有数据封装page对象里面
userMapper.selectPage(page, null);
System.out.println("total"+page.getTotal());//总记录数
System.out.println(page.getRecords());//每页数据集合
System.out.println("pages"+page.getPages());//总页数
System.out.println(page.hasNext());//是否有下一页
System.out.println(page.hasPrevious());//是否有上一页
}
9.逻辑删除
原理:删除的该条数据,在数据库中并没有删除,但查询时是不可查询的,在表中添加一个字段deleted表示状态,默认0为正常,1为已删除,也可以在application.properties里修改
#mp中逻辑删除状态默认设置
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
步骤:1.添加逻辑删除插件
/**
* 逻辑删除插件
* @return
*/
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
2.在实体类对应属性上添加@TableLogic
3.测试
//逻辑删除,意思是查询时不显示结果,但在数据可中有该条数据,依靠一个字段控制状态
@Test
public void delete2(){
userMapper.deleteById(1291035330752847873l);
//userMapper.selectById(1291035330752847873l);测试结果是Total:0,没有查询到该条数据
//该条数据的deleted字段变成1了
}
10.sql执行性能分析
步骤1.在配置类中添加插件
/**
* SQL执行性能分析
* 开发测试环境使用,线上不推荐
* dev:开发环境
* test:测试环境
* prod:生产环境
* @return
*/
@Bean
@Profile({"dev","test"})//设置dev test 环境开启
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor=new PerformanceInterceptor();
performanceInterceptor.setMaxTime(200);//毫秒,超过此处设置得时间这sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
2.application.properties里配置环境
#springboot环境
spring.profiles.active=dev
3.执行sql控制台有如下日志
Time:11 ms - ID:com.lmh.mpdemp.mapper.UserMapper.selectPage
Execute SQL:
SELECT
id,
name,
age,
email,
create_time,
update_time,
version,
deleted
FROM
mybatis1
WHERE
deleted=0 LIMIT 0,1
其中time:11ms,没有超过插件设置的performanceInterceptor.setMaxTime(200);//毫秒,超过此处设置的时间这sql不执行
11.负责的条件查询
@Test
public void testFind(){
//创建QueryWrapper对象
QueryWrapper<User> wrapper=new QueryWrapper<>();
//通过QueryWrapper设置条件
//ge,gt,le,lt(>= > <= <)
wrapper.ge("age",10);
//eq,ne(== !=)
wrapper.eq("name","李四3");
//between [val1,val2]
wrapper.between("age",20,30);
//like(模糊查询)
wrapper.like("name","李");
//orderDesc(排序,降序)/升序orderAsc
wrapper.orderByDesc("id");//根据id降序排列
//last
wrapper.last("limit 1");//向sql语句最后拼接以个语句
//查询指定列
wrapper.select("id","name","age");//查询结果只可以看见指定列数据
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
总体测试
package com.lmh.mpdemp;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lmh.mpdemp.domain.User;
import com.lmh.mpdemp.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SpringBootTest
class MpdempApplicationTests {
@Autowired
private UserMapper userMapper;
//查询所有
@Test
void contextLoads() {
List<User> users = userMapper.selectList(null);
System.out.println(users);
//[User(id=1, name=张三, age=12, email=15689hdsj, createTime=Wed Aug 05 22:13:40 CST 2020, updateTime=Wed Aug 05 22:13:47 CST 2020)]
}
//插入保存
@Test
public void testSave(){
User user=new User();
user.setAge(18);
user.setName("李四5");
user.setEmail("16656dshgd");
int insert = userMapper.insert(user);
System.out.println("insert"+insert);
}
//修改操作
@Test
public void testUpdate(){
User user=new User();
user.setId(1291023312687763457l);
user.setAge(18);
int i = userMapper.updateById(user);
System.out.println("update"+i);
}
//乐观锁下的修改操作
@Test
public void testUpdate1(){
//先查询,版本对应才能修改
User user = userMapper.selectById(1291026957873459201l);
user.setAge(20);
userMapper.updateById(user);
//修改成功,version加1,前提是要在属性上加@Version注解,并配置乐观锁插件
}
//多个ID的批量查询
@Test
public void testFindByIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1291026957873459201l, 1291023312687763457l, 1l));
for (User user : users) {
System.out.println(user);
}
}
//分页查询
@Test
public void testFindByPage(){
//创建page对象
//传入两个参数,current:当前页 size:每页显示记录数
Page<User> page=new Page<>(1,1);
//调用mp分页查询的方法
//把分页所有数据封装page对象里面
userMapper.selectPage(page, null);
System.out.println("total"+page.getTotal());//总记录数
System.out.println(page.getRecords());//每页数据集合
System.out.println("pages"+page.getPages());//总页数
System.out.println(page.hasNext());//是否有下一页
System.out.println(page.hasPrevious());//是否有上一页
}
//物理删除
@Test
public void delete(){
userMapper.deleteById(1l);
}
//多个ID批量删除
@Test
public void delete1(){
userMapper.deleteBatchIds(Arrays.asList(1291026957873459201l,1291023312687763457l));
}
//逻辑删除,意思是查询时不显示结果,但在数据可中有该条数据,依靠一个字段控制状态
@Test
public void delete2(){
userMapper.deleteById(1291035330752847873l);
//userMapper.selectById(1291035330752847873l);测试结果是Total:0,没有查询到该条数据
//该条数据的deleted字段变成1了
}
//复杂条件查询
@Test
public void testFind(){
//创建QueryWrapper对象
QueryWrapper<User> wrapper=new QueryWrapper<>();
//通过QueryWrapper设置条件
//ge,gt,le,lt(>= > <= <)
wrapper.ge("age",10);
//eq,ne(== !=)
wrapper.eq("name","李四3");
//between [val1,val2]
wrapper.between("age",20,30);
//like(模糊查询)
wrapper.like("name","李");
//orderDesc(排序,降序)/升序orderAsc
wrapper.orderByDesc("id");//根据id降序排列
//last
wrapper.last("limit 1");//向sql语句最后拼接以个语句
//查询指定列
wrapper.select("id","name","age");//查询结果只可以看见指定列数据
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
}
}