Mybatis-plus使用笔记
参考资料
参考链接:https://blog.csdn.net/qq_42682745/article/details/120626012
参考视频:https://www.bilibili.com/video/BV17E411N7KN
步骤
1、创建数据库以及对应的表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户唯一标识',
`account_id` varchar(100) DEFAULT NULL COMMENT '用户编号',
`name` varchar(50) DEFAULT NULL COMMENT '用户名',
`token` varchar(36) DEFAULT NULL COMMENT '主动设置的密钥',
`gmt_create` bigint(50) DEFAULT NULL COMMENT '创建时间',
`gmt_modified` bigint(50) DEFAULT NULL COMMENT '修改时间',
`avatar_url` varchar(255) DEFAULT NULL COMMENT '头像地址',
`deleted` int(10) DEFAULT NULL COMMENT '逻辑删除',
`version` int(10) DEFAULT NULL COMMENT '乐观锁',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
在真实开发中,version(乐观锁)、deleted(逻辑删除)、gmt_create(创建时间)、gmt_modified(更新\修改时间)
2、导入依赖
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--mybatis-plus代码生成器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<!--freemarker模板-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
3、配置文件
#mysql 5 驱动不同 com.mysql.jdbc.Driver 补充:高版本是兼容低版本的
spring.datasource.username=root
spring.datasource.password=8848
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
#useSSL:是否使用安全连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#MySQL8 驱动不同 com.mysql.cj.jdbc.Driver 、需要增加时区的配置
4、运行代码生成器
/代码自动生成器
public class anyuanCode {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8", "root", "8848")
.globalConfig(builder -> {
builder.author("anyuan") // 设置作者
.commentDate("yyyy-MM-dd")//设置时间
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("F:\\idea\\commulity\\src\\main\\java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.anyuan") // 设置父包名
.entity("model")//设置实体类包名
.service("service")//设置service包名
.serviceImpl("service.serviceImpl")//设置service实体类包名
.controller("controller")//设置实体类包名
.mapper("mapper")//设置实体类包名
.xml("mapper")//设置mapper.xml包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "F:\\idea项目\\zhang_hen\\src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("user","question") // 设置需要生成的表名
.addTablePrefix("t_", "c_") // 设置过滤表前缀
.serviceBuilder()//service配置策略
.formatServiceFileName("%sService")//service类名 %s适配,更具表明替换
.formatServiceImplFileName("%sServiceImpl")
.entityBuilder()//实体类适配策略
.enableLombok()//开启Lombok
.logicDeleteColumnName("deleted")//说明逻辑删除字段
.enableTableFieldAnnotation()//属性加上说明注解
.controllerBuilder()//controller策略配置
.formatFileName("%sController")
.enableRestStyle()//开启RestController
.mapperBuilder()//mapper配置策略
.superClass(BaseMapper.class)//继承 BaseMapper
.formatMapperFileName("%sMapper")
.enableMapperAnnotation()//@mapper 开启
.formatXmlFileName("%sMapper");
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
- 注意点,我们需要在启动类上去扫描我们的mapper接口
//扫描我们的mapper文件夹
@MapperScan("com/anyuan/mapper")
扩展
配置日志
我们所有的sql现在是不可见的,我们希望知道他是怎么执行的,所以我们必须要看日志
#配置日志
#这里使用默认的控制台输出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
主键生成策略
分布式系统唯一id生成方法:https://www.cnblogs.com/haoxinyue/p/5208136.html
雪花算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
主键自增
我们需要配置逐渐自增
1、实体类字段上加 @TableId(type = IdType.AUTO)
2、数据库字段一定要是自增的
3、再次测试插入即可
其余的源码解释
public enum IdType {
AUTO(0),//数据库id自增
NONE(1),//未设置主键
INPUT(2),//手动输入
ASSIGN_ID(3),//默认策略 使用一个 64 bit 的 long 型的数字作为全局唯一 id。
ASSIGN_UUID(4);//自动生成不含中划线的 UUID 作为主键。主键类型为 String,对应 MySQL 的表字段为 VARCHAR(32)
}
自动填充
创建时间、修改时间!这些个操作一般都是自动化完成的,我们不希望手动更新!
1、实体类的字段属性上增加注解操作
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
2、编写处理器来处理注解
@Component //要是该功能能够使用,需要将其加入到IOC容器中
@Slf4j //加上日志
public class MyDateObjectHandler implements MetaObjectHandler {
//插入式的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ........");
this.setFieldValByName("create_time",new Date(),metaObject);
this.setFieldValByName("update_time",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ........");
this.setFieldValByName("update_time",new Date(),metaObject);
}
}
乐观锁
乐观锁:顾名思义十分乐观,他总是认为不会出现问题,无论干什么都不去上锁!如果出了问题,再次更新值测试
悲观锁:顾名思义十分悲观,他总是认为总是出现问题,无论干什么都会上锁!再去操作!
涉及字段:version 或 new version
主要讲解乐观锁机制!https://baomidou.com/pages/0d93c0/
- 去除记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
乐观锁:
1、先查询,获得版本号 version = 1
-- A线程
update user set name = "kuang", version = version + 1
where id = 2 and version = 1
-- B线程抢先修改,使得vsersion = 2,会导致A线程修改失败
update user set name = "kuang", version = version + 1
where id = 2 and version = 1
测试MP的乐观锁(MP是 Mybatis_plus的简称)
1、在数据库中添加 version 字段 设置默认值为1
2、在代码中添加 version 属性
@Version //乐观锁Version注解
private Integer version;
3、注册主件
//扫描我们的mapper文件夹
@MapperScan("com/anyuan/mapper")
@Configuration //代表该类是配置类
@EnableTransactionManagement // 自动管理事务
public class MybatisPlusConfig {
//注册乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
4、测试乐观锁
// 测试乐观锁成功案例
@Test
void contextLoad3() {
//1、查询用户信息
User user = userMapper.selectById(1L);
//2、修改用户信息
user.setName("kuangsheng说");
user.setEmail("123456@qq.com");
//3、执行更新操作
userMapper.updateById(user);
}
// 测试乐观锁失败案例!多线程下
@Test
void contextLoad4() {
//线程1
User user = userMapper.selectById(1L);
user.setName("kuangsheng说11111");
user.setEmail("123456@qq.com");
System.out.println(user);
//模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName("kuangsheng说2222");
user2.setEmail("123456@qq.com");
userMapper.updateById(user2);
userMapper.updateById(user);//如果没有乐观锁,就会覆盖插队线程的值
}
分页查询
MP其实也内置了分页插件
1、配置拦截器组件即可
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//注册乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//注册分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
2、直接使用page对象即可
//测试分页查询
@Test
public void test7(){
//参数一 :当前页
//参数二:页面大小
Page<User> page = new Page<>(2, 5);
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
}
逻辑删除
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量让他失效!deleted = 0 => deleted = 1
管理员可以查看被删除的数据!防止数据的丢失,类似于回收站
1、在数据表中增加一个deleted
字段
2、pojo实体类中增加属性
@TableLogic //逻辑删除注解
private Integer deleted;
3、增加配置
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)
实际代码操作
#配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
mybatis-plus.global-config.db-config.logic-delete-field=deleted
条件构造器
参考官方文档
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战