【Hibernate】hibernate实体关系映射——单边的多对多关系
//劉夢冰發(fā)表于2015-6-19
單邊的多對多關(guān)系
多對一、一對多的關(guān)系只需要兩個(gè)表即可,使用子表的外鍵與主表的主鍵連接就能存儲主從關(guān)系。而對多對多的關(guān)系至少需要三個(gè)表,其中兩個(gè)表保存兩個(gè)實(shí)體類,另一個(gè)表保存關(guān)系。
下面以一個(gè)論壇文章管理為例來深入學(xué)習(xí):
現(xiàn)在論壇的每個(gè)帖子都挺有相關(guān)的標(biāo)簽,一個(gè)帖子可以屬于多個(gè)標(biāo)簽,因此它們之間是多對多的關(guān)系。本例就使用多對多來處理標(biāo)簽與帖子之間的業(yè)務(wù)邏輯。
標(biāo)簽類Tag中沒有Post屬性,但是帖子類Post中有Tag屬性,它們之間是單邊的多對多的關(guān)系。Tag、Post都是多方,它們的多對多關(guān)系保存在第三個(gè)表(中間表tb_tag_post)中。
Tag標(biāo)簽實(shí)體類只有一個(gè)id主鍵以及String類型的name普通屬性。
Tag.java
package com.lmb.hibernate.bean;import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;@Entity @Table(name="tb_tag") public class Tag {@Id@GeneratedValue(strategy=GenerationType.AUTO)private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}Post帖子實(shí)體類中有id主鍵、標(biāo)題、內(nèi)容等普通屬性,還有一個(gè)Set類型的多對多集合屬性tags。從java代碼上來看,一對多屬性與多對多屬性沒什么區(qū)別,都是set或者list類型的集合屬性。但是,它們的hibernate配置是完全不一樣的,存儲機(jī)制也是完全不一樣的。
Post.java
package com.lmb.hibernate.bean;import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table;@Entity @Table(name="tb_post") public class Post {@Id@GeneratedValue(strategy=GenerationType.AUTO)private Integer id;private String title;@ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST})@JoinTable( //中間關(guān)系表配置name="tb_tag_post",joinColumns= @JoinColumn(name="post id",referencedColumnName="id"),inverseJoinColumns=@JoinColumn(name="tag_id",referencedColumnName="id"))private Set<Tag> tags=new HashSet<Tag>();@Column(columnDefinition="text")private String content;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public Set<Tag> getTags() {return tags;}public void setTags(Set<Tag> tags) {this.tags = tags;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}}注意:內(nèi)容content使用@Column的columnDefination指定在數(shù)據(jù)庫中使用text大文本類型。而在多對多屬性tags上,使用@ManyToMany指定該列為多對多屬性,fetch配置加載方式, cascade配置級聯(lián)保存屬性。多對多屬性必須使用@JoinTable指定中間表的配置,其中name指定表名,joinColumns指定該表(也就是Post對應(yīng)的表)與中間表的對應(yīng)關(guān)系,inverseJoinColumns指定另一端(也就是Tag對應(yīng)的表)與中間表的對應(yīng)關(guān)系。@joinColumn的name屬性post_id、tag_id都指中間表中的列,referencedColumnName指的是實(shí)體類的關(guān)聯(lián)列,默認(rèn)為主鍵。如果為主鍵,referencedColumnName可省略。
將兩個(gè)實(shí)體類配置到hibernate配置文件中去;
hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration><session-factory><property name="dialect">org.hibernate.dialect.MySQLDialect</property><property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property><property name="connection.username">lmb</property><property name="connection.password">lmb</property><property name="connection.driver_class">com.mysql.jdbc.Driver</property><mapping class="com.lmb.hibernate.bean.Post" /><mapping class="com.lmb.hibernate.bean.Tag" /></session-factory></hibernate-configuration> 超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的【Hibernate】hibernate实体关系映射——单边的多对多关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【HibernateHibernate实
- 下一篇: 【Hibernate】Hibernate