SpringBoot与MybatisPlus MybatisPlus

这篇具有很好参考价值的文章主要介绍了SpringBoot与MybatisPlus MybatisPlus。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、MyBatisPlus概述

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

MyBatis-Plus(简称 MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。

MyBatisPlus的愿景是成为MyBatis最好的搭档,就像魂斗罗中的1P、2P,基友搭配,效率翻倍。

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

官方网址:MyBatis-Plus 

二、SpringBoot集成MyBatisPlus

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

1、创建SpringBoot项目,添加MyBatisPlus起步依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<!-- MyBatisPlus -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.5.0</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.26</version>
</dependency>
<!-- lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>

2、在SpringBoot配置文件中配置数据源

# 数据源
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///mybatis?serverTimezone=UTC
    username: root
    password: 123456

3、编写实体类

@Data
public class User {
    public Integer id;
    public String username;
    public String sex;
    public String address;
    public Integer account;
}

 4、编写Mapper接口,继承BaseMapper

public interface UserMapper extends BaseMapper<User> {

}

5、在 SpringBoot启动类中添加 @MapperScan 注解,扫描Mapper文件夹

@SpringBootApplication
@MapperScan("com.zj.mapper")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

6、测试Mapper方法

@SpringBootTest
public class TestUserMapper {

    @Resource
    private UserMapper userMapper;

    @Test
    public void test(){
        User user = userMapper.selectById(10);
        System.out.println(user);
    }
}

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

二、MyBatisPlus  CRUD

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

2.1 添加

1、配置文件开启SQL日志打印

# 开启SQL日志
mybatis-plus:
  configuration:
   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2、测试添加方法

    @Test
    public void testAdd(){
       User user = new User(null,"梅川内酷","男","临沂市",3000);
       userMapper.insert(user);
        // MyBatisPlus插入成功后,可直接直接获取主键的值
        System.out.println(user.getUserId());
    }

2.2 相关注解

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

我们将user类中的字段修改为和数据库表中的字段不一致。将表名称改为tb_user, 这样表中的字段、表名都和实体类不一致。这样mybatosplus无法自动将字段和属性对应。也就无法生成正确的sql语句。此时需要使用注解来指定映射关系。

@TableName

作用:指定类为哪个表的实体类

位置:类上方

@TableId

作用:指定实体类的属性为主键

位置:属性上方

属性:

  • value:主键字段名

  • type:主键策略

描述
NONE 无状态,不设置主键类型
AUTO 自增主键
INPUT 插入前自行设置主键值
ASSIGN_ID 默认策略,使用雪花算法自动生成主键ID,主键类型为整形或字符串。(雪花算法:微博开源的分布式ID生成算法,使用一个64位的Long类型数字作为全局唯一ID。在分布式系统中的应用十分广泛,且ID引入了时间戳,基本上保持自增)
ASSIGN_UUID 自动生成排除中划线的UUID作为主键,主键类型为

@TableField

作用:在属性和列名不同的情况下,指定映射关系

位置:非主键属性上方

@Data
@AllArgsConstructor
@TableName("tb_user")
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    public Integer UserId;
    @TableField("username")
    public String userName;
    @TableField("sex")
    public String userSex;
    @TableField("address")
    public String userAddress;
    @TableField("account")
    public Integer userAccount;
}

2.3 修改

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

    @Test
    public void testUpdate(){
        User user = new User(1,"梅川丘酷","男","烟台市",4000);
        userMapper.updateById(user);
    }

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

2.4 删除

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 根据id删除

    @Test
    public void testDeleteById(){
        userMapper.deleteById(8);
    }

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

批量删除

    @Test
    public void testDeleteBatch(){
        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(9);
        ids.add(10);
        ids.add(11);
        userMapper.deleteBatchIds(ids);
    }

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

根据字段的条件删除

    @Test
    public void testDeleteMap(){
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("sex","男");  ;//删除所有字段(字段是数据库列名不是类的属性名)值是男的数据
        userMapper.deleteByMap(map);
    }

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

2.5 查询

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

