使用Hibernate Annotations 维护多对多关系

2014-02-06 12:41
使用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)找到汽车人--主体端:

@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>();

    
    public List<Audience> getAudiences() {
        return audiences;
     }

    
    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)找到霸天虎--被关联端:



@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>();

    
    public List<Theater> getTheaters() {
        return theaters;
     }

    
    public void setTheaters(List<Theater> theaters) {
        this.theaters = theaters;
     }
 }
功能说明:
@ManyToMany注解
          mappedBy属性:指定了主体端的属性名,用以绑定双方的关系     


汽车人,变形!--如何操作

     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:注意第二步的操作。

 

以上内容转自http://www.blogjava.net/allen-zhe/archive/2007/08/02/133991.html 留作备用