MybatisPlus学习笔记及资源分享(二)

简介: MybatisPlus学习笔记及资源分享(二)

二、常用注解


1.@TableId

问题:


经过以上的测试, MyBatis-Plus 在实现 CRUD 时,会默认将 id 作为主键列,并在插入数据时,默认

基于雪花算法的策略生成 id , 若实体类和表中表示主键的不是 id ,而是其他字段,例如 uid , MyBatis-Plus 会自动识别 uid 为主 键列吗? 我们实体类中的属性 id 改为 uid ,将表中的字段 id 也改为 uid,测试添加功能 程序抛出异常, Field 'uid' doesn't have a default value ,说明 MyBatis-Plus 没有将 uid 作为主键 赋值。

解决 :在实体类表中的字段加上@TableId注解。

@TeableId的Value属性:

若实体类中主键对应的属性为 id ,而表中表示主键的字段为 uid ,此时若只在属性 id 上添加注解

@TableId ,则抛出异常 Unknown column 'id' in 'field list' ,即 MyBatis-Plus 仍然会将 id 作为表的

主键操作,而表中表示主键的是字段 uid

此时需要通过 @TableId 注解的 value 属性,指定表中的主键字段, @TableId("uid") 或

@TableId(value="uid")


@TableId 的 type 属性:

image.png

使用数据库的自增策略,注意,该类型请确保数据库设置了 id 自增, 否则无效

配置全局主键策略:


mybatis-plus:
  configuration:
# 配置MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
# 配置MyBatis-Plus操作表的默认前缀
      table-prefix: t_
# 配置MyBatis-Plus的主键策略
      id-type: auto

2.@TableField

问题:如果实体类中的属性名和字段名不一致的情况,会出现什么问题呢?


如果是驼峰mybatisplus会自动匹配如果不是就要加入@TableField注解


解决:

@TableField("username")
private String name;

3.@TableLogic

说明:用于逻辑删除


逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为 “ 被删除状态 ” ,之后在数据库

中仍旧能看到此条数据记录

(1)在数据库加入is_delete字段(int类型 长度11 默认0,0表示未删除,1表示已删除)

(2)在实体类字段中加入@TableLogic注解

@TableLogic
private Integer isDelete

三、条件构造器和常用接口


1、wapper介绍如图


image.png

Wrapper : 条件构造抽象类,最顶端父类

AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

QueryWrapper : 查询条件封装

UpdateWrapper : Update 条件封装

AbstractLambdaWrapper : 使用 Lambda 语法

LambdaQueryWrapper :用于 Lambda 语法使用的查询 Wrapper

LambdaUpdateWrapper : Lambda 更新封装 Wrapper

2.QueryWrapper常用方法

常用:like,between,or,and,isNotNull,isNull,order,gt(大于),lt小于可以看我博客有详细介绍。


QuerWrapper常用条件参数

https://blog.csdn.net/weixin_47343544/article/details/119796505?spm=1001.2014.3001.5502

方法使用形式:(注:第一个参数是数据库中的字段名)


@Test
public void test01(){
//查询用户名包含a,年龄在20到30之间,并且邮箱不为null的用户信息
//SELECT id,username AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 AND (username LIKE ? AND age BETWEEN ? AND ? AND email IS NOT NULL)
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("username", "a")
                    .between("age", 20, 30)
                    .isNotNull("email");
        List<User> list = userMapper.selectList(queryWrapper);
        list.forEach(System.out::println);
}

3.UpdateWrapper

区别:UpdateWrapper与QueryWrapper区别主要在于使用update方法。updatewrapper有专属的set方法,不用创建实体 对象。


UpdateWrapper:


@Test
public void test07() {
//将(年龄大于20或邮箱为null)并且用户名中包含有a的用户信息修改
//组装set子句以及修改条件
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//lambda表达式内的逻辑优先运算
         updateWrapper
                    .set("age", 18)
                    .set("email", "user@atguigu.com")
                    .like("username", "a")
                    .and(i -> i.gt("age", 20).or().isNull("email"));
}
QueryWrapper:
@Test
public void test04() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
//UPDATE t_user SET age=?, email=? WHERE (username LIKE ? AND age > ? OR email IS NULL)
            ueryWrapper
                    .like("username", "a")
                    .gt("age", 20)
                    .or()
                    .isNull("email");
            User user = new User();
                user.setAge(18);
                user.setEmail("user@atguigu.com");
            int result = userMapper.update(user, queryWrapper);
            System.out.println("受影响的行数:" + result);
}

4.Condition

