Integer getId() {}
@Temporal(TemporalType.TIME)
public java.util.Date getDatetime() {};
@Transient
被注解成 @Transient 的 getter 方法或属性,将不会被持久化(自己测试,只有放在getter方法内才起作用)
@Basic
所有没有定义注解的属性,等价于在其上面添加了 @Basic注解可以声明属性的获取策略 ( fetch strategy )
fetch:抓取策略,延时加载与立即加载,optional:指定在生成数据库结构时字段是否允许为 null.
@Temporal
在核心的 Java API 中并没有定义时间精度 ( temporal precision )。因此处理时间类型数据时,你还需要定义将其存储在数据库中所预期的精度。
在数据库中,表示时间类型的数据有 DATE,TIME,和 TIMESTAMP 三种精度 ( 即单纯的日期,时间,或者两者兼备 )。 可使用 @Temporal 注解来调整精度。
映射实体Bean的关联关系
使用 @OneToOne 注解可以建立实体Bean
之间的一对一关系。一对一关系有3种情况。
• 关联的实体都共享同样的主键。
@Entity
public class Body {
public Long getId() { return id; }
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {
return heart;
@Entity
public class Heart {
public Long getId() { ...}
通过@PrimaryKeyJoinColumn 注解定义了一对一的关联关系。
其中一个实体通过外键关联到另一个实体的主键。注:一对一,则外键必须为唯一约束。
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
通过@JoinColumn注解定义一对一的关联关系。如果没有@JoinColumn注解,则系统自动处理,在主表中将创建连接列,列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。上例为 passport_id, 因为Customer 中关联属性为 passport, Passport 的主键为 id.
通过关联表来保存两个实体之间的关联关系。注:一对一,则关联表每个外键都必须是唯一约束。
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports",
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumn(name="passport_fk")
public Passport getPassport() {
@Entity public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
Customer 通过 CustomerPassports 关联表和 Passport 关联。该关联表通过 passport_fk 外键指向 Passport 表,该信心定义为 inverseJoinColumns 的属性值。 通过 customer_fk 外键指向 Customer 表,该信息定义为 joinColumns 属性值。
使用 @ManyToOne 注解定义多对一关系。
@Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;
其中@JoinColumn 注解是可选的,关键字段默认值和一对一关联的情况相似。列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。本例中为company_id,因为关联的属性是company, Company的主键为 id.
@ManyToOne 注解有个targetEntity属性,该参数定义了目标实体名。通常不需要定义,大部分情况为默认值。但下面这种情况则需要 targetEntity 定义(使用接口作为返回值,而不是常用的实体)。
@Entity()
public class Flight implements Serializable {
@ManyToOne(cascade= {CascadeType.PERSIST,CascadeType.MERGE},targetEntity= CompanyImpl.class)
@JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;
public interface Company {
多对一也可以通过关联表的方式来映射,通过@JoinTable
注解可定义关联表。该关联表包含指回实体的外键(通过@JoinTable.joinColumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColumns).
@Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinTable(name="Flight_Company",
joinColumns = @JoinColumn(name="FLIGHT_ID"),
inverseJoinColumns = @JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;
非主键多对一关联:
A表:sn B表:cp_sn
A表配置:
1 private List<B> sns;
3 @OneToMany(mappedBy = "a", fetch = FetchType.LAZY)
4 public List<B> getSns() {
5 return sns;
8 public void setSns(List<B> sns) {
9 this.sns = sns;
B表配置:
1 private A a;
3
@ManyToOne(fetch = FetchType.LAZY)
4 @JoinColumn(name = "CP_SN", referencedColumnName="sn", insertable = false, updatable = false)
5 public A getA() {
6 return a;
name = "CP_SN" -- 本表中的字段
referencedColumnName="sn" -- 关联表的字段
@OneToMany 注解可定义一对多关联。一对多关联可以是双向的。
规范中多对一端几乎总是双向关联中的主体(owner)端,而一对多的关联注解为 @OneToMany(mappedBy=)
@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
Troop 通过troop属性和Soldier建立了一对多的双向关联。在 mappedBy 端不必也不能定义任何物理映射。
@Entity
public class Customer implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
public Set<Ticket> getTickets() {
@Entity
public class Ticket implements Serializable {
... //no bidir
一般通过连接表来实现这种关联,可以通过@JoinColumn注解来描述这种单向关联关系。上例 Customer 通过 CUST_ID 列和 Ticket 建立了单向关联关系。
通过关联表来处理单向关联
@Entity
public class Trainer {
@OneToMany
@JoinTable(
name="TrainedMonkeys",
joinColumns = @JoinColumn( name="trainer_id"),
inverseJoinColumns = @JoinColumn( name="monkey_id")
public Set<Monkey> getTrainedMonkeys() {
@Entity
public class Monkey {
... //no bidir
通过关联表来处理单向一对多关系是首选,这种关联通过 @JoinTable 注解来进行描述。上例子中 Trainer 通过TrainedMonkeys表和Monkey建立了单向关联关系。其中外键trainer_id关联到Trainer(joinColumns)而外键monkey_id关联到Monkey(inverseJoinColumns).
默认处理机制
通过连接表来建立单向一对多关联不需要描述任何物理映射,表名由一下3个部分组成,主表(owner table)表名 + 下划线 + 从表(the other side table)表名。指向主表的外键名:主表表名+下划线+主表主键列名 指向从表的外键定义为唯一约束,用来表示一对多的关联关系。
@Entity
public class Trainer {
@OneToMany
public Set<Tiger> getTrainedTigers() {
@Entity
public class Tiger {
... //no bidir
上述例子中 Trainer 和 Tiger 通过 Trainer_Tiger 连接表建立单向关联关系。其中外键 trainer_id 关联到 Trainer表,而外键 trainedTigers_id 关联到 Tiger 表。
通过@ManyToMany 注解定义多对多关系,同时通过 @JoinTable 注解描述关联表和关联条件。其中一端定义为 owner, 另一段定义为 inverse(对关联表进行更新操作,这段被忽略)。
// 维护端注解
@ManyToMany (cascade = CascadeType.REFRESH)
@JoinTable (//关联表
name = "student_teacher" , //关联表名
inverseJoinColumns = @JoinColumn (name = "teacher_id" ),//被维护端外键
joinColumns = @JoinColumn (name = "student_id" ))//维护端外键被维护端注解
@ManyToMany(cascade = CascadeType.REFRESH,
mappedBy = "teachers",//通过维护端的属性关联
fetch = FetchType.LAZY)
// 关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息;
// 关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败 .
关联表名:主表表名 + 下划线 + 从表表名;关联表到主表的外键:主表表名 + 下划线 + 主表中主键列名;关联表到从表的外键名:主表中用于关联的属性名+ 下划线 + 从表的主键列名。
用 cascading 实现传播持久化(Transitive persistence)
cascade 属性接受值为 CascadeType 数组,其类型如下:
• CascadeType.PERSIST: cascades the persist (create) operation to associated entities persist() is called or if the entity is managed 如果一个实体是受管状态,或者当 persist() 函数被调用时,触发级联创建(create)操作。
CascadeType.MERGE:
cascades the merge operation to associated entities if merge() is
called or if the entity is managed 如果一个实体是受管状态,或者当
merge()
函数被调用时,触发级联合并(merge)操作。
CascadeType.REMOVE:
cascades the remove operation to associated entities if delete() is
called 当
delete()
函数被调用时,触发级联删除(remove)操作。
CascadeType.REFRESH:
cascades the refresh operation to associated entities if refresh() is
called 当
refresh()
函数被调用时,出发级联更新(refresh)操作。
CascadeType.ALL:
all of the above 以上全部
其他属性:
@Enumerated
@javax.persistence.Enumerated(EnumType.STRING)
value:EnumType.STRING,EnumType.ORDINAL
枚举类型成员属性映射,EnumType.STRING指定属性映射为字符串,EnumType.ORDINAL指定属性映射为数据序
@javax.persistence.Lob
用于标注字段类型为Clob和Blob类型
Clob(Character Large Ojects)类型是长字符串类型,实体的类型可为char[]、Character[]、或者String类型
Blob(Binary Large Objects)类型是字节类型,实体的类型可为byte[]、Byte[]、或者实现了Serializable接口的类。
通常使用惰性加载的方式, @Basic(fetch=FetchType.LAZY)
@SecondaryTable
@javax.persistence.SecondaryTable
将一个实体映射到多个数据库表中
@Entity
@SecondaryTables({
@SecondaryTable(name = "Address"),
@SecondaryTable(name = "Comments")
public class Forum implements Serializable {
@Column(table = "Address", length = 100)
private String street;
@Column(table = "Address", nullable = false)
private String city;
@Column(table = "Address")
private String conutry;
@Column(table = "Comments")
private String title;
@Column(table = "Comments")
private String Comments;
@Column(table = "Comments")
table属性的值指定字段存储的表名称 没有用 @Column 注解改变属性默认的字段将会存在于 Forum 表
@Index
给某一字段加索引
@Table(name = "tab_developer", indexes = {@Index(columnList = "username")})
根据注解,将会给username字段加上索引