总结
- 懒加载FetchType.LAZY实际是在session中挂一个代理对象来实现的,测试没有session中将导致报错。
- 如果用@Transactional来注解测试,上面问题可以解决但将引入新的问题:事务回滚。非测试情况下@Transactional默认当异常或错误出现时回滚,但在单元测试中@Transactional不管什么情况一律回滚(以免单元测试导致污染数据库)。此时可以搬到实际Controller中进行学习测试,或者单元测试中所有类都调用findAll()再打断点去看是否符合你的预想。
- 乐观锁所import的version是:import javax.persistence.Version
- …
@Entity
说明这个class是实体类,并且使用默认的orm规则,即class名对应数据库表中表名,class字段名即表中的字段名。
name为可选,缺省类名即表名。
必须与@Id注解 结合使用,否则 No identifier specified for entity:
@Entity(name = “tbl_user”)
或者
@Entity
@Table(name = “tbl_user”)
@MappedSuperclass
告诉JPA这是个不受不受管理的实体类,而是会由其他类进行扩展。
@MappedSuperClass
public class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Override
public boolean equals(Object obj) {
...}
@Override
public int hashCode() {
...}
}
@Entity
public class Address extends AbstractEntity {
private String street, city, country;
}
@Table
属性:
- name:表示该主键生成策略的名称,它被引用在@GeneratedValue中设置的generator 值中。
- table:表示表生成策略所持久化的表名。
- pkColumnName:该主键生成策略所对应键值的名称。
- pkColumnValue:该生成策略所对应的主键。
- valueColumnName:该主键当前所生成的值,它的值将会随着每次创建累加。
- allocationSize 表示每次主键值增加的大小, 默认值为 50。
- UniqueConstraint:用来指定建表时需要建唯一约束的列
@Entity
@Table(name="EMPLOYEE",
uniqueConstraints={
@UniqueConstraint(columnNames={
"EMP_ID", "EMP_NAME"})}
)
public class Employee {
... }
columnNames:定义一个字符串数组,指定要建唯一约束的列名。
name来指定和哪个数据表对应,表名优先级:@Table > @Entity。
@Table注解还有两个选项 catalog 和 schema 用于设置表所属的数据库目录或模式,通常为数据库名。
@Column
可以标注在属性前或getter方法前,建议使用属性标注。
属性 | 功能 |
---|---|
unique | 表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中@UniqueConstraint。 |
nullable | 表示该字段是否可以为null值,默认为true。 |
insertable | 表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。 |
updatable | 表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。 |
columnDefinition(大多数情况,几乎不用) | 表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。(也就是说,如果DB中表已经建好,该属性没有必要使用。) |
table | 表示当映射多个表时,指定表的表中的字段。默认值为主表的表名。 |
length | 表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。 |
precision和scale | precision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。 |
Example: 字段值为只读的,不允许插入和修改。通常用于主键和外键
@Column(name = "id", insertable = false, updatable = false)
private Integer id;
@Id
用于声明一个实体类的属性映射为数据库的主键列。该属性通常置于属性声明语句之前,可与声明语句同行,也可写在单独行上。
@Id标注也可置于属性的getter方法之前。
属性:
- generate():主键值的获取类型。
- generator():TableGenerator的名字(当generate=GeneratorType.TABLE才需要指定该属性)。
@GeneratedValue:用于标注主键的生成策略,通过strategy 属性指定,JPA通用策略生成器
- AUTO: JPA自动选择合适的策略,是默认选项(如果不写的话)。
- IDENTITY:采用数据库ID自增长的方式来自增主键字段,Oracle 不支持这种方式。
- SEQUENCE:通过序列产生主键,通过@SequenceGenerator 注解指定序列名,MySql不支持这种方式 。
- TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。
@GenericGenerator:自定义主键生成策略
@GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid.hex")
@TableGenerator:
- name:表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。
- table:表示表生成策略所持久化的表名,例如,这里表使用的是数据库中的“fendo_generator”。
- catalog和schema:指定表所在的目录名或是数据库名。
- pkColumnName:该主键生成策略所对应键值的名称。例如在“fendo_generator”中将“seq_name”作为主键对应值得名称,也就是这个主键所对应的名字。如上“seq_name”为"fendo",那么它所对应的值为"1"。
- valueColumnName:该主键当前所生成的值,它的值将会随着每次创建累加。例如,在“fendo_generator”中将“seq_id”作为主键的值 。
- pkColumnValue:该生成策略生成主键所对应的名字。例如在“fendo_generator”表中,将“seq_name”的值为“fendos”。
- initialValue:表示主键初识值,默认为0。
- allocationSize:表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
- uniqueconstraint:与@Table标记中的用法类似。
CREATE TABLE `fendo_generator` (
`seq_id` int(11) NOT NULL,
`seq_name` varchar(255) NOT NULL,
PRIMARY KEY (`seq_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
对应的代码注解:
@GeneratedValue(strategy=GenerationType.TABLE,generator="table_gen")
@TableGenerator(
name = "table_gen", //name对应@GeneratedValue中generator 引用的名字
table="fendo_generator", //对应数据库表中的名字,表键-字段名
pkColumnName="seq_name", //指定主键的名字
pkColumnValue="fendos", //指定下次插入主键时使用默认的值,表键-字段值
valueColumnName="seq_id", //该主键当前所生成的值,它的值将会随着每次创建累加,表值-字段名
initialValue = 1, //初始化值
allocationSize=1 //累加值,每次累加1
)
@SequenceGenerator:Mysql不支持
@SecondaryTable
一个entity class可以映射到多表,SecondaryTable用来定义单个从表的名字,主键名字等属性。
属性:
- name: 表名。
- catalog: 对应关系数据库中的catalog。
- schema:对应关系数据库中的schema。
- pkJoin: 定义一个PrimaryKeyJoinColumn数组,指定从表的主键列。
- UniqueConstraints: 定义一个UniqueConstraint数组,指定需要建唯一约束的列。
@SecondaryTables
一个entity class可以映射到多个表,可以用 @SecondaryTables 注解多个@SeconddaryTable
@Table(name = "CUSTOMER")
@SecondaryTables( value = {
@SecondaryTable(name = "CUST_NAME", pkJoin = {
@PrimaryKeyJoinColumn(name = "STMO_ID",
referencedColumnName = "id") }),
@SecondaryTable(