以客户和联系人为例:客户是一,联系人是多
表的关系:将一方的主键在多方中设置为外键
第一步 创建两个实体类,客户和联系人,并在两个实体类之中互相表示关系
Customer实体类(一方)
package entity;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Integer cid;
private String custName;
/* * 一个客户有多个联系人 * hibernate要求使用set集合在一方中表示多方 */
private Set<LinkMan> linkMans = new HashSet<LinkMan>();
public Set<LinkMan> getLinkMans() {
return linkMans;
}
public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
}
LinkMan实体类(多方)
package entity;
public class LinkMan {
private Integer lid;
private String lkmName;
/* * 一个联系人只属于一个客户 */
private Customer customer;
public Integer getLid() {
return lid;
}
public void setLid(Integer lid) {
this.lid = lid;
}
public String getLkmName() {
return lkmName;
}
public void setLkmName(String lkmName) {
this.lkmName = lkmName;
}
}
第二步 配置每个实体类的映射关系,包括实体类与数据库中表的映射,以及一对多关系的配置
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- Class映射到表 -->
<class name="entity.Customer" table="t_customer">
<!-- 主键映射(重要) -->
<id name="cid" column="cid">
<!-- Native设置id为自增长 -->
<generator class="native"></generator>
</id>
<!-- 普通属性映射 -->
<property name="custName" column="custName"></property>
<!-- 一方配置多方,映射外键 -->
<!-- set标签表示多方 name属性: set集合名称 inverse属性: 是否放弃对关系的维护 true: 放弃关系的维护(在一对多时最好放弃一方的,应为一方维护一次就要为多方产生和数据相同都的sql update语句,影响性能) false: 不放弃关系的维护 (默认值) cascade属性: 级联操作。 操作一方,关联的另一方也做相同的操作,一般在<one-to-one>和<one-to-many>中设置级联 save-update: 级联保存和更新 delete: 级联删除 all: save-update+delete: 级联保存,更新,删除 -->
<set name="linkMans" inverse="true" cascade="delete">
<!-- hibernate机制:双向维护外键,一方和多方都配置外键 column属性:外键名称 -->
<key column="clid"></key>
<one-to-many class="entity.LinkMan"/>
</set>
</class>
</hibernate-mapping>
LinkMan.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entity.LinkMan" table="t_linkman">
<id name="lid" column="lid">
<generator class="native"></generator>
</id>
<property name="lkmName" column="lkmName"></property>
<!-- 多方中配置一方 -->
<many-to-one name="customer" class="entity.Customer" column="clid"></many-to-one>
</class>
</hibernate-mapping>
对于inverse属性:
一对多表的关系在于多的那个表里有一个外键。在这里就是说,联系人表里面有一个外键是指向客户表的,这个外键就是两个表的关系,我们说的维护这个关系就是维护这个外键。
在更新客户表时,如果一方不放弃维护关系,在一方表更新后,会主动去update多方表,修改其外键,所以就有了如下的update语句;如果一方放弃维护关系,则不会有这条update语句,即不会主动去修改多方表的外键:
Hibernate: update t_customer set custName=?,custLevel=?,custSource=?,custPhone=?,custMobile=? where cid=? Hibernate: update t_linkman set clid=null where clid=?
第三步 将映射文件添加到核心配置文件中,我是把对hibernate的配置放到了spring配置文件中。
bean.xml
<!-- 配置hibernate基本信息 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置映射文件 .hbm.xml -->
<property name="mappingResources">
<list>
<value>entity/Customer.hbm.xml</value>
<value>entity/LinkMan.hbm.xml</value>
</list>
</property>