文章目录
- 映射规则
-
- [1. 列名和属性名不一致](#1. 列名和属性名不一致)
- [2. PO 属性比数据库字段要多](#2. PO 属性比数据库字段要多)
- [3. 关键字冲突](#3. 关键字冲突)
- [4. ID 生成规则](#4. ID 生成规则)
映射规则
1. 列名和属性名不一致
有时你会遇到 PO 类和数据库表字段不一致的情况,并且又没办法将它俩调整成一致。这种情况下,你就要显示地在你的 PO 类的属性上添加 @TableField 注解,并通过它的 value 属性指定该属性所对应的数据库字段。
java
@TableField(value = "location")
private String xxx;
默认情况下,在属性名和数据库字段一致的情况下,@TableField 注解可以偷懒省略掉,不写。但是这种不一致的情况下,你就没法再偷懒了。
2. PO 属性比数据库字段要多
有可能你的数据库字段有 N 个,但是与之对应的 PO 类的属性有 N + 1 个,PO 类属性比数据库字段要多。
警告
个人觉得不应该出现这种情况。出现这种情况的唯一原因就是:有人偷了懒。
本应该再创建一个 JavaBean 的(可能是 DTO,也可能是 Domain),但是偷懒没有。在原本应该使用 DTO 或 Domain 的地方使用 PO ,而 DTO 和 Domain 本身和数据库表结构又不是严格意义对应的,进而导致你要在你的 PO 类中加属性。
PO 类中一加属性,那它还是 PO 吗?它和数据库表还是严格一一对应吗?
通过 @TableField 注解的 exist 属性赋值为 false
,要求 MP 不要管这个属性:在新增/修改操作时,MP 不会把这个属性的值 insert/update 到数据库的表中;在查询操作时,MP 也不会(也不能)用数据库中的某个字段为它赋值。
java
@TableField(exist = false)
private String xxx;
3. 关键字冲突
有时无意中给表名和列名起名字时会和 SQL 语法中的关键字同名。最典型的例子就是 order
。
提示
如果你是手动执行 SQL 语句建表,通常不会出现这种情况。因为在执行建表语句时,就会出错。通常都是大家通过客户端软件,在界面上点点点地建表,从而忽略掉了这个问题。
这种情况下,你需要在你的 PO 类中用上『反单引号(`````)』将表名和列名引起来。其实,本质上本来就是需要的,只不过在不冲突的情况下,我们可以省略。现在无非是加回去了而已。
java
@TableName("`department`")
public class DepartmentPo implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "`id`", type = IdType.AUTO)
private Long id;
@TableField(value = "`name`")
private String name;
@TableField(value = "`location`")
private String location;
}
4. ID 生成规则
从上帝视角看,有 3 方可以为数据库中的数据的 ID 负责:程序员、MP 和数据库自己。
-
『程序员负责』指的是我们在编码过程中,在代码层面为即将 insert 进数据库中的数据准备好 ID 。即,在 insert 到数据库之前,这条数据就已经有了 ID 了。
-
『MP 负责』指的是虽然我们没有决定数据的 ID ,但是由于数据是经由 MP 去执行 insert SQL 语句的,MP 可以为这条数据生成 ID 。也就是说,在 insert 到数据库之前,这条数据已经有 ID 了。
-
由『数据库自己负责』这种情况大家已经很熟悉了,数据库在收到要 insert 的数据时,数据是没有 ID 的,数据库自己来决定这条数据的 ID 。
ID 生成策略指的就是你准备让谁来负责为新数据生成 ID 这个事:
-
@TableId(type = IdType.AUTO)
这就是数据库负责,利用数据库的主键 ID 自增功能。这种情况下,我们在新增数据时不需要考虑为新数据的 ID 赋值。 -
@TableId(type = IdType.INPUT)
这就是程序员负责。这种情况下我们在代码中要为新数据的 ID 属性赋值,并且要保证它是非空且唯一的。 -
ASSIGN_ID
和ASSIGN_UUID
都表示由 MP 负责。对于 ID 为 null 的数据,MP 会使用 uuid 或雪花 id 来为它们赋值,然后再使用 insert SQL 添加到数据库中。