Hibernate笔记 5:实体关联关系
Eijux(讨论 | 贡献)2022年6月19日 (日) 15:43的版本 (创建页面,内容为“category:Hibernate == 关于 == 数据库中多表之间存在着三种关联关系(一对一、一对多、多对多),用于描述实体数据之间的关系,而这种关系也可以通过对象进行描述。 实体关系 # 一对一: #: <syntaxhighlight lang="Java" highlight=""> class A{ B b; } class B{ A a; } </syntaxhighlight> #* 开发中并不常用; # '''一对多''': #: <syntaxhighlight lang="Java" highlight=""> class A{ Se…”)
关于
数据库中多表之间存在着三种关联关系(一对一、一对多、多对多),用于描述实体数据之间的关系,而这种关系也可以通过对象进行描述。
实体关系
- 一对一:
class A{ B b; } class B{ A a; }
- 开发中并不常用;
- 一对多:
class A{ Set<B> bs; } class B{ A a; }
- 多对多:
class A{ Set<B> bs; } class B{ Set<A> as; }
一对多
“一对多”关系分为“一端”与“多端”。 以下,讨论一对一关系。
以“客户”(Customer)与“联系人”(LinkMan)为例: 1、一个客户可以有多个联系人; 2、一个联系人只能被指定给一个客户;
实体类:
- Customer:
public class Customer { private Long cust_id; private String cust_name; private String cust_industry; private String cust_level; private String cust_phone; // 客户类中维护联系人对象集合 private Set<LinkMan> linkMans = new HashSet<LinkMan>(); // getter、setter ... }
- LinkMan:
public class LinkMan { private Long lkm_id; private String 1km_name; private String lkm_phone; // 联系人类中维护客户对象 private Customer customer; // getter、setter ... }
非级联操作(复杂写法)
创建映射:
- Customer.hbm.xml:
... <hibernate-mapping> <class name="cn.itcast.hibernate.domain.Customer" table="cst_customer"> <id name= "cust_id"> <generator class="native"/> </id> <property name="cust_name" length="32"/> <property name="cust_industry" column= "cust_industry"/> <property name="cust_level" column= "cust_level"/> <property name="cust_phone" column= "cust_phone"/> <!-- 配置关联对象集合 --> <set name="linkMans"> <key column="lkm_cust_id"></key> <one-to-many class= "cn.itcast.hibernate.domain.LinkMan"/> </set> </class> </hibernate-mapping>
- LinkMan.hbm.xml:
... <hibernate-mapping> <class name="cn.itcast.hibernate.domain.LinkMan" table="cst_linkMan"> <id name= "lkm_id"> <generator class="native"/> </id> <property name="1km_name" length="32"/> <property name="1km_name" column= "1km_name"/> <property name="lkm_phone" column= "lkm_phone"/> <!-- 配置关联对象 --> <many-to-one name="customer" class="cn.itcast.hibernate.domain.Customer" column="lkm_cust_id"/> </class> </hibernate-mapping>
- 注意:“lkm_cust_id”为“cst_linkMan”表的外键(参照于“cst_customer”表)。【下同】
- 注意:需要加载两个映射文件到核心配置文件。
测试代码:
@Test // 保存:一个客户和他的两个联系人 public void demol() { Session session = HibernateUtils.openSession(); Transaction tx = session.beginTransaction(); // 创建客户 Customer customer = new Customer(); customer.setCust_name("中国移动"); // 创建联系人 LinkMan linkManl = new LinkMan(); linkManl.setLkm_name("老张"); LinkMan linkMan2 = new LinkMan(); linkMan2.setLkm_name("老李"); // 建立关联关系 customer.getLinkMans().add(linkManl); customer.getLinkMans().add(linkMan2); linkManl.setCustomer(customer); linkMan2.setCustomer(customer); // 保存 session.save(customer); session.save(linkManl); session.save(linkManl); tx.commit(); }
如上代码,建立的关系是双向的:
- 建立关联时:Customer 对象关联了 LinkMan 对象,同时 LinkMan 对象也关联了 Customer 对象;
- 保存对象时:对 Customer 对象进行了保存,也分别对 LinkMan 对象进行了保存;
从控制台打印出的 SQL 语句可以看出:
- 执行了三次 insert(对 customer、linkManl、linkMan2)
- 执行了两次 update(对 linkManl、linkMan2 更新外键)
Hibernate: insert into cst_customer (cust_name, cust_industry, cust_level, cust_phone) values (?, ?, ?, ?) Hibernate: insert into cst_linkMan (1km_name, lkm_phone, lkm_cust_id) values (?, ?, ?, ?) Hibernate: insert into cst_linkMan (1km_name, lkm_phone, lkm_cust_id) values (?, ?, ?, ?) Hibernate: update cst_linkMan set lkm_cust_id where lkm_id=? Hibernate: update cst_linkMan set lkm_cust_id where lkm_id=?
非级联操作,是一种复杂的写法,在于