目錄
此篇博客所用到的數據庫表及其關係:
關於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();