hibernate中一对多的javabean文件的编写与映射文件的编写
下面例子为一个客户对应多个联系人:
客户的javabean文件
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/*
* 一个客户对应多个联系人
*/
public class Customer implements Serializable{
private static final long serialVersionUID = 1L;
private Long cust_id; //客户编号(主键)
private String cust_name;//客户名称(公司名称)
private String cust_source;//客户信息来源
private String cust_industry;//客户所属行业
private String cust_level;//客户级别
private String cust_phone;//固定电话
private String cust_mobile;//移动电话
//多个联系人
private Set<Linkman> linkmans=new HashSet<>();
public Long getCust_id() {
return cust_id;
}
public void setCust_id(Long cust_id) {
this.cust_id = cust_id;
}
public String getCust_name() {
return cust_name;
}
public void setCust_name(String cust_name) {
this.cust_name = cust_name;
}
public String getCust_source() {
return cust_source;
}
public void setCust_source(String cust_source) {
this.cust_source = cust_source;
}
public String getCust_industry() {
return cust_industry;
}
public void setCust_industry(String cust_industry) {
this.cust_industry = cust_industry;
}
public String getCust_level() {
return cust_level;
}
public void setCust_level(String cust_level) {
this.cust_level = cust_level;
}
public String getCust_phone() {
return cust_phone;
}
public void setCust_phone(String cust_phone) {
this.cust_phone = cust_phone;
}
public String getCust_mobile() {
return cust_mobile;
}
public void setCust_mobile(String cust_mobile) {
this.cust_mobile = cust_mobile;
}
public Set<Linkman> getLinkmans() {
return linkmans;
}
public void setLinkmans(Set<Linkman> linkmans) {
this.linkmans = linkmans;
}
}
客户的映射文件:
<?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>
<!--name 实体类的全路径,table对应的表名 -->
<class name="com.haha.domain.Customer" table="cst_customer">
<!-- id标签
作用:用于映射主键
属性:
name:指定的是属性名称。也就是get/set方法后面的部分,并且首字母要转小写。
column:指定的是数据库表的字段名称
-->
<id name="cust_id">
<!-- generator标签:
作用:配置主键的生成策略。
属性:
class:指定生成方式的取值。
取值之一:native。使用本地数据库的自动增长能力。
mysql数据库的自动增长能力是让某一列自动+1。但是不是所有数据库都支持这种方式。
-->
<generator class="native"></generator>
</id>
<!-- property标签:
作用:映射其他字段
属性:
name:指定属性的名称。和id标签的name属性含义一致
column:指定数据库表的字段名称
如果name与column字段相同,则column可以省略
-->
<property name="cust_name"/>
<property name="cust_source"/>
<property name="cust_industry"/>
<property name="cust_level"/>
<property name="cust_phone"/>
<property name="cust_mobile"/>
</class>
<!-- 一方的配置,配置多方 name参考实体类中的属性字段 column参考数据库表中的字段
cascade设置级联保存,级联删除,inverse放弃主键的维护权,它们都是有方向的,可以设置在不同的方,
cascade="save-update,delete" inverse="true"
-->
<set name="linkmans" >
<!-- column参考数据库表中的字段 cid为外键的名称 -->
<key column="cid"/>
<!--class为多的那一方的全路径 -->
<one-to-many class="com.haha.domain.Linkman"/>
</set>
</hibernate-mapping>
联系人的javabean文件:
import java.io.Serializable;
public class Linkman implements Serializable{
private int lid;
private String lname;
private String lsex;
//对应的一的一方
private Customer customer;
public int getLid() {
return lid;
}
public void setLid(int lid) {
this.lid = lid;
}
public String getLname() {
return lname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getLsex() {
return lsex;
}
public void setLsex(String lsex) {
this.lsex = lsex;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
联系人的映射文件
<?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="com.haha.domain.Linkman" table="cst_linkman">
<id name="lid">
<generator class="native"></generator>
</id>
<property name="lname"/>
<property name="lsex"/>
<!-- name表示javabean文件中对应一方的属性,column对应表中的外键 -->
<many-to-one name="customer" class="com.haha.domain.Customer" column="cid" />
</class>
</hibernate-mapping>
下面是我自己理解级联保存,一方放弃外键维护的例子
/**
* 添加数据,级联添加,一的一方放弃外键维护
* <set name="linkmans" cascade="save-update" inverse="true">
*/
@Test
public void run1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer c1=new Customer();
c1.setCust_name("包子");
Linkman l1=new Linkman();
l1.setLname("小敏");
Linkman l2=new Linkman();
l2.setLname("小哈");
//一方主动关联,级联保存
c1.getLinkmans().add(l1);
c1.getLinkmans().add(l2);
//多方主动关联一方,外键设置值,
//如果多方不主动关联一方,外键为空
l1.setCustomer(c1);
l2.setCustomer(c1);
session.save(c1);
tx.commit();
}
级联删除
/**
* 级联删除,删除一方会把多方也删除
* <set name="linkmans" cascade="save-update,delete" inverse="true">
*/
@Test
public void run2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer = session.get(Customer.class, 1L);
session.delete(customer);
tx.commit();
}
级联修改外键
/**
* 修改多方的外键
*/
@Test
public void run3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Customer customer = session.get(Customer.class, 3L);
Linkman linkman = session.get(Linkman.class, 4);
//查询到双方,然后修改linkman对应的customer利用快照机制修改多方中对应的外键
linkman.setCustomer(customer);
session.update(linkman);
tx.commit();
}