JPA(Java Persistence API), 是EJB3.0的组成部分, 它显著简化了EJB持续性并提供了一个对象关系映射方法, 该方法使开发者可以采用声明方式定义如何通过一种标准的可移植方式将Java对象映射到关系数据库表.
Hibernate从3.2开始, 就开始兼容JPA, 可以通过注释的方式, 代替原有的xml映射方式.
引入Hibernate annotation后, 我们需要进行如下准备, 下载依赖的类库.
Hibernate core 3.2+
Hibernate annotation
JPA
【示例】
首先先来看一个使用Annotation后的实体配置:
Company.java @Entity @Table(name = "fin_company") public class Company { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Column(name = "c_name", length = 50, nullable = false) private String name; @Column(columnDefinition = "text") private String description; @OneToMany(mappedBy = "company", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) private List<Employee> employees; public Company() { this.employees = new ArrayList<Employee>(); } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } } Employee.java @Entity @Table(name = "fin_employee") public class Employee { private long id; private String name; private Company company; @Id @GeneratedValue(strategy = GenerationType.AUTO) public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "company_id") public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } @Transient public String getCompanyName() { return this.company.getName(); } }
在上面的Java类中, 我们可以看到, 所有以@开头的标注都是JPA标注, JPA标注可以写在属性名前, 也可以写在属性的get方法前. 接下来逐一介绍这些基本标注的意思.
【注释说明】
@Entity
将普通的Java类指定为实体, 默认情况下, 所有Java类为非持续化类@Table
指定映射数据表名, 默认情况下以类名作为数据表名, 如非特殊指定, 可以省略该注释项
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
指定该实体的主键字段, 并且主键的增长方式有JAP选择最适合于基础数据库的主键生成器
@Column(name = "c_name", length = 50, nullable = false)
private String name;
name: 默认情况下, JPA会根据属性名生成数据表字段名, 使用name属性进行特殊指定
length: 字段长度
nullable: 字段是否允许为空@Column(columnDefinition = "text")
private String description;
columnDefinition: 设置为在针对列生成DDL时希望JPA使用的SQL片断.
此设置与数据库绑定, 即切换数据库的时候可能需要进行修改.
@OneToMany(mappedBy = "company", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private List<Employee> employees;
@OneToMany: 声明一对多关联映射, 即一个公司对应多个雇员
mappedBy: 如果关联是单项的, 该数据表维护关系字段
如双向关联(当前情况), 在一方设置mappedBy属性, 对应多方关联一方的属性名称.
让我们来看下一方的设置:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id")
public Company getCompany() {
return company;
}
在多方Employee方, 关联的属性名为company, 所以在一方设置的mappedBy值为company
@JoinColumn: 定义外键的列名
默认情况下, 无需配置, JPA默认以属性名+"_id"方式自动生成该外键列.
如需特殊指定, 设置name属性
fetch: 取得当前对象的时候, 是否加载关联对象
LAZY: 延迟加载策略, 获取当前对象时, 不加载级联对象, 会在首次load或get级联对象的时候加载
EAGER: 迫切获取加载策略, 获取当前对象时, 立即加载级联对象
cascade: 操作层叠关联对象策略
ALL: 针对拥有实体执行的任何持续性操作均层叠到关联的目标
MERGE: 如果合并了拥有实体, 则将 merge 层叠到关联的目标
PERSIST: 如果持久保存拥有实体, 则将 persist 层叠到关联的目标
REFRESH: 如果刷新了拥有实体, 则 refresh 为关联的层叠目标
REMOVE: 如果删除了拥有实体,则还删除关联的目标
当前例子设置为remove, 即在删除company对象时, 会级联删除所关联的employee对象
如不进行remove设置, 在删除操作时, 系统会报外键约束异常
@Transient默认情况下, JPA 持续性提供程序假设实体的所有字段均为持久字段
即所有属性都会映射到数据表字段
如需在实体增加方法, 但又不想进行映射, 使用此注释
【结尾】