目录
一、mybatis-plus
1. 什么是mybatis-plus
2. 初体验
3、Java8代解析
代码生成器(新)
4、主键生成策略
5. 更新
6. 自动填充
7. 乐观锁
8. 条件查询
9. 分页查询
10. 逻辑删除
11. Wrapper
升级版的mybatis,目的是让mybatis更易于使用, 用官方的话说“为简化而生”
官方网址:mybatis plus
(1)新建springboot项目
(2)运行官网复制建表语句
sql语句:
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, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
(3)导入依赖
com.baomidou
mybatis-plus-boot-starter
3.5.1
mysql
mysql-connector-java
io.springfox
springfox-swagger2
2.9.2
io.springfox
springfox-swagger-ui
2.9.2
org.springframework.boot
spring-boot-starter-freemarker
(4)配置
在 application.yml
配置文件中添加 H2 数据库的相关配置:
server:
port: 8080
spring:
application:
name: MyBatisPlus
datasource:
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/plus?userSSL=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
logging:
level:
com.example.plus.mapper: debug
(1)、mybatis plus生成配置文件
(2)、导入依赖
当前包未传递依赖 MP 包,需要自己引入!
com.baomidou
mybatis-plus-generator
3.5.2
(3)、新建自动生成器MysqlGenerator
①、新建generator软件包,在建MysqlGenerator类
package com.mwy.plus.generator;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Slf4j
public class MysqlGenerator {
/**
* 数据源配置(修改成MySQL)
*/
protected static String URL = "jdbc:mysql://localhost:3306/plus?userSSL=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
protected static String USERNAME = "root";
protected static String PASSWORD = "123456";
protected static DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig.Builder(URL, USERNAME, PASSWORD);
// 处理 all 情况
/**
* 交互式的生成器(all)
* @param tables
* @return
*/
protected static List getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
public static void main(String[] args) {
FastAutoGenerator.create(DATA_SOURCE_CONFIG)
// 全局配置
.globalConfig((scanner,builder) ->
// builder就是globalConfig的构建器
builder.fileOverride() //覆盖已生成文件
.outputDir(System.getProperty("user.dir")+"\\src\\main\\java")
.author(scanner.apply("请输入你的用户名"))
.enableSwagger()
.commentDate("yyyy-MM-dd")
.build() //构建器开始工作
)
// 包配置
.packageConfig(builder-> {
builder
.parent("com.mwy.plus")
.entity("pojo")
.service("service")
.serviceImpl("service.impl")
.mapper("mapper")
.xml("mapper.xml")
.controller("controller")
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "\\src\\main\\resources\\mapper"))
.build();
})
// 注入配置
.injectionConfig((builder) ->
builder.beforeOutputFile(
(a, b) -> log.warn("tableInfo: " + a.getEntityName())
)
)
// 策略配置
.strategyConfig((scanner, builder) ->
builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.addTablePrefix("tb_")
.entityBuilder()
.enableChainModel()
.enableLombok()
.enableTableFieldAnnotation()
.addTableFills(
new Column("create_time", FieldFill.INSERT)
)
.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
.build())
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
}
生成成功:
学习网址:代码生成器配置新 | MyBatis-Plus
· 雪花算法,默认的主键生策略,如果需要保存的实体对象中没有指定的主键值,则默认使用雪 花算法来生成· 自增 ID· 数据库的字段必须是配置了自增· 对应的实体的主键字段加入自增注解: @TableId(type = IdType.AUTO)· 其他类型:
AUTO:自动增长
NONE:未设置主键
INPUT:手动输入
ASSIGN_ID:雪花算法
ASSIGN_UUID:排除到下划线的UUID,32位长度
(1)获取UUID ,没有规律,每一次运行的结果都不相同,用做全局ID
(2)雪花ID,用做全局ID,有规律
(1)通过主键更新
package com.mwy.plus;
import com.mwy.plus.mapper.UserMapper;
import com.mwy.plus.pojo.User;
import com.mwy.plus.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.UUID;
@SpringBootTest
class MyBatisPlusApplicationTests {
@Autowired
private UserMapper mapper;
@Autowired
private IUserService service;
@Test
void contextLoads() {
User a = new User().setId(1L).setName("bbb");
// int i = mapper.updateById(a);
boolean b = service.updateById(a);
System.out.println(b);
}
}
mybatis-plus来帮我们进行自动维护在数据表的设计中,经常需要加一些字段,如:创建时间,最后修改时间等,此时可以使用
(1)在自动填充有两种方式:
①、通过数据库完成自动填充
②、实体类
package com.mwy.plus.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; /** * * @author mwy * @since 2022-03-14 */ @Data @Accessors(chain = true) @TableName("user") @ApiModel(value = "User对象", description = "") public class User implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("主键ID") @TableId(value = "id",type = IdType.AUTO) private Long id; @ApiModelProperty("姓名") @TableField("name") private String name; @ApiModelProperty("年龄") @TableField("age") private Integer age; @ApiModelProperty("邮箱") @TableField("email") private String email; //在代码中同步加入创建时间和最后修改时间的维护 private Date createTime; private Date lastModifiedTime; }
完成后可以通过新增或更新
③、使用程序完成自动填充
将数据库中的自动维护功能取消:
第一步:实体类中加入注解
//在代码中同步加入创建时间和最后修改时间的维护 //表明在插入时自动维护字段 @TableField(fill = FieldFill.INSERT) private Date createTime; //表明在插入和更新时自动维护字段 @TableField(fill = FieldFill.INSERT_UPDATE) private Date lastModifiedTime;
第二步:编写处理类
// 不要忘了处理器是spring的组件 @Component public class AutoFillHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(), metaObject); this.setFieldValByName("lastModifiedTime",new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { //this.setFieldValByName("createTime",new Date(), metaObject); this.setFieldValByName("lastModifiedTime",new Date(), metaObject); } }
完成后可以通过新增或更新
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式(来自官方文档):取出记录时,获取当前version更新时,带上这个version执行更新时, set version = newVersion where version = oldVersion如果version不对,就更新失败
(1)配置示例:
①、在数据库表中增加version字段,表示数据版本号,设置默认值为0
②、修改实体类,在使用类中加入对应的version字段,并使用是乐观锁:
//乐观锁
@TableField("version")
@Version
private int version;
③、配置乐观锁
新建configurator软件包,在建MybatisPlusConfig类
package com.mwy.plus.configurator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
④、测试
package com.mwy.plus;
import com.mwy.plus.mapper.UserMapper;
import com.mwy.plus.pojo.User;
import com.mwy.plus.service.IUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.UUID;
@SpringBootTest
class MyBatisPlusApplicationTests {
@Autowired
private UserMapper mapper;
@Autowired
private IUserService service;
@Test
void contextLoads() {
User u1=mapper.selectById(1L);
User u2=mapper.selectById(1L);
u1.setName("mwy");
u2.setName("mi");
int i1=mapper.updateById(u1);
int i2=mapper.updateById(u2);
System.out.println(i1+"-----"+i2);
}
}
第一次修改成功,第二次未被修改:
System.out.println(mapper.selectBatchIds(Arrays.asList(2L,3L,4L)));
package com.mwy.plus; import com.mwy.plus.mapper.UserMapper; import com.mwy.plus.pojo.User; import com.mwy.plus.service.IUserService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.*; @SpringBootTest class MyBatisPlusApplicationTests { @Autowired private UserMapper mapper; @Autowired private IUserService service; @Test void contextLoads() { //使用map进行查询 Map
map = new HashMap<>(); map.put("name", "Tom"); map.put("age", 28); List users = mapper.selectByMap(map); users.forEach(t-> System.out.println(t)); } }
(1)、分页配置
①、在配置器MybatisPlusConfig中加入配置拦截器:
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
②、测试
package com.mwy.plus; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.mwy.plus.mapper.UserMapper; import com.mwy.plus.pojo.User; import com.mwy.plus.service.IUserService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.*; @SpringBootTest class MyBatisPlusApplicationTests { @Autowired private UserMapper mapper; @Autowired private IUserService service; @Test void contextLoads() { mapper .selectPage(Page.of(1l,2L),null) .getRecords() .forEach(System.out::println); } }
什么是逻辑删除?即:标记删除,并不是真的从数据库中删除,而是做个删除标记,在查询时,过滤掉标记为删除的记录即可。
(1)数据库表结构调整
①、增加字段
②、修改实体类
//标记该字段为逻辑删除字段
@TableLogic
private int deleted;
③、在application.yml中加入如下配置
mybatis-plus: global-config: db-config: #逻辑删除字段名 logic-delete-field: deleted # 1表示逻辑删除 logic-delete-value: 1 # 0 表示未删除 logic-not-delete-value: 0
④、测试:
mapper.deleteById(2L);
状态发生改变:
用于构造查询条件
QueryWrapper与updateWrapper的区别:
updateWrapper还可以设置修改的值
(1)测试
@Test
void contextLoads() {
QueryWrapper wrapper = new QueryWrapper<>();
// likeRight查询右边以T开头的,likeLeft以T结尾的
wrapper.likeRight("name", "T")
.eq("age", 28);
// lt代表<,gt代表>,le代表<=
}
@Test
public void testUpdateWrapper() {
UpdateWrapper u = new UpdateWrapper();
//u.set("name", "TT");
u.eq(true, "id", 6L);
User user = userMapper.selectById(6L);
//user = new User();
user.setName("TTT");
userMapper.update(user, u);
}
结束!!!