title: mybatis-plus学习
date: 2020-10-21 23:58:34
tags:
- java
categories: - java
mybatis-plus学习
本文介绍了mybatis-plus的基本方法及学习,详情请参考官方中文文档
可以参考代码生成器的配置参数
复习mybatis用法
- 依赖
-
@Mapper
注解,表名为mapper接口类,可在此类上使用注解写sql语句 - Controller层注入mapper类,并使用对象进行增删改查
- xml需要配置mybatis全局文件,并设置对应的mapper.xml
快速开始
数据库准备
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
依赖
导入mybatis-plus-boot-starter
,注意,尽量不要同时导入mybatis和mybatis-plus,可能存在版本差异
配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value = "User",description = "用户实体类")
public class User {
@Length(min = 0,max = 10000)
@ApiModelProperty(notes = "自增列id",dataType = "int")
private Long id;
@NotNull(message = "姓名不能为空")
@ApiModelProperty(notes = "姓名",dataType = "String")
private String name;
@Length(min = 0,max = 200,message = "年龄不能超过200")
@ApiModelProperty(notes = "年龄",dataType = "int")
private int age;
@Email(message = "邮箱格式错误")
@ApiModelProperty(notes = "邮箱",dataType = "String")
private String email;
}
mapper
@Repository
public interface UserMapper extends BaseMapper<User> {
}
test
@Test
void contextLoads() {
//查询所有用户
// 参数是mapper,条件构造器,不用的情况下可以用null代替
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
主键生成策略
uuid,自增id,雪花算法,redis,zookeeper(分布式系统唯一id生成)-> @TableId(type = IdType.AUTO)
IdType默认ID_WORKER,详情请到源码里查看
注意:使用AUTO主键自增时,对应数据库字段也必须为auto_increment
自动填充字段
数据库级别
直接使用alter table xxx modify column xxx datetime current_timestamp on update current_timestamp
进行数据库层面的操作
代码级别
首先删除所有的字段的自更新操作(除主键)
再在实体类上
@TableField(fill = FieldFill.INSERT)
private Data createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Data updateTime;
其次编写处理器handler
@Slf4j
@Component
public class MetaMybatisHandler 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) {
log.info("start update fill");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
乐观锁
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
乐观锁插件
-
数据库字段设置version字段
-
实体类添加字段
@Version //乐观锁注解 private Integer version;
-
注册组件
@Configuration @EnableTransactionManagement @MapperScan("com.learnmybatis.plusdemo") public class MybatisPlusConfig { //注册乐观锁插件 // @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
-
测试
@Test public void testOptimisticLocker1(){ // 线程1 User user = userMapper.selectById(2L); user.setName("learn001"); user.setEmail("223311@qq.com"); // 线程2, 都对2L进行操作 User user1 = userMapper.selectById(2L); user1.setName("learn002"); user1.setEmail("test@qq.com"); // 设置了乐观锁的情况下,user线程1失败(不抛异常,可以通过检测version->返回值进行检测是否触发乐观锁) userMapper.updateById(user1); userMapper.updateById(user); }
查询与分页查询
批量查询
@Test
public void testSelectBatchId(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
users.forEach(System.out::println);
System.out.println("------------------");
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("name","java1");
List<User> userList = userMapper.selectByMap(hashMap);
userList.forEach(System.out::println);
}
分页查询
-
配置分页拦截器
@Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false // paginationInterceptor.setOverflow(false); // 设置最大单页限制数量,默认 500 条,-1 不受限制 // paginationInterceptor.setLimit(500); // 开启 count 的 join 优化,只针对部分 left join paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; }
-
测试类
@Test public void testPage(){ // 当前页,页面大小 Page<User> page = new Page<>(1,5); userMapper.selectPage(page,null); page.getRecords().forEach(System.out::println); System.out.println("-----------------------"); page.setCurrent(2).setSize(5).getRecords().forEach(System.out::println); }
删除
普通删除
@Test
public void testDelete(){
userMapper.deleteById(1L);
userMapper.deleteBatchIds(Arrays.asList(2L,3L));
HashMap<String, Object> map = new HashMap<>();
map.put("name","java2");
userMapper.deleteByMap(map);
}
物理删除:从数据库里删除
逻辑删除:设置删除字段
逻辑删除
-
设计数据库删除字段
-
实体类
@TableLogic
注解 -
配置config(高版本不需要)
-
配置文件修改
mybatis-plus: global-config: db-config: logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2) logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
-
查询后会过滤已删除的数据
条件查询
@Test
public void testWrapper(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name").isNotNull("email")
.ge("age","10");
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
代码自动生成器
public class GeneratorCode {
public static void main(String[] args) {
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("jhWu");
gc.setOpen(false);
gc.setFileOverride(false);
gc.setServiceName("%sService");
// 数据库配置
gc.setIdType(IdType.AUTO);
gc.setDateType(DateType.ONLY_DATE);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
// getDataSource dataSource = new getDataSource();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?serverTimezone=UTC&useSSL=false");
dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("123456");
dataSourceConfig.setDbType(DbType.MYSQL);
mpg.setDataSource(dataSourceConfig);
// 包的配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setModuleName("blog");
packageConfig.setParent("com.learnmybatis.plusdemo");
packageConfig.setEntity("entity");
packageConfig.setService("service");
packageConfig.setController("controller");
mpg.setPackageInfo(packageConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user");
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
strategy.setLogicDeleteFieldName("deleted");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 自动填充配置
TableFill createTime = new TableFill("createTime", FieldFill.INSERT);
TableFill modifyTime = new TableFill("modifyTime", FieldFill.INSERT_UPDATE);
strategy.setTableFillList(Arrays.asList(createTime,modifyTime));
// 乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
}