hibernate里面的一对多关系映射里面,一般都是指一张主表和一张从表。
在表示“多”的一方数据表里面增加一个外键,来指向表示“一”的那方数据表,“一”也就是我们所说的主表,而“多”就是我们所说的从表,接下来我们可以举个例子来进行说明:
(我所用的数据库是mysql)
这是一张顾客表(customer)的结构
这是一张订单表(order)的结构
在两张表里面,customer的cid和order里面的cid是一致的,因此我们可以将订单表里面的cid设置一个外键,将它和顾客表里面的cid进行绑定;
通过相应的绑定,当用户删除掉一条客户信息的时候,订单表里面的cid会自动变换为null值,在这里我设置了删除时为set null操作而不是cascade操作,因此不会出现级联删除(后边会讲如何进行级联删除操作)
然后便是顾客类的代码:
package com.sise.lh.model; import java.util.HashSet; import java.util.Set; public class Customer { public int cid; public String cname; public Set<Order> order=new HashSet<Order>(); public Set<Order> getOrder() { return order; } public void setOrder(Set<Order> order) { this.order = order; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public int getCid() { return cid; } public void setCid(int cid) { this.cid = cid; } } 复制代码
然后便是订单order类:
package com.sise.lh.model; public class Order { public String address; public int cid; public int id; public int price; public Customer customer; public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public String getAddress() { return address; } public int getCid() { return cid; } public int getId() { return id; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } public void setAddress(String address) { this.address = address; } public void setCid(int cid) { this.cid = cid; } public void setId(int id) { this.id = id; } } 复制代码
光有这些类的描述还不够,还需要有相应的配置才可以:
这里是顾客表的配置:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.sise.lh.model.Customer" table="customer" catalog="test"> <id name="cid" column="cid"> <generator class="identity"></generator> </id> <property name="cname" type="java.lang.String"> <column name="cname" length="35" not-null="true" /> </property> <!-- save-update:设置级联关系,这样的话可以支持顺时态和持久态的对象同时保存 --> <!-- delete:设置级联关系进行删除 --> <!-- delete-orphan:设置级联关系进行孤儿删除 --> <set name="order" > <key column="cid"/> <one-to-many class="com.sise.lh.model.Order"/> </set> </class> </hibernate-mapping> 复制代码
这里是订单表的配置:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.sise.lh.model.Order" table="order" catalog="test"> <id name="id" column="id"> <generator class="identity"></generator> </id> <property name="address" type="java.lang.String"> <column name="address" length="35" not-null="true" /> </property> <property name="price" type="java.lang.Integer"> <column name="price" length="6" not-null="true" /> </property> <many-to-one name="customer" class="com.sise.lh.model.Customer" column="cid"> </many-to-one> </class> </hibernate-mapping> 复制代码
接下来是进行相应的测试部分:
@Test public void testManyToOne() { Transaction transaction= session.beginTransaction(); Customer c=(Customer) session.get(Customer.class, 13); Order o1=new Order(); o1.setAddress("深圳01"); o1.setPrice(144); Order o2=new Order(); o2.setAddress("南京01"); o2.setPrice(188); c.getOrder().add(o1); c.getOrder().add(o2); session.save(c); session.save(o1); session.save(o2); transaction.commit(); } 复制代码
成功之后的截图如下:
由于我们之前在设置外键的时候只是设置为了set null操作,因此当用户表里面的信息被删除之后,订单表里面的信息还不会立马就被删除,只是有所绑定的cid字段会被设置为null而已。
接下来便是删除操作部分:
@Test public void testDelete() { Transaction transaction=session.beginTransaction(); Customer c=(Customer) session.get(Customer.class, 13); session.delete(c); transaction.commit(); } 复制代码
果然和开始预期所想的结果一样,那么这个时候,又是否有办法在不接触到数据库的前提下,通过hibernate的配置来进行订单表里面整条数据的级联删除呢?
答案是有的,可以通过修改xml里面cascade属性进行操作,也就是这顾客类customer.hbm.xml的配置:
<set name="order" cascade="delete"> <key column="cid"/> <one-to-many class="com.sise.lh.model.Order"/> </set> 复制代码
只需要在上边添加cascade=”delete”属性即可实现
关于顾客表里面的cascade状态我参考了另外一篇博客里面的内容
此时我又进行了相应的操作,再次插入两条数据:
接下来再是一次执行删除操作
@Test public void testDelete() { Transaction transaction=session.beginTransaction(); Customer c=(Customer) session.get(Customer.class, 18); session.delete(c); transaction.commit(); } 复制代码
通过cascade=”delete”属性的绑定,这次数据被完全删除了