本章主要介绍spring-data-jpa数据库映射实体,东西挺多,所有有必要单独成一张。
建立实体
简单来说,建立一个实体非常容易,如果你不要求特殊的属性,两个注解就能让一个普通的类成为一个jpa支持的实体类:
@Entity 标识这是一个实体
@Id 主键,默认自增
我写了一下代码:
@Entity
public class Student {
@Id
private Integer id;
private String name;
private Integer num;
private Date birthday;
// 省略get/set
}
通常可以满足一般使用了,但是按照真实场景,还是有一些特殊情况需要加以处理。
(1)表名冗长
这里我们需要借助Table注解,注入name的值,代替真实的表名。
@Entity
@Table(name = "T_Student")
(2)需要其他主键生成策略
JPA通过GeneratedValue注解来提供不同的主键生成策略,默认便是自增,下面我们需要主键由数据库自动生成
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
jpa一共提供了四种策略:TABLE,SEQUENCE,IDENTITY,AUTO
TABLE:使用一张表来提供主键值,表中对应一个表始终只防止下一个主键的值,需要配合TableGenerator注解一起使用
@Id
@GeneratedValue(strategy = GenerationType.TABLE,generator = "stSeq")
@TableGenerator(name = "stSeq",
allocationSize = 1,
table = "stSeqTable",
pkColumnName = "st_id",
pkColumnValue="STUDENT_PK",
valueColumnName = "st_count")
其中name是生成器的名字,在GeneratedValue指定,allocationSize可以理解为step,也就是每次增长的大小,table是提供主键的表的名字,pkColumnName是主键字段的键名,pkColumnValue可以理解成Student表保存主键的命名空间,valueColumnName则是保存命名空间的字段。我们重启一下项目会得到一张st_seq_table表,使用jpa的方式保存一个学生,则st_seq_table会出现:
SEQUENCE:利用数据库序列进行主键,需要配合SequenceGenerator注解使用,但是有些数据库不支持(MySql)
IDENTITY:这个便是自动增长了
AUTO:默认方式,把主键生成策略交给持久化引擎,默认就是自增
(3)createTime,updateTime等字段在各个实体出现,去除冗余
当然第一反应是让所有实体继承同一个父类,在父类里面加入这两个字段,确实如此,但在实际操作中发现,JPA不会去识别实体父类中的字段,如果这个字段不能为空,保存时自动报错。(我的理解是这样做保证实体的纯洁,父类中可以加入特殊字段或者通用方法用于业务,而不会影响实体对数据表字段的体现),当然JPA也提供了解决方案,在父类加入MappedSuperclass注解,父类中的字段就会被JPA当初对应的表字段。
(4)实体中需要放入与数据表无关的辅助字段
首先这肯定是不专业的,但却是偷懒的好办法,所有实体或者是有MappedSuperclass注解的实体父类中的字段,都会被JPA当成是表字段,如果实体与真实表字段不符,进行数据操作的时候回直接报错。JPA提供了Transient注解,在非表字段的属性上增加该注解,JPA会将其忽略。
(5)更丰富的表字段需求
JPA提供了Column注解,查看这个注解的内部应该是很好了解注解意图的