使用Hibernate Annotations 维护多对多关系的心得
在HibernateAnnotations中通过@ManyToMany注解可定义多对多关联。同时,也需要通过注解@JoinTable描述关联表和关联条件。对于双向关联,其中一端必须定义为owner,另一端必须定义为inverse(在对关联表进行更性操作时这一端将被忽略)。被关联端不必也不能描述物理映射,只需要一个简单的mappedBy参数,该参数包含了主体端的属性名,这样就绑定了双方的关系。
??????上周六去电影院圆了儿时的梦想,看了变形金刚,超棒的一部片子 ^_^。那么就以剧院和观众为例讲解吧。
如何制作PO
1)找到CUBE--需要引入哪些类:
import ?java.util.ArrayList;
import ?java.util.List;
import ?javax.persistence.CascadeType;
import ?javax.persistence.Entity;
import ?javax.persistence.FetchType;
import ?javax.persistence.JoinColumn;
import ?javax.persistence.JoinTable;
import ?javax.persistence.ManyToMany;
import ?javax.persistence.Table;
import ?org.hibernate.annotations.Cache;
import ?org.hibernate.annotations.CacheConcurrencyStrategy;
2)找到汽车人--主体端:
/**?*//**
?*?Theater
?*?@author?allen
?*/
@SuppressWarnings("serial")
@Entity
@Table(name?=?"THEATER")
@Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)
public?class?Theater?implements?Serializable?
{
????
????@ManyToMany(
????????????targetEntity=net.allen.domain.Audience.class,
????????????cascade?=
{CascadeType.PERSIST,CascadeType.MERGE},
????????????fetch=FetchType.LAZY
????)
????@JoinTable(
????????????name="THEATER_AUDIENCE",
????????????joinColumns=
{@JoinColumn(name="THEATER_ID")},
????????????inverseJoinColumns=
{@JoinColumn(name="AUDIENCE_ID")}
????)
????@Cache(usage?=?CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
????private?List<Audience>?audiences?=?new?ArrayList<Audience>();
????/**?*//**
?????*?@return?Returns?the?audiences.
?????*/
????public?List<Audience>?getAudiences()?
{
????????return?audiences;
????}
????/**?*//**
?????*?@param?audiences?The?audiences?to?set.
?????*/
????public?void?setAudiences(List<Audience>?audiences)?
{
????????this.audiences?=?audiences;
????}????
}功能说明:
@ManyToMany注解
???? targetEntity属性:指向被关联端的实体对象
???? cascade属性:与Hibernate xml配置文件中的意思一样,这里选用两种方式
????????????CascadeType.PERSIST:若实体是处于被管理状态,或当persist()方法被调用时,触发级联创建(create)操作。???
????????????CascadeType.MERGE:若实体是处于被管理状态,或当merge)方法被调用时,触发级联合并(merge)操作。
?????????????其它属性如CascadeType.REMOVE、CascadeType.REFRESH、CascadeType.ALL等属性可参考Hibernate Annotations Reference。
???? fetch属性:关联关系获取方式
?????????????? LAZY(默认值)在第一次访问关联对象时才触发相应的查询操作。
?????????????? 另一个值EAGER是通过out join select直接获取关联对象
????
@JoinTable注解
???? name属性:指定关联表名 若不指定Hibernate可以根据既定的规则自动生成(具体规则见reference)
???? joinColumns属性:指定主体端的外键
???? inverseJoinColumns属性:指定被关联端的外键
@Cache注解
???? usage属性:给定了缓存的并发策略
3)找到霸天虎--被关联端:
/**?*//**
?*?Audience
?*?@author?allen
?*/
@SuppressWarnings("serial")
@Entity
@Table(name?=?"AUDIENCE")
@Cache(usage?=?CacheConcurrencyStrategy.READ_WRITE)
public?class?Audience?implements?Serializable?
{
????
????@ManyToMany(
???????????cascade=
{CascadeType.PERSIST,CascadeType.MERGE},
???????????mappedBy="audiences"
????)
????/**?*//**?所在的剧院?*/
????private?List<Theater>?theaters?=?new?ArrayList<Theater>();
????/**?*//**
?????*?@return?Returns?the?theaters.
?????*/
????public?List<Theater>?getTheaters()?
{
????????return?theaters;
????}
????/**?*//**
?????*?@param?theaters?The?theaters?to?set.
?????*/
????public?void?setTheaters(List<Theater>?theaters)?
{
????????this.theaters?=?theaters;
????}
}功能说明:
@ManyToMany注解
???? mappedBy属性:指定了主体端的属性名,用以绑定双方的关系???
汽车人,变形!--如何操作
/**?*//**
?????*?select?transformers?wathers?from?ShowMax?Theater
?????*/
????protected?void?selectWathers()?
{
????????//1)?get?current?theater
????????Theater?theater?=?findTheaterById("showMax");
????????//2)?clear?theater's?audiences
????????theater.getAudiences().clear();
????????//3)?get?audiences?who?want?to?watch?transformers
????????List<Audience>?audiences?=?findAudiencesByMovie("transformers");
????????for?(Audience?a:?audiences)?
{
????????????//4)?mountain?relations
????????????a.getTheaters().add(theater);
????????????theater.getAudiences().add(a);
????????}
????????//5)?do?save?main?entity
????????doSaveEntity(theater);
????}tips:注意第二步的操作。
好了,大功告成!说回电影,红蜘蛛这小子跑得还挺快,期待续集!
PS:找到一份中文的hiberante?annotations reference,与大家共享。点击下载