根据id查询

    @Test
    public void testFindById(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE id=?
==> Parameters: 5(Integer)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==      Total: 1

根据id批量查询

    @Test
    public void testFindBatch(){
        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(5);
        ids.add(6);
        ids.add(12);
        List<User> users = userMapper.selectBatchIds(ids);
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE id IN ( ? , ? , ? )
==> Parameters: 5(Integer), 6(Integer), 12(Integer)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==        Row: 12, 唐宛凝, 女, 石家庄市, 3334
<==      Total: 3

根据字段条件查询

    @Test
    public void testFindByMap(){
        Map<String,Object> map = new HashMap<String,Object>();
        //条件之间是and关系
        map.put("username","张晓");
        map.put("address","青岛市");
        List<User> users = userMapper.selectByMap(map);
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE address = ? AND username = ?
==> Parameters: 青岛市(String), 张晓(String)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==      Total: 1

 2.7 条件构造器

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 Mybatis-Plus通过QueryWrapper对象让用户自由的构建SQL条件,简单便捷,没有额外的负担,能够有效提高开发效率。

条件参数说明:

查询方式 说明
or 或条件语句
and 且条件语句
like 模糊查询 like
notLike 模糊查询 not Like
exists exists 条件语句
notExists not Exists 条件语句
isNull null 值查询
isNotNull is Not Null 查询
in in 查询
notIn not in 查询
groupBy 分组查询
orderBy 排序查询
having 分组后筛选
eq 等于 =
ne 不等于 <>
between between 条件语句
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=

 示例1:查询账户余额在1000-3000之间的用户的信息

    @Test
    public void testFindWrapper(){
         //创建条件构造器
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.ge("account", 1000).lt("account", 3000);
        List<User> users = userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE (account >= ? AND account < ?)
==> Parameters: 1000(Integer), 3000(Integer)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==      Total: 2

示例2:查询账户小于1000或者大于等于9000的用户

    @Test
    public void testFindWrapper(){
         //创建条件构造器
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lt("account", 2000).or().ge("account", 9000);
        List<User> users = userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE (account < ? OR account >= ?)
==> Parameters: 2000(Integer), 9000(Integer)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==        Row: 16, 郑怜雪, 女, 重庆市, 555900
<==        Row: 19, 黎飒, 男, 深圳市, 9000
<==      Total: 3

示例3:查询名字中有张的用户,按照账户升序排序。

    @Test
    public void testFindWrapper(){
         //创建条件构造器
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("username", "张").orderByAsc("account");
        List<User> users = userMapper.selectList(wrapper);
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE (username LIKE ?) ORDER BY account ASC
==> Parameters: %张%(String)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==        Row: 21, 张三, 男, 昆明市, 5000
<==      Total: 2

2.8 分页查询

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

1、在配置类或启动类配置分页插件

// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  return interceptor;
}

2、测试分页查询

    @Test
    public void testFindPage(){
        //分页条件;第一个参数表示从第几条开始,第二个参数表示取几条数据。
        Page page = new Page(0,2);
        IPage<User> iPage = userMapper.selectPage(page, null);//null表示查询全部
        System.out.println("结果集:"+iPage.getRecords());
        System.out.println("总页数:"+iPage.getPages());
        System.out.println("总条数:"+iPage.getTotal());
        System.out.println("当前页:"+iPage.getCurrent());
        System.out.println("每页条数:"+iPage.getSize());

    }
==>  Preparing: SELECT COUNT(*) AS total FROM tb_user
==> Parameters: 
<==    Columns: total
<==        Row: 8
<==      Total: 1
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user LIMIT ?
==> Parameters: 2(Long)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5ff2b8ca]
结果集:[User(UserId=5, userName=翟玲娇, userSex=女, userAddress=长沙市, userAccount=1000), User(UserId=6, userName=张晓, userSex=女, userAddress=青岛市, userAccount=2500)]
总页数:4
总条数:8
当前页:1
每页条数:2

2.9 全局配置

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 假如数据库的所有表都以tb_开头,主键都是自增的。如果针对每一个实体类都要添加相关注解比较麻烦,可以在SpringBoot配置文件中进行全局配置,该配置在所有的实体类中都生效。

mybatis-plus:
  # 全局配置
  global-config:
    db-config:
      #主键类型
      id-type: AUTO
      # 设置表名前缀
      table-prefix: tb_
      # 是否使用驼峰转下划线命名,默认开启 ,例如 实体类中的UserAddress属性等于数据库中的 user_address字段
      table-underline: true

三、ActiveRecord

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。

在MyBatisPlus中,AR模式即在实体类中封装了对数据库的访问,而不通过mapper类。

1、虽然操作数据库不通过mapper类,但需要编写mapper类并继承BaseMapper

public interface UserMapper extends BaseMapper<User> {

}

2、实体类继承Model类,开启AR模式

@Data
@AllArgsConstructor
@TableName("tb_user")
public class User  extends Model<User> {
    @TableId(value = "id",type = IdType.AUTO)
    public Integer UserId;
    @TableField("username")
    public String userName;
    @TableField("sex")
    public String userSex;
    @TableField("address")
    public String userAddress;
    @TableField("account")
    public Integer userAccount;
}

四、ActiveRecord增删改查

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 4.1 AR添加

    @Test
    public void testAdd(){
        User user = new User(null, "李四", "男", "北京市", 12000);
        user.insert();
    }
==>  Preparing: INSERT INTO tb_user ( username, sex, address, account ) VALUES ( ?, ?, ?, ? )
==> Parameters: 李四(String), 男(String), 北京市(String), 12000(Integer)
<==    Updates: 1

4.2 AR根据id修改

    @Test
    public void testUpdate(){
        // 创建实体类对象
        User user = new User();
        // 设置需要更新的属性
        user.setUserAccount(13000);
        // 设置需要修改的id
        user.setUserId(22);
        // 根据主键进行更新,没有设置的值忽略
        user.updateById();
    }
==>  Preparing: UPDATE tb_user SET account=? WHERE id=?
==> Parameters: 13000(Integer), 22(Integer)
<==    Updates: 1

4.3 AR根据id查询

    @Test
    public void testFindById(){
        User user = new User();
        user.setUserId(16);
        User user1 = user.selectById();
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE id=?
==> Parameters: 16(Integer)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 16, 郑怜雪, 女, 重庆市, 555900
<==      Total: 1

4.4 AR删除

    @Test
    public void testDeleteById(){
        User user = new User();
        user.setUserId(21);
        user.deleteById();
    }
==>  Preparing: DELETE FROM tb_user WHERE id=?
==> Parameters: 21(Integer)
<==    Updates: 1

4.5 AR查询所有

    @Test
    public void testFindAll(){
        User user = new User();
        List<User> users = user.selectAll();
    }
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user
==> Parameters: 
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 5, 翟玲娇, 女, 长沙市, 1000
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==        Row: 12, 唐宛凝, 女, 石家庄市, 3334
<==        Row: 16, 郑怜雪, 女, 重庆市, 555900
<==        Row: 18, 梅川内酷, 男, 临沂市, 3000
<==        Row: 19, 黎飒, 男, 深圳市, 9000
<==        Row: 20, 黄林, 男, 昆明市, 5000
<==        Row: 22, 李四, 男, 北京市, 13000
<==      Total: 8

4.6 AR分页查询

    @Test
    public void testFindPage(){
        // 创建分页条件
        Page page = new Page(0,2);
        // 查询构造器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 查询名字包含"张"的学生,按照账户升序排序
        queryWrapper.like("username","张").orderByAsc("account");

        User user = new User();
        // 分页查询
        IPage iPage = user.selectPage(page, queryWrapper);
        // 打印分页数据
        System.out.println("结果集:"+iPage.getRecords());
        System.out.println("总页数:"+iPage.getPages());
        System.out.println("总条数:"+iPage.getTotal());
        System.out.println("当前页:"+iPage.getCurrent());
        System.out.println("每页条数:"+iPage.getSize());
    }
==>  Preparing: SELECT COUNT(*) AS total FROM tb_user WHERE (username LIKE ?)
==> Parameters: %张%(String)
<==    Columns: total
<==        Row: 2
<==      Total: 1
==>  Preparing: SELECT id AS UserId,username,sex AS userSex,address AS userAddress,account AS userAccount FROM tb_user WHERE (username LIKE ?) ORDER BY account ASC LIMIT ?
==> Parameters: %张%(String), 2(Long)
<==    Columns: UserId, username, userSex, userAddress, userAccount
<==        Row: 6, 张晓, 女, 青岛市, 2500
<==        Row: 23, 张三, 男, 北京市, 12000
<==      Total: 2

注意:AR分页查询也需要配置分页插件 

五、MyBatisPlus插件

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

5.1 插件概述 

MyBatis插件机制

MyBatis插件就是对Executor、StatementHandler、ParameterHandler、ResultSetHandler这四个接口上的方法进行拦截,利用JDK动态代理机制,为这些接口的实现类创建代理对象,在执行方法时,先去执行代理对象的方法,从而执行自己编写的拦截逻辑。

  • Executor

    MyBatis的内部执行器,它负责调用StatementHandler操作数据库,并把结果集通过 ResultSetHandler进行自动映射。

  • StatementHandler

    MyBatis直接让数据库执行sql脚本的对象。

  • ParameterHandler

    MyBatis实现Sql入参设置的对象。

  • ResultSetHandler

    MyBatis把ResultSet集合映射成POJO的接口对象。

MyBatisPlus常用插件

MyBatisPlus依据MyBatis插件机制,为我们提供了一些开发中常用的插件,我们在开发中使用即可。

常用插件:

  • 自动分页: PaginationInnerInterceptor
  • 防止全表更新与删除: BlockAttackInnerInterceptor
  • 乐观锁: OptimisticLockerInnerInterceptor

这些插件都实现了InnerInterceptor接口

5.2 分页插件

在配置类或启动类配置分页插件,之前用过,不配置插件的话分页功能无法实现。

// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  return interceptor;
}

5.3 防止全表更新与删除插件

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

作用:分析删除/更新语句,防止小白或者恶意进行删除/更新全表操作。

注意:

  • 该插件只支持 MySQL5.6.3 以上版本
  • 该插件只建议在开发环境中使用,不建议在生产环境使用

插件使用:

1、在配置类或启动类配置防止全表更新与删除插件

// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  // 分页插件
  interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  // 防止全表更新与删除插件
  interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  return interceptor;
}

2、测试全表删除

    @Test
    public void testDeleteAll() {
        User user = new User();
        user.delete(new QueryWrapper());
    }

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 5.4 乐观锁插件

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

修改数据库中的数据时,为了避免同时被其他人修改,最好的办法就是对该数据进行加锁以防止并发。

锁的设计分为悲观锁和乐观锁:

  • 悲观锁:悲观锁对数据被外界修改持保守态度。即在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制。

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

  • 乐观锁:乐观锁在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果冲突,则返回给用户异常信息,让用户决定如何去做

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 MyBatisPlus乐观锁插件实现方式:

  1. 取出记录时,获取当前version
  2. 更新时,带上这个version
  3. 执行更新时, set version = newVersion where version = oldVersion
  4. 如果version不对,就更新失败

使用MyBatisPlus乐观锁插件:

1、注册乐观锁插件

// 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  // 分页插件
  interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  // 防止全表更新与删除插件
  interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  // 乐观锁插件
  interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
  return interceptor;
}

2、修改实体类,添加version列并在该属性上面增加@Version

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User  extends Model<User> {
    @TableId(value = "id",type = IdType.AUTO)
    public Integer UserId;
    @TableField("username")
    public String userName;
    @TableField("sex")
    public String userSex;
    @TableField("address")
    public String userAddress;
    @TableField("account")
    public Integer userAccount;

    @Version
    private Integer version;
}

3、修改数据库表,添加一列整型version字段并设置默认值为0

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

4、测试修改功能 

    @Test
    public void testUpdate1() {
        User user = new User();
        user.setUserId(18);
        user.setUserName("梅川丘酷");
        //如果版本号和数据库一致更新成功,版本号+1,如果不一致更新失败
        user.setVersion(0);
        user.updateById();
    }
==>  Preparing: UPDATE tb_user SET username=?, version=? WHERE id=? AND version=?
==> Parameters: 梅川丘酷(String), 1(Integer), 18(Integer), 0(Integer)
<==    Updates: 1

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 六、MyBatisPlus逻辑删除

6.1 逻辑删除概念

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 在实际开发中,由于数据十分重要,为了避免误删除数据导致数据无法找回,我们往往不会使用物理删除,即从数据库中直接删除数据。而是采用逻辑删除的方式,即不会真正在数据库删除数据,而是通过一个变量代表它被删除。

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 

deleted属性代表该数据是否删除,0代表未删除,1代表已删除。此时增删改查的Sql语句发生变化:

  • 插入: 不作限制
  • 查找: 追加where条件过滤掉已删除数据。
  • 更新: 追加where条件防止更新到已删除数据。
  • 删除: 转变为更新

例如:

  • 删除: update user set deleted=1 where id = 1 and deleted=0
  • 查找: select id,name,deleted from user where deleted=0

6.2 逻辑删除使用

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 1、在配置文件配置逻辑删除

# mybatis-plus相关配置
mybatis-plus:
 # 全局配置
  global-config:
   db-config:
   # 全局逻辑删除的字段名
    logic-delete-field: deleted
   # 逻辑已删除值(默认为 1)
    logic-delete-value: 1
   # 逻辑未删除值(默认为 0)
    logic-not-delete-value: 0

2、修改实体类,添加逻辑删除属性

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User  extends Model<User> {
    @TableId(value = "id",type = IdType.AUTO)
    public Integer UserId;
    @TableField("username")
    public String userName;
    @TableField("sex")
    public String userSex;
    @TableField("address")
    public String userAddress;
    @TableField("account")
    public Integer userAccount;

    @Version
    private Integer version;
    /*逻辑删除*/
    @TableLogic
    private Integer deleted;
}

3、修改数据库表,添加一列整型deleted字段并设置默认值为0

4、测试删除和查询方法,会看到删除时将deleted字段变为1,查询时添加条件deleted=0

    @Test
    public void testDelete() {
        User user = new User();
        user.deleteById(23);
    }
==>  Preparing: UPDATE tb_user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 23(Integer)
<==    Updates: 1

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

bug:

Caused by: org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
	at org.yaml.snakeyaml.reader.StreamReader.update(StreamReader.java:218)
	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:176)
	at org.yaml.snakeyaml.reader.StreamReader.ensureEnoughData(StreamReader.java:171)
	at org.yaml.snakeyaml.reader.StreamReader.peek(StreamReader.java:126)
	at org.yaml.snakeyaml.scanner.ScannerImpl.scanToNextToken(ScannerImpl.java:1177)
	at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:287)
	at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:227)
	at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:195)
	at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158)
	at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:148)
	at org.yaml.snakeyaml.composer.Composer.checkNode(Composer.java:72)
	at org.yaml.snakeyaml.constructor.BaseConstructor.checkData(BaseConstructor.java:114)
	at org.yaml.snakeyaml.Yaml$1.hasNext(Yaml.java:543)
	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:160)
	at org.springframework.beans.factory.config.YamlProcessor.process(YamlProcessor.java:134)
	at org.springframework.boot.env.OriginTrackedYamlLoader.load(OriginTrackedYamlLoader.java:75)
	at org.springframework.boot.env.YamlPropertySourceLoader.load(YamlPropertySourceLoader.java:50)
	at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadDocuments(ConfigFileApplicationListener.java:562)
	at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:518)
	... 37 common frames omitted
