Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)(3)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)

2.乐观锁(@version)

  1. 应用场景举例

添加和删除的操作简单的介绍完了,接下来介绍一下修改相关的问题及其解决方在案:乐观锁。比如我们在网上购物进行秒杀活动的时候,大家都去抢一个商品,每抢一次商品数量减一,最后一个被抢完的时候需要一个限制条件防止异常,这个处理并发问题的解决方案叫做乐观锁。它通过一个字段来标识,每抢一次该标识+1,这样每个人拿到的标识都不一样,当标识到达设定值后程序开始拦截请求。

  1. 添加乐观锁字段version

在user表上右键设计表格,点击添加字段,编辑version字段,设置数据类型为int,默认值为1

效果如下

  1. 在实体类user中添加乐观锁字段version,并添加@version注解

  1. 在Mpconfig类中添加乐观锁拦截器

要实现每次访问version的效果需要在访问的sql语句里添加功能可以实现 version = version + 1 的字段,mp里乐观锁拦截器可以做这个事情

  1. 在测试类的 testUpdate()方法中编辑修改记录的代码看看效果
  • 代码
void testUpdate(){
        User user = new User();
        user.setId(3L);
        user.setName("Jock666");
        //要传version,如果没有传version就没有锁机制
        user.setVersion(1);
        userDao.updateById(user);
 }
  • 运行结果

右边的version是传入的version,左边的version是更新后的version,可以看到实现了version = version + 1的效果

6. 开启锁机制的第二种方法,先查询,再进行更新操作

  • 代码
@Test
    void testUpdate(){
        //1.先通过要修改的数据id将当前数据查询出来
        User user = userDao.selectById(3L);
        //2.将要修改的属性逐一设置进去
        user.setName("Jock777");
        userDao.updateById(user);
  • 运行结果

  1. 模拟多用户秒杀场景

假设此时秒杀活动已经过去了2秒,数据库里id为3的商品乐观锁字段version已经累加到了3

假设用户1 user, 用户2 user2 再进行秒杀活动,用户2先访问秒杀界点击下单,然后数库更新代表该商品的 id 为 3 的乐观锁字段version, 当用户1再进行访问下单的时候,version == 3的条件不成立,该更新请求操作失效,即秒杀失败

  • 代码
@Test
        void testUpdate(){
        //用户1查询时version=3
        User user = userDao.selectById(3L);
        //用户2查询时version=3
        User user2 = userDao.selectById(3L);
        user2.setName("Jock aaa");
        //用户2更新后version==4
        userDao.updateById(user2);
        user.setName("Jock bbb");
        //此时用户1更新时verion=3的条件不成立,该更新语句失效
        userDao.updateById(user);
    }
  • 运行结果

3. mp快速开发-代码生成器

1.场景介绍

在我们开发mp项目的时候,创建编写实体类功能的时候,模板都差不多,区别就是模块名不一样,这就类似于造句,只要提供模板和参数,mp就能自动帮我们生成代码

  • 模板 :MyBatisPlus提供
  • 数据库相关配置 :读取数据库获取信息
  • 开发者自定义配置 :手工配置
  1. 创建新的springboot空项目DL_mp_generator(不勾选任何依赖,一会手动加),创建好新项目后导入 代码生成器 以及 velocity模板引擎 等坐标(完整代码见资源mybatis-plus源码)
//pom.xml文件
    <dependencies>
        <!--代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--velocity模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
    </dependencies>
  1. 核心代码

创建Generator类,编写核心代码

此时运行没有什么意义,因为什么信息都没有配置

public class Generator {
    public static void main(String[] args) {
        //创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //执行生成器
        autoGenerator.execute();
    }
}

4.配置数据源

public class Generator {
    public static void main(String[] args) {
        //创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //配置数据源信息
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);
        //执行生成器
        autoGenerator.execute();
    }
}

(默认生成文件路径在D盘根目录下)

2.配置文件生成路径

  • 代码