如果你想在使用QueryWrapper调用方法传入的字段的参数进行验证的话,不用if else可以使用Condition参数,选择方法带condition参数的方法。


例如:


QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper
                            .like(StringUtils.isNotBlank(username), "username", "a")
                            .ge(ageBegin != null, "age", ageBegin)
                            .le(ageEnd != null, "age", ageEnd);

5.LambdaQueryWrapper

说明:LambdaQueryWrapper与QueryWrapper的区别主要在于,将数据库表中的字段变成了在实体类中调用方法如:将“user_name” 变为 User::getUserName


例:


@Test
public void test09() {
//定义查询条件,有可能为null(用户未输入)
        String username = "a";
        Integer ageBegin = 10;
        Integer ageEnd = 24;
     LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
//避免使用字符串表示字段,防止运行时错误
        queryWrapper
                .like(StringUtils.isNotBlank(username), User::getName, username)
                .ge(ageBegin != null, User::getAge, ageBegin)
                .le(ageEnd != null, User::getAge, ageEnd);
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(System.out::println);
}

四、插件


1.使用分页插件,配置

//创建配置类,添加内部拦截器
@Configuration
@MapperScan("com.atguigu.mybatisplus.mapper") //可以将主类中的注解移到此处
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

2.常用分页方法

@Test
public void testPage(){
//设置分页参数
    Page<User> page = new Page<>(1, 5);
    userMapper.selectPage(page, null);
//获取分页数据
    List<User> list = page.getRecords();
    list.forEach(System.out::println);
    System.out.println("当前页:"+page.getCurrent());
    System.out.println("每页显示的条数:"+page.getSize());
    System.out.println("总记录数:"+page.getTotal());
    System.out.println("总页数:"+page.getPages());
    System.out.println("是否有上一页:"+page.hasPrevious());
    System.out.println("是否有下一页:"+page.hasNext());
}


3.实现乐观锁

(1.)实现流程


SELECT id,`name`,price,`version` FROM product WHERE id=1
UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND
`version`=1

(2)在数据库表中添加version(int类型)字段。在实体类中添加version属性,添加@Version注解。


@Data
public class Product {
    private Long id;
    private String name;
    private Integer price;
    @Version
    private Integer version;
}

(3)添加乐观锁插件配置


在配置类中添加乐观锁拦截器


@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加分页插件
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

(4)进行测试,在p2修改失败后,在进行一次查询版本号,在重新插入。


4.通用枚举


(1)在数据库表中加入sex字段(int类型),创建枚举实体类


@Data
public enum SexEnum {
    MALE(1, "男"),
    FEMALE(2, "女");
    @EnumValue
    private Integer sex;
    private String sexName;
}

(2)进行配置


mybatis-plus:
  type-enums-package: com.atguigu.mybatisplus.enums

五、代码生成器


1.引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.1</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

2.输入代码

public class FastAutoGeneratorTest {
public static void main(String[] args) {
    FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&userSSL=false", "root", "123456").globalConfig(builder -> {
                    builder.author("atguigu") // 设置作者
                    //.enableSwagger() // 开启 swagger 模式
                    .fileOverride() // 覆盖已生成文件
                    .outputDir("D://mybatis_plus"); // 指定输出目录
                    })
                    .packageConfig(builder -> {
                    builder.parent("com.atguigu") // 设置父包名
                    .moduleName("mybatisplus") // 设置父包模块名
                    .pathInfo(Collections.singletonMap(OutputFile.mapperXml,                  
                               "D://mybatis_plus"));
                    // 设置mapperXml生成路径
                    })
                    .strategyConfig(builder -> {
                    builder.addInclude("t_user") // 设置需要生成的表名
                    .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker
                    引擎模板,默认的是Velocity引擎模板
                    .execute();
        }
}


相关文章
|
6月前
|
SQL Java 关系型数据库
MyBatisPlus学习笔记(SpringBoot版)
MyBatisPlus学习笔记(SpringBoot版)
497 0
|
SQL Java 关系型数据库
|
SQL Java 关系型数据库
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
java202304java学习笔记第六十六天-ssm-mybatis的dao层实现1
36 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-foreach之2
56 0
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
java202304java学习笔记第六十六天-ssm-mybatis中dao层实现-动态sql-if之1
37 0
|
XML Java 数据库连接
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述1
java202304java学习笔记第六十五天-ssm-声明式控制-基于xml的声明式配置-mybatis的概述1
55 0
java202304java学习笔记第六十六天-ssm-mybatis的增删改查-修改和删除操作1
java202304java学习笔记第六十六天-ssm-mybatis的增删改查-修改和删除操作1
45 0
下一篇
无影云桌面