Caused by: java.nio.charset.MalformedInputException: Input length = 1

这里要将编码格式设置为utf-8,然后再删除yml配置文件,再重新写一个yml。

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 七、MyBatisPlus扩展

7.1 自动填充

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

由于有了逻辑删除字段,那么向数据库插入数据时候,都需要设置deleted=0,而每次插入数据时都要设置该值十分繁琐,于是MyBatisPlus提供了自动填充功能。

1、为实体类的自动填充字段添加@TableField 

@TableLogic
// 自动填充字段
@TableField(fill = FieldFill.INSERT)
private Integer deleted;

填充策略:

描述
DEFAULT 默认不处理
INSERT 插入操作填充字段
UPDATE 更新操作填充字段
INSERT_UPDATE 插入操作和更新操作均填充字段

2、自定义填充类实现MetaObjectHandler接口

package com.zj.meta;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /* 插入时填充逻辑
     * metaObject 元对象
     * */
    @Override
    public void insertFill(MetaObject metaObject) {
        /* 参数1:填充字段名
         * 参数2:参数值
         * 参数3:元对象*/
      this.setFieldValByName("deleted",0,metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {

    }
}

3、测试插入数据

    @Test
    public void testAdd() {
        User user = new User();
        user.setUserName("小刚");
        user.setUserAddress("淄博市");
        user.setUserSex("男");
        user.setUserAccount(4000);
        user.insert();
    }
==>  Preparing: INSERT INTO tb_user ( username, sex, address, account, deleted ) VALUES ( ?, ?, ?, ?, ? )
==> Parameters: 小刚(String), 男(String), 淄博市(String), 4000(Integer), 0(Integer)
<==    Updates: 1: 1

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 在插入数据的时候,如果将数据库的deleted字段设置默认值为0的话,其实不需要使用mybatisplus的自动填充,因为在添加数据的时候自动就赋值为0了。

7.2 SQL注入器

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 MyBatisPlus方法是有限的,我们可以使用SQL注入器自定义全局方法,注入到全局中,这样所有的Mapper类都能使用该方法,接下来我们自定义一个deleteAll方法。

1、创建注入方法类,继承AbstractMethod

public class DeleteAll extends AbstractMethod {
    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        //1.定义sql语句
        String sql = "delete from "+tableInfo.getTableName();
        //2.定义方法名
        String methodName = "deleteAll";
        //3.构建sqlSource对象,负责将sql传递到数据库
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        //4.构建删除方法
        return this.addDeleteMappedStatement(mapperClass,methodName,sqlSource);
    }
}

