【MybatisPlus】MP解决四种表与实体的映射问题,以及id自增策略

简介: MP解决四种表与实体的映射问题,以及id自增策略

前言

CRUD多了就形成了一种思维定势——得到的数据字段是与实体类中属性一一对应的,这么一想好像也是中规中矩,按规矩办事。难道表中的字段总是与类中的属性相对应吗?
在这里插入图片描述
上述就是所谓的理想情况,字段与属性一 一对应
下面我们来探究第一种可能出现的问题

一.字段与属性值不同

我更改了实体类中的属性看执行一条普通的查询会报出什么样的结果
在这里插入图片描述
查询失败!
因此,当表的列名和模型类的属性名发生不一致,就会导致数据封装不到模型对象,这个时候就需要其中一方做出修改
这时MP的一个注解帮我们解决了这个问题,MP给我们提供了一个注解@TableField,使用该注解可以实现模型类属性名和表的列名之间的映射关系,就像这样@TableField(value = "password")
在这里插入图片描述

二.表中不存在的属性

当实体类中出现了一个数据库表不存在的字段,就会导致生成的sql语句中在select的时候查询了数据库不存在的字段
在这里插入图片描述
具体的解决方案用到的还@TableField注解,它有一个属性叫exist,设置该字段是否在数据库表中存在,如果设置为false则不存在,生成sql语句查询的时候,就不会再查询该字段

三.表中不存在的属性

操作后可能把一些敏感数据查询到返回给前端,这个时候我们就需要限制哪些字段默认不要进行查询,按照常理,密码等隐私信息不应该被一同查询出来,我们如何做到对这些字段的隐藏呢?还是通过@TableField注解:
在这里插入图片描述
@TableField注解的一个属性叫select,该属性设置默认是否需要查询该字段的值,true(默认值)表示默认查询该字段,false表示默认不查询该字段

名称 @TableField
类型 属性注解
位置 模型类属性定义上方
作用 设置当前属性对应的数据库表中的字段关系

**value(默认):设置数据库表字段名称
exist: 设置属性在数据库表字段中是否存在,默认为true,此属性不能与value合并使用
select: 设置属性是否参与查询,此属性与select()映射配置不冲突**

四.类名表名不匹配

记得懒羊羊在前段时间解决了一个bug:
在这里插入图片描述
简而言之,就是实体类的类名和数据库里的表名没有做到一致,导致MP不能和表相映射关联。没想到学到后面竟然可以采用注解的方式解决:
MP提供的另外一个注解@TableName来设置表与实体类之间的对应关系
在这里插入图片描述
这样,我就再也不用刻意的去按照表名来写实体类啦!

名称 @TableName
类型 ==类注解==
位置 模型类定义上方
作用 设置当前类对应于数据库表关系
相关属性 value(默认):设置数据库表名称

五.id自增策略

1.type = IdType.AUTO

刚使用MP时,我就写了一个增添的方法,只不过比较奇怪的是,添加的数据主键id不是依次递增的,而是一个非常奇怪的数字,就像这样:
在这里插入图片描述
新增成功后,主键ID是一个很长串的内容,我们更想要的是按照数据库表字段进行自增长,而且不同的表应用不同的id生成策略比如:
**日志:自增(1,2,3,4,……)
订单:特殊规则(FQ77948AK3982)
外卖单:关联地区日期等信息(50 22 24765314 87 44)**

我们以自增为例:@TableId注解
在这里插入图片描述

名称 @TableId
类型 ==属性注解==
位置 模型类中用于表示主键的属性定义上方
作用 设置当前类中主键属性的生成策略
相关属性 value(默认):设置数据库表主键名称<br/>type:设置主键属性的生成策略,值查照IdType的枚举值

idType的枚举类中还有很多的策略:

@Getter
public enum IdType {
    /**
     * 数据库ID自增
     * <p>该类型请确保数据库设置了 ID自增 否则无效</p>
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充</p>
     */
    INPUT(2),

    /* 以下2种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 分配ID (主键类型为number或string),
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
     *
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * 分配UUID (主键类型为 string)
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
     */
    ASSIGN_UUID(4);

    private final int key;

    IdType(int key) {
        this.key = key;
    }
}

接下来我们看一下另一种策略

2.type = IdType.INPUT

