【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

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

相关文章
|
1天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
2月前
|
前端开发 JavaScript Java
技术分享:使用Spring Boot3.3与MyBatis-Plus联合实现多层次树结构的异步加载策略
在现代Web开发中,处理多层次树形结构数据是一项常见且重要的任务。这些结构广泛应用于分类管理、组织结构、权限管理等场景。为了提升用户体验和系统性能,采用异步加载策略来动态加载树形结构的各个层级变得尤为重要。本文将详细介绍如何使用Spring Boot3.3与MyBatis-Plus联合实现这一功能。
105 2
|
4月前
|
Java 数据库连接 测试技术
mybatis plus 获取新增实体的主键
mybatis plus 获取新增实体的主键
130 8
|
4月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
85 3
|
4月前
|
算法 Java 数据库连接
mybatis plus 主键策略
mybatis plus 主键策略
52 2
|
4月前
|
Oracle 关系型数据库 Java
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
若依修改,集成mybatisplus报错,若依集成mybatisplus,总是找不到映射是怎么回事只要是用mp的方法就找报,改成mybatisPlus配置一定要改
若依修改,集成mybatisplus报错,若依集成mybatisplus,总是找不到映射是怎么回事只要是用mp的方法就找报,改成mybatisPlus配置一定要改
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
MyBatisPlus如何根据id批量查询?Required request parameter ‘id‘ for method 解决方法是看青戈大佬MybatisPlus的教程
|
24天前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
70 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。

相关实验场景

更多