public class Generator {
    public static void main(String[] args) {
        //创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //配置数据源
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);
        //设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");    //设置代码生成位置
        globalConfig.setOpen(true);    //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("东离与糖宝");    //设置作者
        globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);
        //执行生成器
        autoGenerator.execute();
    }
}
  • 运行结果

(默认生成的包名叫baomidou)

  1. 配置包名相关信息

先把baomidou包删除,并将临时表名改为tbl_user并执行如下代码

  • 代码
public class Generator {
    public static void main(String[] args) {
        //创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //配置数据源
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);
        //设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");    //设置代码生成位置
        globalConfig.setOpen(true);    //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("东离与糖宝");    //设置作者
        globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);
        //设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.aaa");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain");    //设置实体类包名
        packageInfo.setMapper("dao");   //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);
        //执行生成器
        autoGenerator.execute();
    }
}
  • 运行结果

解析举例; 可以看到根据表名称生成了tbl前缀,并且实体类中有getter和setter方法

  1. 策略配置
  • 代码
public class Generator {
    public static void main(String[] args) {
        //创建生成器对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //配置数据源
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);
        //设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");    //设置代码生成位置
        globalConfig.setOpen(true);    //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("东离与糖宝");    //设置作者
        globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);
        //设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.aaa");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain");    //设置实体类包名
        packageInfo.setMapper("dao");   //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);
        //策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tbl_user");  //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setTablePrefix("tbl_");  //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: User = tbl_user - tbl_
        strategyConfig.setRestControllerStyle(true);    //设置是否启用Rest风格
        strategyConfig.setVersionFieldName("version");  //设置乐观锁字段名
        strategyConfig.setLogicDeleteFieldName("deleted");  //设置逻辑删除字段名
        strategyConfig.setEntityLombokModel(true);  //设置是否启用lombok
        autoGenerator.setStrategy(strategyConfig);
        //执行生成器
        autoGenerator.execute();
    }
}
  • 运行结果

解析举例: 可以看到数据库表前缀名称 tbl_ 在生成实体类等文件的时候被成功剪切,并且生成了乐观锁和逻辑删除字段,并且启用lombok(自带getter 和 setter方法)

`博客内容借鉴了bilibili黑马程序员SSM课程资料,如有侵权,请联系作者删除`

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
SQL Java 数据库连接
MyBatis-Plus高级用法:最优化持久层开发
MyBatis-Plus 通过简化常见的持久层开发任务,提高了开发效率和代码的可维护性。通过合理使用条件构造器、分页插件、逻辑删除和代码生成器等高级功能,可以进一步优化持久层开发,提升系统性能和稳定性。掌握这些高级用法和最佳实践,有助于开发者构建高效、稳定和可扩展的企业级应用。
52 13
|
3月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
94 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
3月前
|
Java 数据库连接 mybatis
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
该文档详细介绍了如何在Springboot Web项目中整合Mybatis,包括添加依赖、使用`@MapperScan`注解配置包扫描路径等步骤。若未使用`@MapperScan`,系统会自动扫描加了`@Mapper`注解的接口;若使用了`@MapperScan`,则按指定路径扫描。文档还深入分析了相关源码,解释了不同情况下的扫描逻辑与优先级,帮助理解Mybatis在Springboot项目中的自动配置机制。
216 0
Springboot整合Mybatis,MybatisPlus源码分析,自动装配实现包扫描源码
|
4月前
|
SQL XML Java
springboot整合mybatis-plus及mybatis-plus分页插件的使用
这篇文章介绍了如何在Spring Boot项目中整合MyBatis-Plus及其分页插件,包括依赖引入、配置文件编写、SQL表创建、Mapper层、Service层、Controller层的创建,以及分页插件的使用和数据展示HTML页面的编写。
springboot整合mybatis-plus及mybatis-plus分页插件的使用
|
4月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
5月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
391 0
|
3月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
173 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
3月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
109 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
3月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
752 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
3月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
51 0
mybatis使用二:springboot 整合 mybatis,创建开发环境