EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
来源:互联网 发布:mac按键精灵使用教程 编辑:程序博客网 时间:2024/06/02 06:39
EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展(2)
原文地址:http://hi.baidu.com/fengfan_2008/blog/item/34a9fd25d22b0f20d5074264.html
一对一关联可能是双向的.在双向关联中,有且仅有一端是作为主体(owner)端存在的:主体端负责维护联接列(即更新).
对于不需要维护这种关系的从表则通过mappedBy属性进行声明.
mappedBy的值指向主体的关联属性.
在上面这个例子中,mappedBy的值为 passport.
最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.
如果在主体没有声明@JoinColumn,系统自动进行处理:
在主表(owner table)中将创建联接列,
列名为:主体的关联属性名+下划线+被关联端的主键列名.
在上面这个例子中是passport_id,
因为Customer中关联属性名为passport,
Passport的主键是id.
The third possibility (using an association table) is very
exotic.
第三种方式也许是最另类的(通过关联表).
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports"
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumns(name="passport_fk")
)
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}
Customer通过名为 CustomerPassports的关联表和Passport关联; 该关联表拥有名为passport_fk的外键列,该外键指向Passport表,该信息定义为inverseJoinColumn的属性值,而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是可选的,关联字段默认值和一对一(one to one)关联的情况相似,
列名为:主体的关联属性名+下划线+被关联端的主键列名.
在这个例子中是company_id,因为关联的属性是company,Company的主键是id.
@ManyToOne注解有一个名为targetEntity的参数,
该参数定义了目标实体名.通常不需要定义该参数,
因为在大部分情况下默认值(表示关联关系的属性类型)就可以很好的满足要求了.
不过下面这种情况下这个参数就显得有意义了:使用接口作为返回值而不是常见的实体.
@Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, role="bold">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 = @JoinColumns(name="COMP_ID")
)
public Company getCompany() {
return company;
}
...
}
你可以对 Collection ,List(指有序列表, 而不是索引列表),Map和Set这几种类型进行映射.
EJB3规范定义了怎么样使用@javax.persistence.OrderBy
注解来对有序列表进行映射:
该注解接受的参数格式:用逗号隔开的(目标实体)属性名及排序指令,如firstname asc, age desc,如果该参数为空,则默认以id对该集合进行排序.
如果某个集合在数据库中对应一个关联表(association table)的话,你不能在这个集合属性上面使用@OrderBy注解.
对于这种情况的处理方法,请参考.
EJB3 允许你利用目标实体的一个属性作为Map的key,
这个属性可以用@MapKey(name="myProperty")来声明.
如果使用@MapKey注解的时候不提供属性名,
系统默认使用目标实体的主键.
map的key使用和属性相同的列:不需要为map key定义专用的列,因为map key实际上就表达了一个目标属性.
注意一旦加载,key不再和属性保持同步,也就是说,如果你改变了该属性的值,在你的Java模型中的key不会自动更新
(请参考).
很多人被<map>和@MapKey弄糊涂了.
其他它们有两点区别.@MapKey目前还有一些限制,详情请查看论坛或者我们的JIRA缺陷系统.
注意一旦加载,key不再和属性保持同步,也就是说,如果你改变了该属性的值,在你的Java模型中的key不会自动更新.
(Hibernate 3中Map支持的方式在当前的发布版中还未得到支持). Hibernate将集合分以下几类.
语义
Java实现类
注解
Bag 语义
java.util.List, java.util.Collection
@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany
带主键的Bag语义(没有普通Bag语义的限制)
java.util.List, java.util.Collection
(@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany) 和 @CollectionId
List 语义
java.util.List
(@org.hibernate.annotations.CollectionOfElements 或@OneToMany 或 @ManyToMany)
以及 @org.hibernate.annotations.IndexColumn
Set 语义
java.util.Set
@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany
Map 语义
java.util.Map
(@org.hibernate.annotations.CollectionOfElements 或@OneToMany 或 @ManyToMany)
以及(空或@org.hibernate.annotations.MapKey/MapKeyManyToMany(支持真正的map), 或@javax.persistence.MapKey
从上面可以明确地看到,没有@org.hibernate.annotations.IndexColumn
注解的java.util.List集合将被看作bag类.
EJB3规范不支持原始类型,核心类型,嵌入式对象的集合.但是Hibernate对此提供了支持
(详情参考 ).
@Entity public class City {
@OneToMany(mappedBy="city")
@OrderBy("streetName")
public List<Street> getStreets() {
return streets;
}
...
}
@Entity public class Street {
public String getStreetName() {
return streetName;
}
@ManyToOne
public City getCity() {
return city;
}
...
}
@Entity
public class Software {
@OneToMany(mappedBy="software")
@MapKey(name="codeName")
public Map<String, Version> getVersions() {
return versions;
}
...
}
@Entity
@Table(name="tbl_version")
public class Version {
public String getCodeName() {...}
@ManyToOne
public Software getSoftware() { ... }
...
}
上面这个例子中,City中包括了以streetName排序的Street的集合.而Software中包括了以codeName作为key和以Version作为值的Map.
除非集合为generic类型,否则你需要指定targetEntity.
这个注解属性接受的参数为目标实体的class.
在属性级使用 @OneToMany注解可定义一对多关联.一对多关联可以是双向关联.
在EJB3规范中多对一这端几乎总是双向关联中的主体(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端不必也不能再定义任何物理映射
对于一对多的双向映射,如果要一对多这一端维护关联关系,你需要删除mappedBy元素并将多对一这端的 @JoinColumn的insertable和updatable设置为false.
很明显,这种方案不会得到什么明显的优化,而且还会增加一些附加的UPDATE语句.
@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}
通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的,也是不推荐的.
我们强烈建议通过一个联接表(join table)来实现这种关联(下一节会对此进行解释).
可以通过@JoinColumn注解来描述这种单向关联关系.
@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
对于不需要维护这种关系的从表则通过mappedBy属性进行声明.
mappedBy的值指向主体的关联属性.
在上面这个例子中,mappedBy的值为 passport.
最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.
如果在主体没有声明@JoinColumn,系统自动进行处理:
在主表(owner table)中将创建联接列,
列名为:主体的关联属性名+下划线+被关联端的主键列名.
在上面这个例子中是passport_id,
因为Customer中关联属性名为passport,
Passport的主键是id.
The third possibility (using an association table) is very
exotic.
第三种方式也许是最另类的(通过关联表).
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports"
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumns(name="passport_fk")
)
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}
Customer通过名为 CustomerPassports的关联表和Passport关联; 该关联表拥有名为passport_fk的外键列,该外键指向Passport表,该信息定义为inverseJoinColumn的属性值,而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是可选的,关联字段默认值和一对一(one to one)关联的情况相似,
列名为:主体的关联属性名+下划线+被关联端的主键列名.
在这个例子中是company_id,因为关联的属性是company,Company的主键是id.
@ManyToOne注解有一个名为targetEntity的参数,
该参数定义了目标实体名.通常不需要定义该参数,
因为在大部分情况下默认值(表示关联关系的属性类型)就可以很好的满足要求了.
不过下面这种情况下这个参数就显得有意义了:使用接口作为返回值而不是常见的实体.
@Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, role="bold">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 = @JoinColumns(name="COMP_ID")
)
public Company getCompany() {
return company;
}
...
}
你可以对 Collection ,List(指有序列表, 而不是索引列表),Map和Set这几种类型进行映射.
EJB3规范定义了怎么样使用@javax.persistence.OrderBy
注解来对有序列表进行映射:
该注解接受的参数格式:用逗号隔开的(目标实体)属性名及排序指令,如firstname asc, age desc,如果该参数为空,则默认以id对该集合进行排序.
如果某个集合在数据库中对应一个关联表(association table)的话,你不能在这个集合属性上面使用@OrderBy注解.
对于这种情况的处理方法,请参考.
EJB3 允许你利用目标实体的一个属性作为Map的key,
这个属性可以用@MapKey(name="myProperty")来声明.
如果使用@MapKey注解的时候不提供属性名,
系统默认使用目标实体的主键.
map的key使用和属性相同的列:不需要为map key定义专用的列,因为map key实际上就表达了一个目标属性.
注意一旦加载,key不再和属性保持同步,也就是说,如果你改变了该属性的值,在你的Java模型中的key不会自动更新
(请参考).
很多人被<map>和@MapKey弄糊涂了.
其他它们有两点区别.@MapKey目前还有一些限制,详情请查看论坛或者我们的JIRA缺陷系统.
注意一旦加载,key不再和属性保持同步,也就是说,如果你改变了该属性的值,在你的Java模型中的key不会自动更新.
(Hibernate 3中Map支持的方式在当前的发布版中还未得到支持). Hibernate将集合分以下几类.
语义
Java实现类
注解
Bag 语义
java.util.List, java.util.Collection
@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany
带主键的Bag语义(没有普通Bag语义的限制)
java.util.List, java.util.Collection
(@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany) 和 @CollectionId
List 语义
java.util.List
(@org.hibernate.annotations.CollectionOfElements 或@OneToMany 或 @ManyToMany)
以及 @org.hibernate.annotations.IndexColumn
Set 语义
java.util.Set
@org.hibernate.annotations.CollectionOfElements 或
@OneToMany 或 @ManyToMany
Map 语义
java.util.Map
(@org.hibernate.annotations.CollectionOfElements 或@OneToMany 或 @ManyToMany)
以及(空或@org.hibernate.annotations.MapKey/MapKeyManyToMany(支持真正的map), 或@javax.persistence.MapKey
从上面可以明确地看到,没有@org.hibernate.annotations.IndexColumn
注解的java.util.List集合将被看作bag类.
EJB3规范不支持原始类型,核心类型,嵌入式对象的集合.但是Hibernate对此提供了支持
(详情参考 ).
@Entity public class City {
@OneToMany(mappedBy="city")
@OrderBy("streetName")
public List<Street> getStreets() {
return streets;
}
...
}
@Entity public class Street {
public String getStreetName() {
return streetName;
}
@ManyToOne
public City getCity() {
return city;
}
...
}
@Entity
public class Software {
@OneToMany(mappedBy="software")
@MapKey(name="codeName")
public Map<String, Version> getVersions() {
return versions;
}
...
}
@Entity
@Table(name="tbl_version")
public class Version {
public String getCodeName() {...}
@ManyToOne
public Software getSoftware() { ... }
...
}
上面这个例子中,City中包括了以streetName排序的Street的集合.而Software中包括了以codeName作为key和以Version作为值的Map.
除非集合为generic类型,否则你需要指定targetEntity.
这个注解属性接受的参数为目标实体的class.
在属性级使用 @OneToMany注解可定义一对多关联.一对多关联可以是双向关联.
在EJB3规范中多对一这端几乎总是双向关联中的主体(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端不必也不能再定义任何物理映射
对于一对多的双向映射,如果要一对多这一端维护关联关系,你需要删除mappedBy元素并将多对一这端的 @JoinColumn的insertable和updatable设置为false.
很明显,这种方案不会得到什么明显的优化,而且还会增加一些附加的UPDATE语句.
@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}
通过在被拥有的实体端(owned entity)增加一个外键列来实现一对多单向关联是很少见的,也是不推荐的.
我们强烈建议通过一个联接表(join table)来实现这种关联(下一节会对此进行解释).
可以通过@JoinColumn注解来描述这种单向关联关系.
@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
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- EJB3.0,JPA,Hibernate之间的关系
- hibernate反向工程生成带注解的实体(jpa)
- JPA实体的常用注解
- EJB3.0、JPA、Hibernate、ORM之间的关系
- 使用JPA 注解的Hibernate
- JPA注解的使用,用于实体类的注解
- JPA注解的使用,用于实体类的注解
- JPA注解的使用,用于实体类的注解
- JPA与EJB3的关系
- JPA与EJB3的关系
- JPA与EJB3的关系
- JPA与EJB3的关系
- JPA/Hibernate注解的主键策略
- 中小企业的云计算之路,到头来还是回到原点
- QueryCache
- sql server 隔离级别
- 假冒杀毒软件在Mac OSX上的感染过程
- 项目中碰见的错误(二) java socket接收中文乱码问题
- EJB3.0-JPA实体的注解规范以及Hibernate特有的扩展
- [转]Vim 的标签页功能
- ListView中的Button点击设置
- BomGroupDao
- C#时间比较
- 制作鼠标双击就可以运行的Jar文件
- Companies and the industries listed abov
- WinForm窗体之间参数传递
- ORACLE高效分页存储过程代码