hibernate中多對多關係的維護

My_name_is_ZwZ發表於2018-10-17

目錄

此篇部落格所用到的資料庫表及其關係:

hibernate中多對多關係的維護方式:

如何向表中加入user和good的關係:

 刪除某個物件所收藏的商品:


此篇部落格所用到的資料庫表及其關係:

關於users表:

userid : 使用者的id

username : 使用者的姓名

關於goods表:

goodsid : 商品的id

goodsname : 商品的名字

關於shoucang表:

uid : 外來鍵。對應users表中的userid

gid : 外來鍵。對應goods表中的goodsid

sid : 此收藏關係的id 

同一個使用者可以收藏多個商品,而同一個商品可以被多個使用者收藏,這種多對多關係,要使用中間表進行維護。如下圖:

hibernate中多對多關係的維護方式:

在“多”的兩方都配置set集合。

首先在users表所對應的Userinfo類中配置用於儲存Goods物件的set集合屬性:

public class Userinfo {
	private int userid;
	private String username;
	private Set<Goods> goods = new HashSet<Goods>();
	public Set<Goods> getGoods() {
		return goods;
	}
	public void setGoods(Set<Goods> goods) {
		this.goods = goods;
	}
	public int getUserid() {
		return userid;
	}
	public void setUserid(int userid) {
		this.userid = userid;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
}

在 其對應的.hbm.xml檔案中進行宣告:

<hibernate-mapping>
	<class name="com.pojo.Userinfo" table="users">
		<id column="userid" name="userid">
			<generator class="assigned"></generator>		
		</id>
		<property column="username" name="username"></property>
		<!-- cascade="all" -->
		<set name="goods" table="shoucang">
			<key column="uid"></key>
			<many-to-many class="com.pojo.Goods" column="gid"></many-to-many>
		</set>	
	</class>
</hibernate-mapping>

 關於<set>標籤:

name屬性:用於填寫此商品在Userinfo類中的屬性名(set集合的名字);

table屬性:所對應的用來維護“多對多”關係的中間表的名字;

<key>子標籤中的column屬性:用來指明中間表中與Userinfo類所對應的外來鍵名字;

<many-to-many>子標籤的class屬性:指明商品所對應的pojo類的位置;

<many-to-many>子標籤的column屬性:指明中間表中Goods類所對應的外來鍵名字;

然後在goods表所對應的Goods類中配置用於儲存Goods物件的set集合屬性:

public class Goods {
	private int goodsid;
	private String goodsname;
	private Set<Userinfo> userinfos = new HashSet<Userinfo>();

	public Set<Userinfo> getUserinfos() {
		return userinfos;
	}
	public void setUserinfos(Set<Userinfo> userinfos) {
		this.userinfos = userinfos;
	}
	public int getGoodsid() {
		return goodsid;
	}
	public void setGoodsid(int goodsid) {
		this.goodsid = goodsid;
	}
	public String getGoodsname() {
		return goodsname;
	}
	public void setGoodsname(String goodsname) {
		this.goodsname = goodsname;
	}
}

在其所對應的.hbm.xml配置檔案中宣告:

<hibernate-mapping>
	<class name="com.pojo.Goods" table="goods">
		<id column="goodsid" name="goodsid">
			<generator class="assigned"></generator>
		</id>
		<property column="goodsname" name="goodsname"></property>

		<set name="userinfos" table="shoucang" >
			<key column="gid"></key>
			<many-to-many class="com.pojo.Userinfo" column="uid"></many-to-many>
		</set>
	</class>
</hibernate-mapping>

以上就是關於hibernate中"多對多"關係出現之後如何維護和配置。其中中間表不用配pojo,因為它是以集合的形式體現。

如何向表中加入user和good的關係:

public static void main(String[] args) {
	Configuration configuration = new Configuration().configure();
	SessionFactory factory = configuration.buildSessionFactory();
	Session session = factory.openSession();

	Transaction transaction = session.beginTransaction();

	Userinfo userinfo = new Userinfo();
	userinfo.setUserid(6);
	userinfo.setUsername("Mr.shi");
	Goods goods = new Goods();
	goods.setGoodsid(11);
	goods.setGoodsname("一加手機5");

	//userinfo.getGoods().add(goods);//操作中間表
	goods.getUserinfos().add(userinfo);
		
	session.save(goods);
	session.save(userinfo);

	transaction.commit();
	session.close();
}

 執行之後,控制檯列印輸出的sql語句:

Hibernate: insert into goods (goodsname, goodsid) values (?, ?)
Hibernate: insert into users (username, userid) values (?, ?)
Hibernate: insert into shoucang (gid, uid) values (?, ?)

並且在資料庫中成功的將資料加入。

將資料庫中剛剛加入的資料刪除,並將上邊的程式碼做以下部分改動:

userinfo.getGoods().add(goods);//操作中間表
//goods.getUserinfos().add(userinfo);

則控制檯列印輸出的結果如下:

Hibernate: insert into goods (goodsname, goodsid) values (?, ?)
Hibernate: insert into users (username, userid) values (?, ?)
Hibernate: insert into shoucang (uid, gid) values (?, ?)

可見在兩個物件的集合屬性中,誰新增誰這個順序不會影響sql語句的執行順序。而真正影響sql語句執行順序的是:

session.save(goods);
session.save(userinfo);

 我們根據上面的例子可以看出,無論是使用下面這兩條語句的哪一條,都可以用來維護我們的“多對多”關係:

goods.getUserinfos().add(userinfo);
userinfo.getGoods().add(goods);

 但是要注意的是<set>集合中的inverse屬性,這個屬性預設的是:false,但是如果把它設定成了true之後,就以為著這個集合所對應的物件不能再去維護多對多這種關係。

例如:

將userinfo.hbm.xml中的<set>集合中的inverse屬性改成true:

<set name="goods" table="shoucang" inverse="true">

而在測試方法中使用:

userinfo.getGoods().add(goods);

此時,控制檯列印輸出的sql語句如下:

Hibernate: insert into goods (goodsname, goodsid) values (?, ?)
Hibernate: insert into users (username, userid) values (?, ?)

 並沒有向shoucang表中加入資料,而且資料庫中的中間表中也沒有資料。可見,userinfo已經不可以維護“多對多”的關係。此外<set>還有一個級聯屬性cascade,它可以連帶操作與此表有所聯絡的表。不常用到,在此處不多加贅述

 刪除某個物件所收藏的商品:

userinfo.getGoods().clear();

 

相關文章