Mybatis-Plus
引入mybatis-plus
简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
环境配置
-
1、在SpringBoot项目中引入依赖,引入mybatis-plus后不用引入mybatis依赖
mysql mysql-connector-java runtime org.projectlombok lombok true com.baomidou mybatis-plus-boot-starter 3.4.1 -
2、配置数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://121.199.33.165:3306/mybatis-plus?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC spring.datasource.username=mybatis-plus spring.datasource.password=123456 -
3、编写Mapper接口
/** * 继承BaseMapper类即可使用mybatis-plus封装好的crud方法 * 泛型传入操作的实体类 */ @Repository public interface UserMapper extends BaseMapper{ } -
4、在启动类添加扫描mapper接口包
@MapperScan("com.wt.mapper") -
5、使用CRUD方法
具体方法参考官网:https://baomidou.com/guide/crud-interface.html#mapper-crud-接口
@Autowired private UserMapper userMapper; @Test void contextLoads() { ListuserList = userMapper.selectList(null); }
配置日志
# 配置日志,此处使用控制台输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
主键生成策略
一、配置主键生成策略
1、全局配置
#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
2、局部配置(针对于某一张表配置)
@TableId(type = IdType.AUTO)
private Long id;
二、雪花算法
SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。
64位ID组成:
- 1 bit:符号位,统一为正数位0
- 41 bit:表示的是时间戳,单位是毫秒
- 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10 台机器上,也就是 1024 台机器
- 12 bit:这个是用来记录同一个毫秒内产生的不同 id
三、主键生成策略的类型
- ID_WORKER:根据雪花算法生成19位的数值
- ID_WORKER_STR:根据雪花算法生成19位的字符串
- AUTO:采用数据库自增方式。(数据库也需要设置自增)
- UUID:使用UUID作为主键ID
- INPUT:手动设置ID
- ONOE:未设置主键
- ASSIGN_ID:根据雪花算法生成19位的数值(主键类型为长整形或字符串)
- ASSIGN_UUID:排除中划线的UUID
自动填充
1、在需要填充的实体类字段加上注解
/**
*FieldFill.INSERT:在插入时进行填充
*FieldFill.UPDATE:在修改时进行填充
*FieldFill.INSERT_UPDATE:在插入和修改时进行填充
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
2、配置自动填充处理类
@Component //将配置类交给spring管理
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 插入时的填充策略
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
//设置填充的字段名,值,对象
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
/**
* 更新时的填充策略
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
乐观锁
一、乐观锁与悲观锁
- 悲观锁:总是假设最坏的情况,每次去数据库拿数据时都认为别人会修改,所以每次拿数据都会进行上锁,直到操作结束后,才会释放锁,别人才能操作。缺点:每次都要加锁,降低执行效率
- 乐观锁:总是假设最好的情况,在去数据库拿数据时,认为没人会修改,所以不会上锁,而是在更新操作的时候,判断此期间有没有人去更新过数据,通过版本号或CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量
二、配置乐观锁
1、在实体类版本号字段上加上@Version注解
@Version
private Integer version;
2、配置乐观锁插件
@EnableTransactionManagement //配置事务管理
@Configuration //标明是配置类
public class MybatisPlusConfig {
/**
* 乐观锁插件(过时写法)
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 乐观锁插件(最新版本写法)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//配置乐观锁
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
3、测试
@Test
public void testOptimisticLocker2() {
User user = userMapper.selectById(1350729402602700801L);
user.setName("张三111");
User user1 = userMapper.selectById(1350729402602700801L);
user1.setName("张三222");
//更新成功
userMapper.updateById(user1);
//更新失败,版本号已经被变动
userMapper.updateById(user);
}
查询操作
-
根据id主键查询
User user = userMapper.selectById(1350729402602700801L); -
根据id集合查询
ArrayListids = new ArrayList<>(); ids.add("1"); ids.add("2"); ids.add("3"); List users = userMapper.selectBatchIds(ids); -
根据Map条件查询
HashMapmap = new HashMap<>(); //封装过滤条件 map.put("name","张三222"); map.put("age","21"); List users = userMapper.selectByMap(map);
分页查询
1、配置查询分页插件
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
/**
* 配置分页插件(过时写法)
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/**
* 配置分页插件(最新版本写法)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//配置分页插件
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
2、使用分页
/*
* 参数一:当前页
* 参数二:每页条数
*/
Page page = new Page<>(1,5);
Page userPage = userMapper.selectPage(page, null);
//分页后数据结果列表
List records = userPage.getRecords();
//数据总数
long total = userPage.getTotal();
删除操作
一、基本删除
//根据id删除
int result = userMapper.deleteById(1L);
//根据id集合删除
ArrayList ids = new ArrayList<>();
ids.add("2");
ids.add("3");
int result2 = userMapper.deleteBatchIds(ids);
//根据Map条件集合删除
HashMap map = new HashMap<>();
map.put("name","张三222");
int result3 = userMapper.deleteByMap(map);
二、逻辑删除
逻辑删除:不真正删除数据,只通过改变逻辑删除字段,让数据不再被查询出来
1、给实体类逻辑删除字段加上注解
@TableLogic
private Integer deleted;
2、逻辑删除插件配置
# 配置mybatis-plus逻辑删除
#全局逻辑删除实体类的字段
mybatis-plus.global-config.db-config.logic-delete-field=deleted
#逻辑已删除的值
mybatis-plus.global-config.db-config.logic-delete-value=1
#逻辑未删除的值
mybatis-plus.global-config.db-config.logic-not-delete-value=0
条件构造器
参考官网:https://mp.baomidou.com/guide/wrapper.html#abstractwrapper
代码生成器
//代码生成器,类为com.baomidou.mybatisplus.generator.AutoGenerator包下
AutoGenerator generator = new AutoGenerator();
//全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//设置输出路径
gc.setOutputDir(projectPath+"/src/main/java");
gc.setAuthor("wutao");
//是否默认打开输出目录
gc.setOpen(false);
//去掉Service接口的首字母I
gc.setServiceName("%sService");
// gc.setSwagger2(true); 实体属性 Swagger2 注解
//将配置设置到代码生成器中
generator.setGlobalConfig(gc);
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
generator.setDataSource(dsc);
//包配置
PackageConfig pc = new PackageConfig();
//设置模块名
pc.setModuleName("demo");
//设置父包名目录
pc.setParent("com.wt");
//设置实体类包名
pc.setEntity("model");
//设置业务层接口包名
pc.setService("service");
//设置业务层实现类包名
pc.setServiceImpl("service.impl");
//设置控制层包名
pc.setController("controller");
//设置持久层接口包名
pc.setMapper("dao");
//设置mapper文件包名
pc.setXml("resources/mapper");
generator.setPackageInfo(pc);
//策略配置
StrategyConfig sc = new StrategyConfig();
//指定要映射的数据库表,可以写多个,多个表名用逗号隔开
sc.setInclude("user");
//设置下划线转驼峰命名
sc.setNaming(NamingStrategy.underline_to_camel);
//设置数据库列名规则,用下划线拼接
sc.setColumnNaming(NamingStrategy.underline_to_camel);
//设置是否生成lombok注解
sc.setEntityLombokModel(true);
//自动填充配置
TableFill create_time = new TableFill("create_time", FieldFill.INSERT);
TableFill update_time = new TableFill("update_time", FieldFill.INSERT_UPDATE);
ArrayList list = new ArrayList<>();
list.add(create_time);
list.add(update_time);
sc.setTableFillList(list);
//配置乐观锁
sc.setVersionFieldName("version");
sc.setRestControllerStyle(true);
//将策略配置设置到代码生成器中
generator.setStrategy(sc);
//执行
generator.execute();