posts - 40,  comments - 187,  trackbacks - 0

说明
        在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,与大家共享。点击下载


                                                                              THE END
                

posted on 2007-08-02 15:19 小立飞刀 阅读(14336) 评论(8)  编辑  收藏 所属分类: Hibernate

FeedBack:
# re: 使用Hibernate Annotations 维护多对多关系的心得
2007-08-03 13:10 | 中东
写的很好,关于多对多关系,转换为二个一对多关,有什么看法?  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得
2007-08-03 13:13 | 中东
为什么在主从方都定义了“cascade={CascadeType.PERSIST,CascadeType.MERGE}”??有什么不同吗?在从方可以不定义吗?  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得
2007-08-14 17:11 | 小雪飞刀
@中东
因为是多对多的关系,所以双方都要定义。
另外多对一时,主从方也都需要设置cascade属性,举个例子:

主控方:Business
@ManyToOne(cascade ={CascadeType.PERSIST,CascadeType.MERGE})
/** 对应的流程模板 */
private BusinessFlow flow;

受控方:BusinessFlow
@OneToMany(mappedBy="flow",cascade ={CascadeType.ALL},fetch=FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
/** 业务流程可以应用于的业务列表 */
private List<Business> business = new ArrayList<Business>();

当在Business类中配置成cascade = { CascadeType.PERSIST, CascadeType.MERGE } 时,更新和删除两个级联时,可以正常删除;
当在Business类中配置成cascade = { CascadeType.ALL } or cascade={} 时,无法删除。
更新时也类似于这种情况。

关于以上所说,您可以亲自试验一下,看看其中的区别。然后请您告诉我实验结果。:)
毕竟是“实践出真知”嘛!  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得
2007-10-26 10:39 | 中华信鸽
学习了。  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得[未登录]
2009-02-12 13:27 | kevin
不錯~學習了~  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得
2009-07-01 18:05 | 11
good thank you!  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得
2009-09-17 16:12 | popoer
写得很清楚,谢谢!  回复  更多评论
  
# re: 使用Hibernate Annotations 维护多对多关系的心得[未登录]
2013-11-11 10:28 | jack
学习了  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
<2007年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

生存或毁灭,这是个必答之问题:是否应默默的忍受坎苛命运之无情打击,还是应与深如大海之无涯苦难奋然为敌,并将其克服。此二抉择,究竟是哪个较崇高?

常用链接

留言簿(12)

随笔分类(43)

相册

收藏夹(7)

朋友的博客

电子资料

搜索

  •  

积分与排名

  • 积分 - 288961
  • 排名 - 172

最新评论

阅读排行榜

评论排行榜