2、创建SQL自动注入器,继承AbstractSqlInjector

@Component
public class MySqlInject extends AbstractSqlInjector {

    //注入自定义方法集合
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        ArrayList<AbstractMethod> abstractMethods = new ArrayList<>();
        abstractMethods.add(new DeleteAll());
        return abstractMethods;
    }
}

3、注销防止全表更新与删除插件

4、在Mapper接口中定义deleteAll方法

public interface UserMapper extends BaseMapper<User> {

    void deleteAll();

}

5、测试deleteAll方法,测试的时候不能使用AR模式,因为该方法不存在User类中,而是自定义的。

@Test
public void testDeleteAll() {
  userMapper.deleteAll();
}

7.3 代码生成器

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

如果不想手动编写实体类等文件,MyBaitsPlus提供了代码生成器,它可以读取数据库的表信息,生成MyBaitsPlus代码供我们使用,之前我们学过MyBatis的代码生成器MyBatis Generator,这二者的区别是:

  • MBG基于xml文件配置的,MyBaitsPlus代码生成器是基于Java代码配置的。
  • MBG可生成实体类、Mapper接口、Mapper映射文件;MyBaitsPlus代码生成器可生成实体类、Mapper接口、Mapper映射文件、Service类、Controller类

 1、添加代码生成器所需的依赖

