导入依赖,具体版本根据自己需要可以选择:
com.baomidou mybatis-plus-boot-starterLatest Version
导入mybatis-plus就不用导入mybatis。
数据源配置,这里直接使用spring boot 自带的数据源。
spring.datasource.username=root spring.datasource.password=root spring.datasource.url=jdbc:mysql://localhost:3306/db_test/useSSL=false&useUnicode=true&characterEncoding=utf-8 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis-plus中,提供了一个baseMapper,这个mapper整合了单表的CRUD操作,只要使用Mapper集成,就可以直接使用,同时集成了分页的插件,不过要配置拦截器才能使用。主要扫描接口,@MapperScan("com.mg.mapper"):
package com.baomidou.mybatisplus.core.mapper; import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Param; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Constants; public interface baseMapper{ int insert(T entity); int deleteById(Serializable id); int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap); int delete(@Param(Constants.WRAPPER) Wrapper queryWrapper); int deleteBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList); int updateById(@Param(Constants.ENTITY) T entity); int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper updateWrapper); T selectById(Serializable id); List selectBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList); List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap); T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper); Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper); List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper); List
在Mapper中直接集成即可:
package com.mg.mapper; import com.baomidou.mybatisplus.core.mapper.baseMapper; import com.mg.pojo.User; public interface UserMapper extends baseMapper{ }
简单一波测试:
mybatis-plus,已经帮忙写好了单表的CRUD和方法。
二、日志配置所有的SQL都是不可见的,需要查看SQL执行顺序等等。
#日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
可以根据日期,去分析相关问题。
三、CRUD扩展1、插入,ID会自动添加
@Test
public void test01(){
User user = new User();
user.setName("LMR");
user.setAge(4);
user.setEmail("Lmr@123.com");
int insert = userMapper.insert(user);
System.out.println(insert);
System.out.println(user.toString());
}
主键生成策略:
- UUID
- 自增ID
- 雪花算法(分布式)
- 中间件生成(redis、zookeeper)
雪花算法:
是Twitter开源的分布式ID生成算法,结果是一个Long的ID。核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5bit是数据中心,5bit是机器ID),12bit作为毫秒内的流水号(意味着每个节点在每秒可以产生4096个ID),最后一个符号位永远是0。
可以配置ID生成策略:
@TableId(type = IdType.AUTO)
private Long id;
枚举:
package com.baomidou.mybatisplus.annotation;
import lombok.Getter;
@Getter
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ID_WORKER(3),
UUID(4),
ID_WORKER_STR(5);
private int key;
IdType(int key) {
this.key = key;
}
}
2、更新操作
@Test
public void test02(){
User user = new User();
user.setId(5L);
user.setName("MG base GOGO!");
userMapper.updateById(user);
}
自动填充:
例如修改时间、添加时间都需要自动填充进去,不能手动更新。
- 数据库级别的修改:在表中新增字段,不太建议使用(测试中发现,就算更显操作了,但是值没有改变,则不会填充时间)
- 代码级别的修改,编写处理器进行处理。
@TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;package com.mg.handler; import com.baomidou.mybatisplus.core.handlers.metaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.metaObject; import org.springframework.stereotype.Component; import javax.annotation.security.DenyAll; import java.util.Date; @Component @Slf4j public class MyMeteObjectHandler implements metaObjectHandler { @Override public void insertFill(metaObject metaObject) { log.info("start insert fill。。。"); //字段、值、元数据 this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } @Override public void updateFill(metaObject metaObject) { this.setFieldValByName("updateTime", new Date(), metaObject); } }
乐观锁/悲观锁:
- 乐观锁:总是认为不会出现问题,所以不会去上锁,如果出现了问题,就在再次更新值 version字段
- 悲观锁:认为总是会出现问题,不论干什么都会先上锁在操作
mybatis-plus乐观锁插件:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
下面看看怎么配置:
1、数据库增加字段,version,默认值是1
2、实体类增加version字段和@Version注解
@Version
private Integer version;
3、注册组件(新版本MybatisPlus 为了统一管理插件,使用了一个 统一的插件管理类,只需要注册一个Bean就行了 MybatisPlusInterceptor)
package com.mg.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
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
@MapperScan("com.mg.mapper")
@Configuration
public class MybatisPlusConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInnerInterceptor(){
return new OptimisticLockerInterceptor();
}
}
4、测试,这里user更新就不会成功,因为版本已经被覆盖了
@Test
public void test04(){
//线程1
User user = userMapper.selectById(1L);
user.setName("123");
user.setEmail("2292@123.com");
//线程2
User user2 = userMapper.selectById(1L);
user2.setName("123_2");
user2.setEmail("2292@123.com_2");
userMapper.updateById(user2);
userMapper.updateById(user);
}
3、查询操作
简单查询:
@Test
public void test05(){
//单个查询
User user = userMapper.selectById(1L);
System.out.println("单个查询:" + user.toString());
//批量查询
List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(u ->{
System.out.println("批量:" + u.toString());
});
//条件查询 使用map
Map paramMap = new HashMap<>();
paramMap.put("name", "123_2");
paramMap.put("age", 18);
List users1 = userMapper.selectByMap(paramMap);
users1.forEach(u->{
System.out.println("批量:" + u.toString());
});
}
分页查询:
mybatis-plus 内置分页插件:(如果是线上的话,一般情况下回自己手动写 count()查询的sql)
1、配置拦截器组件即可
// 旧版
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
@Test
public void test06(){
//当前页、页面大小
Page page = new Page<>(1, 5);
IPage userIPage = userMapper.selectPage(page, null);
userIPage.getRecords().forEach(u->{
System.out.println("批量:" + u.toString());
});
}
4、删除
物理删除:
逻辑删除:
1、增加一个deleted字段
2、增加属性
@TableLogic
private Integer deleted;
3、配置组件
//逻辑删除
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
#逻辑删除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
4、测试,生成的sql不会查询出来
@Test
public void test07(){
userMapper.deleteById(1L);
}
四、性能分析插件
主要在平时使用的时候,遇到一些慢sql,mybatis-plus也提供了这样的插件,如果超过设定时间,则停止运行。发现新版本已经没有这个功能了,可能是因为提供这样功能的组件太多了,就给去掉了。
1、导入插件
@Profile({"dev","test"})
@Bean
public PerformanceInterceptor performanceInterceptor(){
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//最大执行时间,超过则不执行
performanceInterceptor.setMaxTime(1);
//sql格式化
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
2、测试使用,超出设置时间,就会抛出异常
五、条件构造器Wapper 条件构造器,十分重要,一些复杂的条件,可以使用这个替代。
1、测试1
@Test
public void test01(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.isNotNull("name").isNotNull("email").ge("age", 12);
List users = userMapper.selectList(queryWrapper);
users.forEach(u->{
System.out.println(u);
});
}
2、测试2,查询一个 selectOne
@Test
public void test02(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "Tom");
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);
}
3、测试3,查询数量selectCount
@Test
public void test03(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.between("age", "1", "30");
int n = userMapper.selectCount(queryWrapper);
System.out.println(n);
}
4、测试4,模糊查询
@Test
public void test04(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.notLike("name", "e")
.likeLeft("name", "e")
.likeRight("email", "1");
List
5、测试5,嵌入sql
@Test
public void test05(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.inSql("id", "select id from user where id<3");
List
6、测试6,排序
@Test
public void test06(){
QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.orderByAsc("id");
List
六、代码自动生成器
引入依赖:
com.baomidou mybatis-plus-generator3.0.5 org.springframework.boot spring-boot-starter-freemarker
生成代码:
package com.mg;
import java.util.Arrays;
import java.util.HashMap;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
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 com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
public class MGCode {
public static void main(String[] args) {
//构建代码生成器对象
AutoGenerator mpg = new AutoGenerator();
//配置策略
//1、全局配置
GlobalConfig gc = new GlobalConfig();
//设置生成地址
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("mg");
//是否打开资源管理器
gc.setOpen(false);
//是否覆盖
gc.setFileOverride(true);
//设置接口名字
gc.setServiceName("%sService");
//主键策略
gc.setIdType(IdType.ID_WORKER);
//日期类型
gc.setDateType(DateType.ONLY_DATE);
//是否开启文档
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/db_test?useSSL=false&useUnicode=true&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、配置一些包
PackageConfig pc = new PackageConfig();
//模块名称
pc.setModuleName("wjf");
//包名
pc.setParent("com.mg");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
pc.setServiceImpl("service.impl");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
//设置需要映射的表明 tb_user
strategy.setInclude("user", "tb_user");
//规则 驼峰
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//Lombok
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
//逻辑删除字段
strategy.setLogicDeleteFieldName("deleted");
//自动填充配置
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
strategy.setTableFillList(Arrays.asList(createTime, updateTime));
//乐观锁
strategy.setVersionFieldName("version");
//controller 相关
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
//执行生成
mpg.execute();
}
}
生成的代码结构:
本文章是基于B站博主,狂神说的,所以mybatis-plus版本比较老,学习新版本的,可以看官网,里面的东西写的很清楚。MyBatis-Plus。



