最近突然想学一下mybatis-plus希望尽快提上日程吧。
好了,提上日程,冲冲冲
快速开始
这里贴一个官网连接 mybatis-plus
照着他们一步步来就可以了,有些省事,但确实写的非常详细。
BaseMapper 中的 insert方法的默认 策略
在 mp(mybatis-plus) 中,你使用 insert方法的时候,是会自动将id 回填到的对象中的,但是默认情况生成的是这种一连串的 数字
这种生成方式,采用的是 Twitter的雪花算法,具体了解可百度,保证了分布式的情况下id也唯一。
如果你想使用 主键自增的方式,你需要将数据库表中的 主键自增打开,然后在 id 属性上加 @TableId(type = IdType.AUTO)
@Data
public class User {
//主键自增
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
虽然分布式下采用默认的生成策略较好,但是毕竟身为大三狗,我写的也都是小项目。所以就先用自增吧。
update 方法
mp的 update 是 执行的是动态sql, 也就是条件修改
@Test
void testUpdate() {
User user = new User();
user.setId(1238647983271899149L);
user.setName("hello");
user.setAge(20);
userMapper.updateById(user);
}
你对象里没有的字段,是不会进行修改的
关于 create_time 和 update_time 的问题
在阿里开发手册中写了,数据表必须要有这两个字段。
所以不免会想到,这两个字段能不能自动生成或更新,不通过每次创建时间。
一般有两种策略
之前我用的就是这种
- 数据库自动生成
对这两个字段设置默认值为 CURRENT_TIMESTAMP ,update需要在 根据时间戳更新那里打上勾- mp 生成自动填充
//插入的时候自动填充
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
//插入和更新的时候自动填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
//自动填充 增强类 这里的cretaeTime是实体类属性而不是数据库字段名
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
//插入填充
@Override
public void insertFill(MetaObject metaObject) {
//自动填充时间
log.info("insertFill running");
//三个参数分别是 字段名,填充值,元数据
this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
}
//更新填充
@Override
public void updateFill(MetaObject metaObject) {
//自动填充时间
log.info("updateFill running");
//三个参数分别是 字段名,填充值,元数据
this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
}
}
查询
批量查询
@Test
//批量查询 in(1, 2, 3)
void testSelectBatchIds() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
条件查询
//简单的 条件查询
@Test
void testSelectByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name","hello");
map.put("email","geji@qq.com");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
分页查询
@Test
void testSelectPage() {
Page<User> userPage = new Page<>(1, 5);
userMapper.selectPage(userPage, null);
List<User> records = userPage.getRecords();
records.forEach(System.out::println);
}
逻辑删除
数据库添加逻辑字段
在实体类里也添加字段
//表示当前字段为逻辑删除字段,默认1删除,0未删除
@TableLogic
private Integer isDeleted;
代码生成器 和 配置
要引入 模版和 generator 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1.tmp</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&useUnicode=yes
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations:
- classpath:cn.edu.zzuli.mapper.xml/*.xml
@Test
void testCodeGenerator() {
//1.创建代码生成器
AutoGenerator mpg = new AutoGenerator();
//2.全局配置
GlobalConfig gc = new GlobalConfig();
//获取当前项目的路径
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("geji");
//生成后是否打开资源管理器
gc.setOpen(false);
//生成文件的时候是否重新覆盖
gc.setFileOverride(false);
//设置主键策略
gc.setIdType(IdType.AUTO);
//设置Service首字母去除I
gc.setServiceName("%sService");
//设置日期类型
gc.setDateType(DateType.TIME_PACK);
//实体属性 Swagger2 注解
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//3.数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&useUnicode=yes");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName(scanner("模块名"));
pc.setParent("cn.edu.zzuli.MybatisPlusGenerate");
pc.setEntity("entity");
pc.setController("controller");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
//策略配置
StrategyConfig strategy = new StrategyConfig();
//strategy.setInclude("xxx"+"_\\w*");//映射的表名
//strategy.setTablePrefix("xxx_");//不生成表的前缀
strategy.setNaming(NamingStrategy.underline_to_camel);//驼峰策略
//strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//自动添加 lombok的注解
strategy.setEntityLombokModel(true);
strategy.setLogicDeleteFieldName("is_deleted");
//去除boolean值的前缀
//strategy.setEntityBooleanColumnRemoveIsPrefix(true);
//生成自动填充
TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
List<TableFill> tableFills = new ArrayList<>();
tableFills.add(createTime);
tableFills.add(updateTime);
strategy.setTableFillList(tableFills);
//生成乐观锁的列,version 字段,这里我没有用,就注释掉
//strategy.setVersionFieldName("version");
//RestFul API
strategy.setRestControllerStyle(true);
//url 驼峰命名,转换为_
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
//执行
mpg.execute();
}
条件构造器
舒服啊,这样,特别是 lambdaWrapper,美滋滋好吧
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getName,"halo")
.lt(User::getAge,25);
User user = userMapper.selectOne(queryWrapper);
System.out.println(user);