MyBatis-Plus
2021-04-22 20:29:17 36 举报
AI智能生成
MyBatis-Plus的基本入门使用,还有几个插件的使用示例
作者其他创作
大纲/内容
官网
https://mp.baomidou.com/
快速入门
https://mp.baomidou.com/guide/
本质
就是mybatis的升级,只是在mybatis的基础上做了提升,支持完全的向下兼容
这个图可以很好的解释
开始入门Demo
导入依赖
<!--mybatis-plus依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
只导入这一个依赖,不要再导入mybatis了,避免版本冲突
连接数据库
导入mysql依赖
<!--mysql连接依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
配置application.properties
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username=root # 时区配置,mysql8必须配置
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # 这是mysql8的版本驱动,完全支持向下兼容
编写pojo类
package com.xiaoye.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* @author 小也
* @create 2021/4/22 13:53
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysUser {
private Long id;
private String username;
private String password;
private String nickname;
private Long gender;
private Long age;
private Long clazzId;
private Long isDelete;
private Long version;
private LocalDateTime bjtCreate;
private LocalDateTime bjtModified;
}
编写mapper接口
package com.xiaoye.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaoye.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
/**
* @author 小也
* @create 2021/4/22 13:56
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
//只要集成了BaseMapper这个父类就可以直接使用很多的单表操作了
}
BaseMapper
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
public interface BaseMapper<T> {
int insert(T var1);
int deleteById(Serializable var1);
int deleteByMap(@Param("cm") Map<String, Object> var1);
int delete(@Param("ew") Wrapper<T> var1);
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> var1);
int updateById(@Param("et") T var1);
int update(@Param("et") T var1, @Param("ew") Wrapper<T> var2);
T selectById(Serializable var1);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> var1);
List<T> selectByMap(@Param("cm") Map<String, Object> var1);
T selectOne(@Param("ew") Wrapper<T> var1);
Integer selectCount(@Param("ew") Wrapper<T> var1);
List<T> selectList(@Param("ew") Wrapper<T> var1);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> var1);
List<Object> selectObjs(@Param("ew") Wrapper<T> var1);
IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
}
在主启动类上扫描mapper接口
package com.xiaoye;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 22944
*/
@SpringBootApplication
@MapperScan("com.xiaoye.mapper")
public class Springboot04MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot04MybatisPlusApplication.class, args);
}
}
开启mybatis-plus的日志
配置application.properties配置文件
# 开启日志输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
测试一波
测试代码
package com.xiaoye;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaoye.entity.SysUser;
import com.xiaoye.mapper.SysUserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class Springboot04MybatisPlusApplicationTests {
@Autowired
private SysUserMapper sysUserMapper;
@Test
void contextLoads() {
QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
wrapper.eq("id",1).like("nickname","ye").le("age",30).ge("gender","1");
List<SysUser> users = sysUserMapper.selectList(wrapper);
for (SysUser user : users) {
System.out.println(user.toString());
}
}
}
QueryWrapper
QueryWrapper是mybatis-plus自带的条件查询器,我们可以使用这个QueryWrapper来构造查询条件
eq("数据库列名","值")
要求某行的该列值和传入的值完全相等才能查出来
like("数据库列名","值")
要求某行的该列值包含传入的值才能查出来
le("数据库列名","值")
要求某行的该列值小于等于传入的值才能查出来
ge("数据库列名","值")
要求某行的该列值大于等于传入的值才能查出来
测试结果
mybatis-plus会帮我们自动生成简单的sql并拼接,对于单表操作可以说很友好了,但是对于多表联查还是需要自己手动写的
主键自增
数据库明明设置了主键自增,为什么添加数据的时候却给了一串很长的随机数呢?
其实这是mybatis-plus帮我们生成的主键id,采用的是twitter的雪花算法,用毫秒数、机器编号等参数形成的唯一id
我们想要变成我们想要的1,2,3,4,5这种简单的自增也很简单,添加一个注解就好了
乐观锁
简介
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
实际操作一下
实体类中需要在相对应得字段上添加@Version注解
编写配置类(来自官网)
// Spring Boot 方式
@Configuration
@MapperScan("按需修改")
public class MybatisPlusConfig {
/**
* 旧版
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 新版
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
测试乐观锁
普通情况下(单线程操作)
@Test
void OptimisticLockTest(){
//1、查询用户,拿到版本号
SysUser user = sysUserMapper.selectById(1);
//2、执行更新操作
user.setAge(18);
sysUserMapper.updateById(user);
}
结果
多线程情况下
@Test
void OptimisticLockTest(){
//线程A
SysUser user1 = sysUserMapper.selectById(1);
user1.setAge(18);
//线程B执行
SysUser user2 = sysUserMapper.selectById(1);
user2.setAge(30);
sysUserMapper.updateById(user2);
//线程A继续执行更新操作
sysUserMapper.updateById(user1);
}
结果
时间戳
阿里巴巴Java开发手册上明确表示了数据库建表的时候必须要有创建时间(gmt_create)、修改时间(gmt_modified)字段
我们来实际使用一下
数据库建表加上这两个字段,并且类型设置timestamp
创建时间
默认时现在操作的时间,并且不再更新
修改时间
默认是现在的操作时间,并且会因为数据更新而更新时间戳
上面的操作在数据库中操作以及完全可以玩的来了,但是实际开发我却发现更新不生效
所以我查了很多资料,发现解决方式有两种,一种是加注解,一种是加注解和配置类
既然一个注解可以解决的事情,我为什么还要加配置类呢?完事收工
分页查询
我们首先想到的应该是学过的limit关键字,在数据库层面实现分页查询
现在我们使用mybatis-plus自带的分页插件来实现分页查询
简单的Page实现
代码
@Test
void limitPageTest(){
Page<SysUser> page = new Page<>(2,1);
sysUserMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
}
效果
一共三条记录,现在显示页面大小为1,第二页的记录
逻辑删除
之前写逻辑删除的时候每次写sql都要手动拼接is_delete = 0,现在mybatis-plus帮我们封装好了
逻辑删除字段添加注解
@TableLogic
private Integer isDelete;
配置拦截器
package com.xiaoye.config;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.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;
/**
* @author 小也
* @create 2021/4/22 16:40
*/
@MapperScan("com.xiaoye.mapper")
@Configuration
public class MybatisPlusConfig {
/**
* 乐观锁
* @return
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){
return new OptimisticLockerInterceptor();
}
/**
* 分页组件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor(){return new PaginationInterceptor();}
/**
* 逻辑删除
* @return
*/
@Bean
public ISqlInjector iSqlInjector(){return new LogicSqlInjector();}
}
application.properties配置文件里配置逻辑删除的代号
# 开启日志输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#逻辑删除,未删除是0,已删除是1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-value=1
开始测试
测试代码
@Test
void logicDeleteTest(){
sysUserMapper.deleteById(1);
}
测试结果
先执行删除操作
再次查询发现已经查不到了
我们可以通过navicat看到实际上只是更改了is_delete的值,并没有真的删除
性能分析插件
性能分析插件就是记录每条sql执行的时间,超时就会停止运行
导入插件,注册组件
@Bean
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//这里是毫秒数,设置sql执行的最大时间,超时就停止
performanceInterceptor.setMaxTime(100);
//开启sql格式化
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
开始测试
这个很常用,可以有效找到慢查询
自动代码生成
AutoGenerator类
可能报错
导入依赖即可
<!--模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
源码
package com.xiaoye.util;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
/**
* @author 小也
* @create 2021/4/22 19:37
*/
public class AutoCoding {
private static final String DATA_SOURCE_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DATA_SOURCE_URL = "jdbc:mysql://localhost:3306/sbs?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
private static final String DATA_SOURCE_USERNAME = "root";
private static final String DATA_SOURCE_PASSWORD = "root";
private static final String MODULE_NAME = "sys";
private static final String MODULE_PARENT_NAME = "com.xiaoye";
private static final String TABLE_NAME = "sys_user";
private static final String LOGIC_DELETE_NAME = "is_delete";
private static final String GMT_CREATE = "bjt_create";
private static final String GMT_MODIFIED = "bjt_modified";
private static final String OPTIMISTIC_LOCK_NAME = "version";
public static void main(String[] args) {
//创建自动代码生成对象
AutoGenerator autoGenerator = new AutoGenerator();
//1、全局配置
GlobalConfig globalConfig = new GlobalConfig();
//设置作者
globalConfig.setAuthor("xiaoye");
//获取当前项目路径
String properties = System.getProperty("user.dir");
//设置输出路径
globalConfig.setOutputDir(properties + "/src/main/java");
//不要打开资源管理器
globalConfig.setOpen(false);
//不覆盖原文件
globalConfig.setFileOverride(false);
//service接口不带I前缀
globalConfig.setServiceName("%sService");
//设置id自增
globalConfig.setIdType(IdType.AUTO);
//设置时间格式
globalConfig.setDateType(DateType.TIME_PACK);
//配置swagger2文档
globalConfig.setSwagger2(true);
//设置mapper.xml生成一个RestMap
globalConfig.setBaseResultMap(true);
autoGenerator.setGlobalConfig(globalConfig);
//2、数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setDbType(DbType.MYSQL);
dataSourceConfig.setDriverName(DATA_SOURCE_DRIVER);
dataSourceConfig.setUrl(DATA_SOURCE_URL);
dataSourceConfig.setUsername(DATA_SOURCE_USERNAME);
dataSourceConfig.setPassword(DATA_SOURCE_PASSWORD);
autoGenerator.setDataSource(dataSourceConfig);
//3、生成包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setModuleName(MODULE_NAME);
packageConfig.setParent(MODULE_PARENT_NAME);
packageConfig.setEntity("entity");
packageConfig.setMapper("mapper");
packageConfig.setService("service");
packageConfig.setController("controller");
autoGenerator.setPackageInfo(packageConfig);
//4、策略配置
StrategyConfig strategyConfig = new StrategyConfig();
//要映射的表名
strategyConfig.setInclude(TABLE_NAME);
//下划线转驼峰命名
strategyConfig.setNaming(NamingStrategy.underline_to_camel);
//下划线转驼峰命名
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
//开启lombok
strategyConfig.setEntityLombokModel(true);
//开启逻辑删除名字
strategyConfig.setLogicDeleteFieldName(LOGIC_DELETE_NAME);
//自动填充设置
TableFill bjtCreate = new TableFill(GMT_CREATE, FieldFill.INSERT);
TableFill bjtModified = new TableFill(GMT_MODIFIED, FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFieldList = new ArrayList<>();
tableFieldList.add(bjtCreate);
tableFieldList.add(bjtModified);
strategyConfig.setTableFillList(tableFieldList);
//乐观锁配置
strategyConfig.setVersionFieldName(OPTIMISTIC_LOCK_NAME);
//restFul风格
strategyConfig.setRestControllerStyle(true);
//下划线url
strategyConfig.setControllerMappingHyphenStyle(true);
autoGenerator.setStrategy(strategyConfig);
//开始执行代码生成
autoGenerator.execute();
}
}
0 条评论
下一页