JPA 实体类和表字段映射关系 常用注解
实体类和表
@Entity
标识当前类是一个可持久化的类,由JPA管理当前类的持久化操作。
可指定name
属性,默认类名称一致,JPQL 语言中对应的表名称。
select u from User u
@Table
当前实体和数据库哪个表对应,默认实体类名称,当实体类名称和数据库中表名称不对应时,可指定name
@Access
对于JPA的一些注解,比如@Column 等注解,可以写到类的字段上,也可以写到类的属性上(Getter),Getter()方法上,等位置。默认JPA会扫描字段、属性Getter等位置的注解。可以手动配置,只扫描1个位置上的主键,这样加快JPA的启动速度。
- @Access(value = AccessType.FIELD) 扫描字段上的注解
- @Access(value = AccessType.PROPERTY) 扫描属性上的注解Getter
实体类属性和列
@Id
指定当前属性为表中的主键
主键生成策略
GenerationType.AUTO
JPA默认值,主键值生成策略给实现JPA规范的各个厂商自己完成。根据不同的数据库会选择合适的策略。比如Table、Sequence、Identity等,对于Oracle会选择Sequence,对于MySQL或MSSQL会选择Identity,比如自增长方式。
//Mysql 自增长ID
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
GenerationType.IDENTITY
对于数据库支持IDENTITY,插入时自动给ID赋值。也就是自增长方式。比如MySQL 的AUTO-INCREMENT,对于MySQL 这个策略和AUTO策略是一样的。这个策略不支持Oracle。
//Mysql 自增长ID
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
GenerationType.TABLE
主要为了数据库之间更好的移植,比如MySQL到Oracle 数据库,MySQL的自增长在Oracle中不支持,这种问题很麻烦。对于这种不依赖数据库厂商,新加一个表维护这个表的主键。这个表默认hibernate_sequences
2个列,关系表名称和表中最大主键值。
这种策略通用性最好,但是对于hibernate_sequences
表数据量会越来越大,性能低。并且不能发挥数据库的一些特性,不推荐使用。
@Entity
@Table
public class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private long id;
private String name;
private Date birthday;
}
TABLE 策略,指定主键表
GenerationType.TABLE 策略不指定表时,默认所有表的主键值都存放到一个表hibernate_sequences
中,后期数据量会越来越大。我们可以指定某个Entity对应自己的主键表
@Data
@Entity
@Table
public class User {
@Id
//定义一个主键生成器,name必须知道。创建1个表保存这个表的最大主键值
@TableGenerator(name = "tableGenerator",table = "User_PK",pkColumnName = "tableName",valueColumnName = "tableMaxId")
//主键值,选择一个生成器,name和Generator一致
@GeneratedValue(generator = "tableGenerator",strategy = GenerationType.TABLE)
private long id;
private String name;
private Date birthday;
}
GenerationType.SEQUENCE
通过队列生成主键值,适用于Oracle /DB2 等不能够自动生成主键的数据库。
@Column
当属性名称和表字段名称不一致时,可指定name
,默认属性名称和表字段名称一致。同时还可设置当前列是否唯一,length长度 等等属性
- name 列名,默认和字段名称一致
- unique 唯一约束
- nullable 非空约束
- insertable false 表示insert 时,不会插入这一列的值
- updatable false 表示update时,不会更新这一列的值
- length 指定列长度
- columnDefination JPA属性类型
- precision 类型为decimal时,金额总长度
- scale 类型为decimal时,金额小数位数
@Data
@Entity
@Table
//告诉JPA只扫描字段上的注解
@Access(value = AccessType.FIELD)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(nullable = false,unique = true)
private String name;
@Transient
private Date birthday;
//大数据类型,对于数据库类型text/clob/blob等类型
@Lob
private String content;
}
@Temporal
当前属性如果是Date类型时,有时数据库存储的值可能是Timestemp、sql.Date等类型,这里可指定表字段值如何转换属性字段值。
@Temporal(value = TemporalType.DATE)
private Date birthday;
@Transient
对于属性必须要持久化时,告诉JPA不对这个属性和表中的列进行映射。插入、更新、查询都不会有这个属性参与。一般用于页面展示,不需要保存到数据库中
@Lob
对于大数据类型的映射,默认String 类型对应到数据库都是VARCHAR
类型,默认长度是255。但是对于文章内容或大字符串时,需要用到text/blob/clob
等类型进行映射时。
//大数据类型,对于数据库类型text/clob/blob等类型
@Lob
private String content;