【java】【MyBatisPlus】【二】MyBatisPlus常规使用

目录

一、简述

1、概述

2、特性

3、支持数据库

二、标准数据层开发

1、标准数据层CRUD功能

[1.1 新增insert](#1.1 新增insert)

[1.2 删除功能deleteById](#1.2 删除功能deleteById)

[1.3 修改功能updateById](#1.3 修改功能updateById)

[1.4 查询单个selectById](#1.4 查询单个selectById)

[1.5 查询全部selectList](#1.5 查询全部selectList)

2、分页功能

[2.1 设置MybatisPlus分页拦截器作为Spring管理的bean](#2.1 设置MybatisPlus分页拦截器作为Spring管理的bean)

[2.2 分页查询IPage selectPage(IPage page)](#2.2 分页查询IPage selectPage(IPage page))

三、DQL编程控制

[1、条件查询方式IPage selectPage(Wrapper queryWrapper)](#1、条件查询方式IPage selectPage(Wrapper queryWrapper))

[1.1 方式一查询(不推荐) :](#1.1 方式一查询(不推荐) :)

[1.2 方式二查询(推荐):lambda格式减少列名出错](#1.2 方式二查询(推荐):lambda格式减少列名出错)

[1.3 方式三查询(推荐):使用Lambda方式的API](#1.3 方式三查询(推荐):使用Lambda方式的API)

[1.4 组合查询:链式方式(并且)](#1.4 组合查询:链式方式(并且))

[1.5 组合查询:链式方式(或)](#1.5 组合查询:链式方式(或))

[1.6 条件查询 :null值处理](#1.6 条件查询 :null值处理)

2、查询投影

[2.1 适用于lambda方式(推荐)](#2.1 适用于lambda方式(推荐))

[2.2 适用于非lambda方式(不推荐)](#2.2 适用于非lambda方式(不推荐))

[2.3 查询投影的【字段未定义的使用方式】(lambda方式不行)求count](#2.3 查询投影的【字段未定义的使用方式】(lambda方式不行)求count)

[2.3 分组](#2.3 分组)

3、查询条件设定

[3.1 eq相等的查询条件](#3.1 eq相等的查询条件)

[3.2 between范围查询](#3.2 between范围查询)

[3.3 模糊匹配like查询(非全文检索版)](#3.3 模糊匹配like查询(非全文检索版))

4、字段映射与表名映射

[4.1 使用TableField(value="数据库字段名")注解 解决数据库字段与实体不一致问题](#4.1 使用TableField(value="数据库字段名")注解 解决数据库字段与实体不一致问题)

[4.2 使用TableField(exist=false)注解解决数据库未定义属性](#4.2 使用TableField(exist=false)注解解决数据库未定义属性)

[4.3 使用TableField(select=false)注解设置属性是否参与查询](#4.3 使用TableField(select=false)注解设置属性是否参与查询)

[4.4 使用TableName("数据库表名")注解设置数据库表名不一致问题](#4.4 使用TableName("数据库表名")注解设置数据库表名不一致问题)

[4.5 使用TableId注解 将属性所对应字段指定为主键](#4.5 使用TableId注解 将属性所对应字段指定为主键)

[4.6 使用TableId(type=) 注解 指定主键id生成策略](#4.6 使用TableId(type=) 注解 指定主键id生成策略)

[4.7 使用TableLogic注解 逻辑删除](#4.7 使用TableLogic注解 逻辑删除)

四、DML编程控制

1、结合id生成规则(Insert)

2、多记录操作(Delete\Select)

[3、逻辑删除(Delete/Update )](#3、逻辑删除(Delete/Update ))

4、乐观锁(并发控制)(Update)

[4.1 数据库加字段version,默认1](#4.1 数据库加字段version,默认1)

[4.2 实体类新增属性version以及@Version注解](#4.2 实体类新增属性version以及@Version注解)

[4.3 新增拦截器,优化之前的MybatisPlusConfig](#4.3 新增拦截器,优化之前的MybatisPlusConfig)

[4.4 运行修改方法](#4.4 运行修改方法)

[4.5 检验乐观锁](#4.5 检验乐观锁)

五、快速开发

1、代码生成器

2、pom导入坐标

3、创建CodeGenetator文件

4、执行CodeGenetator


前言:MyBatisPlus简介、CRUD、分页、条件查询

一、简述

1、概述

2、特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

3、支持数据库

  • mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird

  • Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、达梦数据库 、虚谷数据库 、人大金仓数据库 、南大通用数据库

二、标准数据层开发

1、标准数据层CRUD功能

1.1 新增insert

@SpringBootTest
class MybatisQuickstartApplicationTests {

    @Autowired
    private EmpMapper empMapper;
    @Test
    void testSave(){
        Emp emp = new Emp();
        emp.setId(0);
        emp.setName("mimi");
        emp.setPassword("111111");
        emp.setUsername("咪咪");
        emp.setGender((short) 2);
        emp.setImage("11.jpg");
        emp.setEntrydate(LocalDate.now());
        emp.setJob((short) 2);
        emp.setDeptId(1);
        emp.setUpdateTime(LocalDateTime.now());
        emp.setCreateTime(LocalDateTime.now());
        empMapper.insert(emp);
    }

}

注意:这里因为id数据库是int类型的自增字段,我之前没有设置值,导致报错:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: Could not set property 'id' of 'class com.bocai.entity.Emp' with value '1715193012897251329' Cause: java.lang.IllegalArgumentException: argument type mismatch。 所以设定了一个值就OK 了

1.2 删除功能deleteById

   /**
     * 通过id删除数据,这里ID25是从库里查出来了.........O(∩_∩)O哈哈~
     */
    @Test
    void testDelete(){
        empMapper.deleteById(25);
    }

1.3 修改功能updateById

    /**
     * 根据ID修改 ,这里的id是库里查的哦
     */
    @Test
    void testUpate(){
        Emp emp = new Emp();
        emp.setId(20);
        emp.setUpdateTime(LocalDateTime.now());
        emp.setName("手感好");
        empMapper.updateById(emp);
    }

注意:这里看上去是setId,实际上他转换成sql是id是where条件

1.4 查询单个selectById

    /**
     * 根据id查询
     */
    @Test
    void testGetById(){
        Emp emp = empMapper.selectById(20);
        System.out.println(emp);
    }

1.5 查询全部selectList

    /**
     * 查询全部
     */
    @Test
    void testGetAll() {
        List<Emp> empList = empMapper.selectList(null);
        System.out.println(empList);
    }

2、分页功能

2.1 设置MybatisPlus分页拦截器作为Spring管理的bean

package com.bocai.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置MP的分页插件
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // 1、定义MybatisPlus拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 2、添加具体的拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;

    }
}

2.2 分页查询IPage<T> selectPage(IPage<T> page)

上一步的拦截器必须添加

    /**
     * 分页查询
     *
     */
    @Test
    void testGetByPage(){
        IPage page = new Page(1,5); // 当前第一页,每页5条
        empMapper.selectPage(page, null);
        System.out.println("当前页码值:" + page.getCurrent());
        System.out.println("每页显示数:" + page.getSize());
        System.out.println("一共多少页:" + page.getPages());
        System.out.println("一共多少条数据:" + page.getTotal());
        System.out.println("数据:" + page.getRecords());
    }

三、DQL编程控制

准备用户

User

package com.bocai.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id; //ID
    private String name; //姓名

    private Integer age; //年龄

    private Short gender; // 性别 1 男  2  女

    private String phone; //电话
}

UserMapper

package com.bocai.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.bocai.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

1、条件查询方式IPage<T> selectPage(Wrapper<T> queryWrapper)

1.1 方式一查询(不推荐) :

   /**
     * 条件查询  //  小于的查询条件lt(列名,值) 
     */
    @Test
    void testConditionGetAll() {
        //按条件查询
        QueryWrapper qw = new QueryWrapper<>();
        qw.lt("age",38); 
        List<User> userList = userMapper.selectList(qw);
        System.out.println(userList);
    }

1.2 方式二查询(推荐):lambda格式减少列名出错

    /**
     * 条件查询  //  小于的查询条件lt(列名,值)
     */
    @Test
    void testConditionGetAll() {

        //按条件查询 方式二lambda格式
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.lambda().lt(User::getAge,38);
        List<User> userList = userMapper.selectList(qw);
        System.out.println(userList);
    }

1.3 方式三查询(推荐):使用Lambda方式的API

    /**
     * 条件查询  //  小于的查询条件lt(列名,值)
     */
    @Test
    void testConditionGetAll() {

        //按条件查询 方式三lambda格式
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.lt(User::getAge,38);
        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

1.4 组合查询:链式方式(并且)

    /**
     * 条件查询  //  小于的查询条件lt(列名,值)
     */
    @Test
    void testConditionGetAll() {


        //按条件查询 多条件
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.lt(User::getAge,49).gt(User::getAge,38);

        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

1.5 组合查询:链式方式(或)

    /**
     * 条件查询  //  小于的查询条件lt(列名,值)
     */
    @Test
    void testConditionGetAll() {


        //按条件查询 多条件38到49之外
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        // 38到49之外
        lqw.lt(User::getAge,38).or().gt(User::getAge,49);

        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

1.6 条件查询 :null值处理

前置条件,我们需要模拟前端传参

package com.bocai.entity.query;

import com.bocai.entity.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserQuery extends User {
    private Integer age2; //年龄

}

    /**
     * 条件查询  
     */
    @Test
    void testConditionGetAll() {


        //按条件查询 处理null 问题
        // 模拟页面传统过来的查询数据
        UserQuery userQuery = new UserQuery();
//        userQuery.setAge(20);
        userQuery.setAge2(40);

        // null的判断

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        // null方式判断是否为空,为空不执行这个
        lqw.lt(null != userQuery.getAge2(),User::getAge,userQuery.getAge2())
           .gt(null != userQuery.getAge(),User::getAge,userQuery.getAge());
        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

2、查询投影

查询投影就是查询显示哪些字段

2.1 适用于lambda方式(推荐)

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

        //========按条件查询 查询投影(适用于lambda方式)

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.select(User::getId,User::getAge,User::getName);
        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

2.2 适用于非lambda方式(不推荐)

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

        //========按条件查询 查询投影(适用于非lambda方式)不推荐

    QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("id","age","name");
    List<User> userList = userMapper.selectList(qw);
        System.out.println(userList);
    }

2.3 查询投影的【字段未定义的使用方式】(lambda方式不行)求count

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

   //========按条件查询 【字段未定义的使用方式】查询投影求count
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("count(*) as count");
        List<Map<String, Object>> maps = userMapper.selectMaps(qw);
        System.out.println(maps);
    }

2.3 分组

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

    //========按条件查询 查询投影求count,并分组
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.select("count(*) as count, gender").groupBy("gender");
        List<Map<String, Object>> maps = userMapper.selectMaps(qw);
        System.out.println(maps);
    }

3、查询条件设定

条件构造器 | MyBatis-Plus

3.1 eq相等的查询条件

一条数据就使用selectOne

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

    //========按条件查询 查询条件设定 =匹配
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //等同于=号
        lqw.eq(User::getName,"金毛狮王").eq(User::getAge,45);
        User user = userMapper.selectOne(lqw);
        System.out.println(user);
    }

3.2 between范围查询

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

   //========按条件查询 范围查询between
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //范围查询between
        lqw.between(User::getAge,38,57);
        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

3.3 模糊匹配like查询(非全文检索版)

likeLeft likeRight 模糊匹配%位置

 /**
     * 条件查询  //
     */
    @Test
    void testConditionGetAll() {

    //========按条件查询 模糊查询(非全文检索版)
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
       //========按条件查询 like 模糊查询   不在演示likeLeft   likeRight 模糊匹配%位置
        lqw.like(User::getName,"王");
        List<User> userList = userMapper.selectList(lqw);
        System.out.println(userList);
    }

4、字段映射与表名映射

4.1 使用TableField(value="数据库字段名")注解 解决数据库字段与实体不一致问题

4.2 使用TableField(exist=false)注解解决数据库未定义属性

实体有online字段,数据库没有

package com.bocai.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id; //ID
    private String name; //姓名
    private Integer age; //年龄
    private Short gender; // 性别 1 男  2  女
    private String phone; //电话
    @TableField(exist = false)
    private Integer online; //是否在线 1 在线 2 不在线
}

4.3 使用TableField(select=false)注解设置属性是否参与查询

4.4 使用TableName("数据库表名")注解设置数据库表名不一致问题

4.5 使用TableId注解 将属性所对应字段指定为主键

4.6 使用TableId(type=) 注解 指定主键id生成策略

下图是雪花算法生成主键id

4.7 使用TableLogic注解 逻辑删除

四、DML编程控制

package com.bocai.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 员工实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    @TableId(type= IdType.AUTO) //数据库自增ID方式
    private Integer id; //ID
    private String username; //用户名
    private String password; //密码
    private String name; //姓名
    private Short gender; //性别 , 1 男, 2 女
    private String image; //图像url
    private Short job; //职位 , 1 班主任 , 2 讲师 , 3 学工主管 , 4 教研主管 , 5 咨询师
    private LocalDate entrydate; //入职日期
    private Integer deptId; //部门ID
    private LocalDateTime createTime; //创建时间
    private LocalDateTime updateTime; //修改时间
}

或者使用全部配置

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
    username: root
    password: XXX
  main:
    banner-mode: off  # 关闭控制台springboot的logo
mybatis-plus:
  configuration:
    #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 控制台显示sql
  global-config:
    db-config:
      id-type: auto   # 数据库id生产规则全局 配置 # ASSIGN_ID雪花算法,数据库id建议使用Long类型
   #   table-prefix: tbl_    # 数据库表前缀全局配置
    banner: false   # 关闭控制台mybatis-plus的logo

1、结合id生成规则(Insert)

   /**
     * 新增
     */
    @Test
    void testSave(){
           Emp emp = new Emp();
//        emp.setId(0);  //实体类设置这个属性就不需要这个@TableId(type= IdType.AUTO)  //数据库自增ID 方式
        emp.setName("dadamimi");
        emp.setPassword("111111");
        emp.setUsername("大大咪咪");
        emp.setGender((short) 2);
        emp.setImage("11.jpg");
        emp.setEntrydate(LocalDate.now());
        emp.setJob((short) 2);
        emp.setDeptId(1);
        emp.setUpdateTime(LocalDateTime.now());
        emp.setCreateTime(LocalDateTime.now());
        empMapper.insert(emp);
    }

数据库ID建议使用Long类型,不然本文后面的雪花算法等长度不够

IdType.AUTO:数据库自增

IdType.NONE:没有策略

IdType.INPUT:用户自己输入 。那么数据库的自增策略要移除,新增要指定id值

IdType.ASSIGN_ID:雪花算法。那么数据库的自增策略要移除,新增不需要指定id值

IdType.ASSIGN_UUID:UUID

/** @deprecated */

-======== 下面三个过时了===

IdType.ID_WORKER:生成整型 被他取代IdType.ASSIGN_ID:

IdType.ID_WORKER_STR:生成字符串 被他取代IdType.ASSIGN_ID:

IdType.UUID:被他取代IdType.ASSIGN_UUID:

2、多记录操作(Delete\Select)

    /**
     * 删除多条记录
     */
    @Test
    void testDeleteList(){
        List<Integer> list = new ArrayList<>();
        list.add(26);
        list.add(28);
        empMapper.deleteBatchIds(list);
    }

3、逻辑删除(Delete/Update )

全局配置,就不需要再实体去配置逻辑删除字段了

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
    username: root
    password: runa#2050
  main:
    banner-mode: off  # 关闭控制台springboot的logo
mybatis-plus:
  configuration:
    #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 控制台显示sql
  global-config:
    db-config:
      id-type: auto   # 数据库id生产规则全局 配置 # ASSIGN_ID雪花算法,数据库id建议使用Long类型
     # logic-delete-field: deleted # 全局配置逻辑删除字段名
     # logic-delete-value: 0 # 全局配置逻没有被删除的写0
      #logic-not-delete-value: 1  # 全局配置逻没有被逻辑删除的写1
    #   table-prefix: tbl_    # 数据库表前缀全局配置
    banner: false   # 关闭控制台mybatis-plus的logo

4、乐观锁(并发控制)(Update)

4.1 数据库加字段version,默认1

4.2 实体类新增属性version以及@Version注解

4.3 新增拦截器,优化之前的MybatisPlusConfig

package com.bocai.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置MP的分页插件
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // 1、定义MybatisPlus拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 2、添加分页的拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        // 3、添加乐观锁的拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;

    }
}

package com.bocai.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置MP的分页插件
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // 1、定义MybatisPlus拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 2、添加分页的拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        // 3、添加乐观锁的拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;

    }
}

4.4 运行修改方法

需要传Version数值进行修改

这个方式不需要version传值,因为查询出来的数据有version

4.5 检验乐观锁

所有bbb 没有成功 ,下面是分析

五、快速开发

1、代码生成器

2、pom导入坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- 1、修改为2.7.5 -->
        <version>2.7.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bocai</groupId>
    <artifactId>mybatis_quickstart</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!--   2、 删除这里
    <name>mybatis_quickstart</name>
    <description>mybatis_quickstart</description>
    -->
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  3、 引入mybatisplus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>
        <!--  4、 引入druid -->
        <!--
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.21</version>
        </dependency>
        -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.23</version>
        </dependency>

        <!--   5、lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <scope>provided</scope> <!-- 不打包 -->
            <version>1.18.24</version>
        </dependency>

        <!--  代码生成器 -->
        <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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、创建CodeGenetator文件

package com.bocai;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;

public class CodeGenerator {
    public static void main(String[] args) {
        AutoGenerator autoGenerator = new AutoGenerator();
        // 配置数据库
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("runa#2050");
        autoGenerator.setDataSource(dataSourceConfig);

        // 设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatis_quickstart/src/main/java"); //设置代码生成文件输出位置  /mybatis_quickstart(这里目录依据你实际项目配置)
        globalConfig.setOpen(false); // 设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("春天的菠菜"); //设置作者
        globalConfig.setFileOverride(false); // 设置是否覆盖原始生成的文件默认是false
        globalConfig.setMapperName("%sMapper"); //设置数据层接口名,%s为占位符,  指代模块名称  也有这样写的%Dao,其实不指定的话 他默认就是Mapper
        globalConfig.setIdType(IdType.AUTO); //设置id生成策略,目前是数据库自增,   可以ASSIGN_ID雪花算法,但数据库就不能是自增属性了
        autoGenerator.setGlobalConfig(globalConfig);

        // 设置包名相关配置
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.niuniu");  //设置生成的包名,与代码所在的位置不冲突,二者叠加组成完整路径
        packageConfig.setEntity("entity");  //设置实体类包名  有的叫domain
        packageConfig.setMapper("mapper"); //设置数据层包名 ,有的叫dao
        autoGenerator.setPackageInfo(packageConfig);

        // 策略设置 这个是关键
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("dept");// 设置当前参与生成的  表名,参数为可变参数
//        strategyConfig.setInclude("tbl_user");// 设置当前参与生成的  表名,参数为可变参数,("tbl_user","sss","ssss")
//        strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称。 模块名= 数据库名 - 前缀名  例如 User = tbl_user - tbl
        strategyConfig.setRestControllerStyle(true);  //设置是否启用Rest风格
        strategyConfig.setVersionFieldName("version"); // 设置乐观锁字段名
        strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
        strategyConfig.setEntityLombokModel(true); //设置是否启用lambok
        autoGenerator.setStrategy(strategyConfig);

        // 执行 生成操作
        autoGenerator.execute();

    }
}

4、执行CodeGenetator

完美

下面那个xml可根据需要迁移到resources对应的文件目录下(包名目录相同)

相关推荐
张国荣家的弟弟5 分钟前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi
ZSYP-S16 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos19 分钟前
c++------------------函数
开发语言·c++
yuanbenshidiaos23 分钟前
C++----------函数的调用机制
java·c++·算法
程序员_三木31 分钟前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊41 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama1 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全1 小时前
Java的基础概念(一)
java·开发语言·python
liwulin05061 小时前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc1 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法