<!-- MyBatisPlus代码生成器 -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-generator</artifactId>
  <version>3.5.1</version>
</dependency>
<!-- MyBatisPlus代码生成器需要的模板引擎 -->
<dependency>
  <groupId>org.apache.velocity</groupId>
  <artifactId>velocity-engine-core</artifactId>
  <version>2.2</version>
</dependency>

2、编写代码生成器

package com.zj.Generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class MyGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql:///mybatis", "root", "123456")
                // 全局配置
                .globalConfig(builder -> {
                    builder.author("zhangjin") // 设置作者
                            .commentDate("MM-dd") // 注释日期格式
                            .outputDir(System.getProperty("user.dir") + "/src/main/java") // 指定输出目录
                            .fileOverride(); //覆盖文件
                })
                // 包配置
                .packageConfig(builder -> {
                    builder.parent("com.zj") // 包名前缀
                            .entity("pojo") //实体类包名
                            .mapper("mapper") //mapper接口包名
                            .service("service") //service包名
                            .controller("controller") //controller包名
                            .xml("mapper"); //映射文件包名
                })
                // 策略配置
                .strategyConfig(builder -> {
                    builder.addInclude("tb_user") // 设置需要生成的表名,可以有多个
                            .addTablePrefix("tb_") // 设置表名前缀
                            .entityBuilder() // 开始实体类配置
                            .enableLombok() // 开启lombok模型
                            .naming(NamingStrategy.underline_to_camel) //表名下划线转驼峰
                            .columnNaming(NamingStrategy.underline_to_camel);//列名下划线转驼峰
                })
                .execute();
    }
}

