hibernate中多对多关系的维护

目录

此篇博客所用到的数据库表及其关系:

hibernate中多对多关系的维护方式:

如何向表中加入user和good的关系:

 删除某个对象所收藏的商品:


此篇博客所用到的数据库表及其关系:

hibernate中多对多关系的维护

关于users表:

userid : 用户的id

username : 用户的姓名

关于goods表:

goodsid : 商品的id

goodsname : 商品的名字

关于shoucang表:

uid : 外键。对应users表中的userid

gid : 外键。对应goods表中的goodsid

sid : 此收藏关系的id 

同一个用户可以收藏多个商品,而同一个商品可以被多个用户收藏,这种多对多关系,要使用中间表进行维护。如下图:

hibernate中多对多关系的维护

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