通过自己注册自动填充
当关闭数据库里的自动递增,使用该策略执行增添操作时:
@TableId(type = IdType.INPUT)

    @Test
    void testSave() {
        Users user = new Users();
        user.setName("暖羊羊");
        user.setPw("777");
        user.setAge(11);
        user.setTel("26262665");
        userDao.insert(user);
    }

在这里插入图片描述
显然无法增添该数据,生成的SQL里竟然出现了id而在方法里没有传入id,所以我们需要自己填入:

    @Test
    void testSave() {
        Users user = new Users();
        user.setId(77L);
        user.setName("暖羊羊");
        user.setPw("777");
        user.setAge(11);
        user.setTel("26262665");
        userDao.insert(user);
    }

最后也是完成了增添
在这里插入图片描述

NONE 不设置id生成策略
INPUT 用户手工输入id
ASSIGN_ID 雪花算法生成id(可兼容数值型与字符串型)
ASSIGN_UUID 以UUID生成算法作为id生成策略

也是查阅了一下各种策略的优缺:

  • NONE: 不设置id生成策略,MP不自动生成,约等于INPUT,所以这两种方式都需要用户手动设置,但是手动设置第一个问题是容易出现相同的ID造成主键冲突,为了保证主键不冲突就需要做很多判定,实现起来比较复杂
  • AUTO:数据库ID自增,这种策略适合在数据库服务器只有1台的情况下使用,不可作为分布式ID使用
  • ASSIGN_UUID:可以在分布式的情况下使用,而且能够保证唯一,但是生成的主键是32位的字符串,长度过长占用空间而且还不能排序,查询性能也慢
  • ASSIGN_ID:可以在分布式的情况下使用,生成的是Long类型的数字,可以排序性能也高,但是生成的策略和服务器时间有关,如果修改了系统时间就有可能导致出现重复主键

3.雪花算法简介

使用一个 64 bit 的 long 型的数字作为全局唯一 ID。在分布式系统中的应用十分广泛,且 ID 引入了时间戳,基本上保持自增
在这里插入图片描述
雪花算法是 64 位 的二进制,1位是符号位,也就是最高位,始终是0,没有任何意义,因为要是唯一计算机二进制补码中就是负数,0才是正数。41位是时间戳,具体到毫秒,41位的二进制可以使用69年,因为时间理论上永恒递增,所以根据这个排序是可以的

4.统一主键策略

在以后的项目中,为了不去分别配置每个实体类的主键策略,我们可以统一设置逐渐的策略,就像这样:

mybatis-plus:
  global-config:
    db-config:
        id-type: assign_id

这样就做到一次配置处处统一了!

相关文章
|
4月前
|
SQL 数据库
MyBatisPlus-null判定及查询指定字段
MyBatisPlus-null判定及查询指定字段
219 0
|
4月前
|
Java 关系型数据库 MySQL
JPA中实体类属性相关注解与数据表列映射详解
JPA中实体类属性相关注解与数据表列映射详解
80 0
|
8月前
|
SQL Java 数据库连接
MyBatis动态设置表名 获取添加功能自增的主键 自定义映射
MyBatis动态设置表名 获取添加功能自增的主键 自定义映射
131 0
|
9月前
|
SQL 数据库 C++
Jimmer VS MyBatisPlus查询自关联表
对象抓取器是 jimmer-sql 一个非常强大的特征,具备可媲美 GraphQL 的能力。 即使用户不采用任何 GraphQL 相关的技术栈,也能在 SQL 查询层面得到和 GraphQL 相似的对象图查询能力。
60 0
|
SQL Java 数据库连接
OR-Mapping 设计改进(主键查询改进) | 学习笔记
简介:快速学习 OR-Mapping 设计改进(主键查询改进)
66 0
|
SQL 算法 测试技术
Guid算法与标识列(自动增长字段)在表中的应用
Guid算法与标识列(自动增长字段)在表中的应用
146 0
Guid算法与标识列(自动增长字段)在表中的应用
|
SQL Java 数据库连接
MyBatis:关联查询,相同字段名冲突(关联查询只返回了一条子记录)
MyBatis:关联查询,相同字段名冲突(关联查询只返回了一条子记录)
246 0
MyBatis:关联查询,相同字段名冲突(关联查询只返回了一条子记录)
|
Java 数据库连接
Hibernate的复合主键映射(十五)
Hibernate的复合主键映射(十五)
Hibernate的复合主键映射(十五)