3、运行代码生成器即可生成代码

7.4 MybatisX生成代码

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

MybatisX是一款基于IDEA的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Marketplace,输入 mybatisx 搜索并安装。

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

1、在IDEA中连接数据库

2、如下操作可以根据数据库表生成Mybaits代码

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 7.5 MybatisX生成映射配置、代码跳转

 1、在Mapper接口中编写方法

public interface StudentMapper extends BaseMapper<Student> {
  List<Student> selectAllBySname(String sname);
}

2、如下操作即可在映射文件中自动生成映射配置

mybatisplus版本对应,java后端,spring boot,mybatis,java,mysql

 

代码跳转

点击Mapper接口或映射文件前的小鸟图案,即可快速在Mapper接口与映射文件间跳转文章来源地址https://www.toymoban.com/news/detail-657090.html

到了这里,关于SpringBoot与MybatisPlus MybatisPlus的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot 和 elasticsearch 版本对应关系

     springboot 和 elasticsearch 对应关系,更新一下,随便记录一下

    2024年02月08日
    浏览(44)
  • 注意JDK与SpringBoot的版本对应关系

    注意SpringBoot版本的选择,如果使用 JDK8 的话,则选择 2.x.x 版本。 Spring官网介绍:如果选择了3.0.0版本的SpringBoot,JDK最低要17 版本不适配会造成Application运行失败。 1、查看JDK版本 2、查看SpringBoot版本 ----创建时: ----运行时:

    2024年02月13日
    浏览(49)
  • 如何查看SpringBoot和JDK版本的对应关系

    写在前面 在进行一些自主学习的时候,发现使用maven方式创建的SpringBoot项目启动失败,最终发现是SpringBoot版本和JDK版本不对应导致的 小折腾一下,记录一下问题解决过程 org/springframework/boot/SpringApplication has been compiled by a more recent version of the Java Runtime (class file version 61.0), t

    2024年02月21日
    浏览(56)
  • 【工作踩坑】openFeign 与 springboot版本对应问题

    1、Faild to load ApplicationContext ,嵌套着: Error creating bean with name ‘configurationPropertiesBeans‘ defined in class path resource springboot: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent openFeign: https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign 我这里两者

    2024年02月16日
    浏览(45)
  • ElasticSearch_10_ES和SpringBoot版本对应关系

    记录开发中遇到的问题: 报错:Elasticsearch exception [type=illegal_argument_exception, reason=request [/index索引名/_search] contain spring 2.4.5版本集成ES时,默认集成的是7.9的ES。 我环境搭建的ES是6.8的,导致两个版本不匹配,报上述错误。下方是spring和ES的对应版本,建议大家做好版本匹配。

    2024年02月12日
    浏览(38)
  • SpringBoot版本和Neo4j图数据库版本对应关系

    Neo4j OGM Version Neo4j Version Bolt Version# Spring Data Neo4j Version Spring Boot Version 3.1.0+ 3.1.x, 3.2.x, 3.3.x 1.5.0+ (compatible with 1.4.0+) 5.1.0+ (compatible with 5.0.0+) 2.0.0+ 3.0.0+ 3.1.x, 3.2.x, 3.3.x 1.4.0+ 5.0.0+ 2.0.0+ 2.1.0+ 2.3.x, 3.0.x, 3.1.x 1.1.0+ 4.2.0+ 1.5.0+ 2.0.2+ 2.3.x, 3.0.x 1.0.0+ 4.1.2 - 4.1.6+ 1.4.x 2.0.1* 2.2.x, 2.3.x 1.0.0-

    2024年02月09日
    浏览(48)
  • Jenkins对应java版本

    官网地址:Java Support Policy 运行jenkins时,需要使用下列Java版本:

    2024年02月04日
    浏览(41)
  • SpringBoot 集成 elasticsearch 7.x和对应版本不一致异常信息处理

    开源框架springboot框架中集成es。使用 org.springframework.data.elasticsearch 下的依赖,实现对 elasticsearch 的CURD,非常方便,但是springboot和elasticsearch版本对应很严格,对应版本不统一启动会报错。 开源框架 Elasticsearch 7.x 安装步骤 注意: springboot集成的elasticSearch的版本可能和 我们自己使

    2024年02月07日
    浏览(35)
  • java之SpringBoot基础、前后端项目、MyBatisPlus、MySQL、vue、elementUi

    在基础篇中,我给学习者的定位是先上手,能够使用 SpringBoot 搭建基于 SpringBoot 的 web 项目开发,所以内容设置较少,主要包含如下内容: 1、 SpringBoot 快速入门 2、 SpringBoot 基础配置 3、基于 SpringBoot 整合 SSMP 学习任意一项技术,首先要知道这个技术的作用是什么,不然学完

    2024年02月10日
    浏览(44)
  • 在android开发环境中,gradle 版本和 java 版本的对应关系

    在android开发环境中,gradle 版本和 java 版本的对应关系 Gradle 版本 所支持的 JDK 版本 6.x JDK 8、JDK 11(仅限 Gradle 6.7 及更高版本) 5.x JDK 7、JDK 8 4.x JDK 6、JDK 7、JDK 8 3.x JDK 6、JDK 7、JDK 8 2.x JDK 6、JDK 7、JDK 8 1.x JDK 6、JDK 7

    2024年02月09日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包