hibernate系列之四
数据库中表之间的关系:
一对一、一对多、多对多
一对多的建表原则:在多的一方创建外键指向一的一方的主键;
多对多的建表原则:创建一个中间表,中间表中至少有两个字段作为外键分别指向多对多双方的主键;
一对一建表原则:唯一外键对应:假设一对一中的任意一方为多,在多的一方创建外键指向一的一方的主键,将外键设置为唯一
主键对应:一方的主键作为另一方的主键;
在hibernate中采用java对象关系描述数据表之间的关系:
一对多的映射关系的实现案例:
客户实体类:在hibernate系列一中已经实现点击连接查看:https://www.cnblogs.com/wang-xuan/p/9195795.html
同时在客户实体类中添加属性:
//一个客户对应多个联系人
private Set<LinkMan> linkMans = new HashSet<LinkMan>();
public Set<LinkMan> getLinkMans() {
return linkMans;
}
public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
}
实现联系人实体类LinkMan:
package com.itwx.hibernate.pojo; public class LinkMan { private Long lkm_id;
private String lkm_name;
private String lkm_gender;
private String lkm_phone;
private String lkm_mobile;
private String lkm_email;
private String lkm_qq;
private String lkm_position;
private String lkm_memo; private Customer customer; public Long getLkm_id() {
return lkm_id;
} public void setLkm_id(Long lkm_id) {
this.lkm_id = lkm_id;
} public String getLkm_name() {
return lkm_name;
} public void setLkm_name(String lkm_name) {
this.lkm_name = lkm_name;
} public String getLkm_gender() {
return lkm_gender;
} public void setLkm_gender(String lkm_gender) {
this.lkm_gender = lkm_gender;
} public String getLkm_phone() {
return lkm_phone;
} public void setLkm_phone(String lkm_phone) {
this.lkm_phone = lkm_phone;
} public String getLkm_mobile() {
return lkm_mobile;
} public void setLkm_mobile(String lkm_mobile) {
this.lkm_mobile = lkm_mobile;
} public String getLkm_email() {
return lkm_email;
} public void setLkm_email(String lkm_email) {
this.lkm_email = lkm_email;
} public String getLkm_qq() {
return lkm_qq;
} public void setLkm_qq(String lkm_qq) {
this.lkm_qq = lkm_qq;
} public String getLkm_position() {
return lkm_position;
} public void setLkm_position(String lkm_position) {
this.lkm_position = lkm_position;
} public String getLkm_memo() {
return lkm_memo;
} public void setLkm_memo(String lkm_memo) {
this.lkm_memo = lkm_memo;
} public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
} }
配置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="com.itwx.hibernate.pojo.LinkMan" table="linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native" />
</id>
<property name="lkm_name" column="lkm_name" />
<property name="lkm_gender" column="lkm_gender" />
<property name="lkm_phone" column="lkm_phone" />
<property name="lkm_mobile" column="lkm_mobile" />
<property name="lkm_email" column="lkm_email" />
<property name="lkm_qq" column="lkm_qq" />
<property name="lkm_position" column="lkm_position" />
<!-- 配置关联对象 -->
<!--
many-to-one:代表多对一:
name属性:在实体类中的属性:一的一方的对象的名称;
class属性:一的一方的类的全路径
column:表中的外键,在一的一方中配置的外键;
-->
<many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
column="lkm_cust_id" />
</class>
</hibernate-mapping>
核心配置文件hibernate.cfg.xml
<!-- 配置加载映射文件:全路径-->
<mapping resource="com/itwx/hibernate/pojo/Customer.hbm.xml"/>
<mapping resource="com/itwx/hibernate/pojo/LinkMan.hbm.xml"/>
Customer.hbm.xml配置文件添加一对多的关系映射配置
<!-- 配置多一之间的映射关系 -->
<!--
set标签:name属性:在实体类中的属性,指多的一方的集合的属性名称
key标签:column:多的一方的外键的名称
one-to-many标签:class属性:多的一方的类的全路径
-->
<set name="linkMans">
<key column="lkm_cust_id" />
<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
</set>
测试类中进行测试一对多的关系映射
@Test
public void test4() {
// 获取当前与线程绑定的session
Session session = HibernateUtils.getCurrentSession();
// 开启事务
Transaction transaction = session.beginTransaction();
// 创建关系对象
Customer customer = new Customer();// 此处可以使用带参构造方法
customer.setCust_name("张三");
customer.setCust_source("产品"); LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("周芷若");
linkMan1.setLkm_phone("1223445");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("张无忌");
linkMan2.setLkm_gender("男");
// 建立关系
/**
* 首先获取到set集合对象,然后才能进行添加元素; 所以先调用getXXX()方法获取对象,然后add
*/
// 客户关联联系人
customer.getLinkMans().add(linkMan1);
customer.getLinkMans().add(linkMan2);
// 联系人关联客户
linkMan1.setCustomer(customer);
linkMan2.setCustomer(customer);
// 执行操作
session.save(linkMan1);
session.save(linkMan2);
session.save(customer);
// 提交事务
transaction.commit();
//执行结果
/**
* Hibernate: insert into linkman (lkm_name, lkm_gender, lkm_phone,
* lkm_mobile, lkm_email, lkm_qq, lkm_position, lkm_cust_id) values (?,
* ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into linkman (lkm_name,
* lkm_gender, lkm_phone, lkm_mobile, lkm_email, lkm_qq, lkm_position,
* lkm_cust_id) values (?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into
* customer (cust_name, cust_source, cust_industry, cust_level,
* cust_phone, cust_mobile) values (?, ?, ?, ?, ?, ?) Hibernate: update
* linkman set lkm_name=?, lkm_gender=?, lkm_phone=?, lkm_mobile=?,
* lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=? where lkm_id=?
* Hibernate: update linkman set lkm_name=?, lkm_gender=?, lkm_phone=?,
* lkm_mobile=?, lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=?
* where lkm_id=? Hibernate: update linkman set lkm_cust_id=? where
* lkm_id=? Hibernate: update linkman set lkm_cust_id=? where lkm_id=?
*/
}
级联操作:
指在主控方执行保存、更新和删除操作时,其关联(被控方)也执行相同操作。在映射文件中通过对cascade属性的设置来控制是否对关联对象采用级联操作,级联操作对各种关联关系都是有效的;
级联具有方向性:在保存一的一方级联多的一方和在多的一方可以级联一的一方;
在映射文件中配置cascade=“save-update”;
级联删除和级联保存、更新:谁是主控方,则可以在映射文件中配置cascade=“delete、save-update”,也可以同时配置;
级联删除:在set标签中配置cascade=“delete”或者在mony-to-one中配置cascade属性;
<many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
column="lkm_cust_id" cascade="save-update" />
或者
<set name="linkMans" cascade="delete,save-update" >
<key column="lkm_cust_id" />
<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
</set>
防止SQL语句冗余:双向维护关系,持久态对象可以自动更新数据库,更新客户的时候会修改一次外键,更新联系人的时候会修改一次外键,所以会产生SQL语句冗余;
解决方案:一方放弃外键的维护,通常交给多的一方去维护,所以一的一方就需要放弃维护,即需要配置inverse=“true”;
<set name="linkMans" cascade="delete,save-update" inverse="true">
<key column="lkm_cust_id" />
<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
</set>
hibernate系列之四的更多相关文章
- Hibernate 系列 学习笔记 目录 (持续更新...)
前言: 最近也在学习Hibernate,遇到的问题差不多都解决了,顺便把学习过程遇到的问题和查找的资料文档都整理了一下分享出来,也算是能帮助更多的朋友们了. 最开始使用的是经典的MyEclipse,后 ...
- Hibernate 系列 01 - 框架技术 (介绍Hibernate框架的发展由来)
引导目录: Hibernate 系列教程 目录 本篇导航: 为什么学习框架技术 框架的概念 主流框架的介绍 1.为什么学习框架技术 如何制作一份看上去具有专业水准的PPT文档呢?一个简单的方法就是使用 ...
- Hibernate 系列 02 - Hibernate介绍及其环境搭建
引导目录: Hibernate 系列教程 目录 昨晚喝多了,下午刚清醒,继续搞Hibernate.走起. 觉得还行的话,记得点赞哈,给我这个渣渣点学习的动力.有错误的话也请指出,省的我在错误上走了不归 ...
- Hibernate 系列 03 - 使用Hibernate完成持久化操作
引导目录: Hibernate 系列教程 目录 康姆昂,北鼻,来此狗.动次打次,Hibernate继续走起. 目录: 使用Hibernate实现按主键查询 使用Hibernate实现数据库的增.删.改 ...
- Hibernate 系列 04 - Hibernate 配置相关的类
引导目录: Hibernate 系列教程 目录 前言: 通过上一篇的增删改查小练习之后,咱们大概已经掌握了Hibernate的基本用法. 我们发现,在调用Hibernate API的过程中,虽然Hib ...
- Hibernate 系列 05 - Session 类
引导目录: Hibernate 系列教程 目录 前言: Session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库的存取都与Session息息相关. 就如同在编写JDBC时需要关 ...
- Hibernate 系列 06 - 对象在JVM中的生命周期
引导目录: Hibernate 系列教程 目录 Java对象通过new命令进行创建,Java虚拟机(Java Virtual Machine,JVM)会为新的Java对象在内存中开辟一个新空间以存放次 ...
- Hibernate 系列 07 - Hibernate中Java对象的三种状态
引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...
- Hibernate 系列 08 - 对象识别机制
目录导读: Hibernate 系列 学习笔记 目录 本篇目录: 为了区别不同的对象,有两种识别方法: 1. 内存地址识别(“==”号识别) 2. equals()和hashCode()识别 1. 以 ...
随机推荐
- HDU 3829——Cat VS Dog——————【最大独立集】
Cat VS Dog Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit S ...
- avalon教程-简介
avalon是什么? avalon是一个MVVM框架, Modle-模型层,即为js中从后台接口中取出的数据,例如一个对象或者对象数组,并对这些数据进行一定的格式化.常见的返回数据是这样的{id : ...
- WCF:无法满足对安全令牌的请求,因为身份验证失败。
服务端和客户端如果有认证的话的这样: <wsHttpBinding> <binding name="WSHttpBinding_IService1" closeT ...
- kafka的分区分配策略
用过 Kafka 的同学应该都知道,每个 Topic 一般会有很多个 partitions.为了使得我们能够及时消费消息,我们也可能会启动多个 Consumer 去消费,而每个 Consumer 又会 ...
- 进一步了解this和super
知乎上看到一问题很好,拿了与大家分享,原地址:https://www.zhihu.com/question/31548104. 问: JAVA 中this 和super与覆写冲突的问题? 实例一: 输 ...
- Centos 6.5_64bit 下安装 Zabbix server 3.0监控主机的加入
安装Zabbix server 3.0客户端之前需要先关闭selinux和打开10050和10051端口 关闭selinux 1 vi /etc/selinux/config 2 ...
- vim复制粘贴到系统剪贴板
一般来讲,如果你没有在.vimrc中配置过相关的信息的话,可以考虑下面的方法.系统环境 Ubuntu 14.04 LTS. 安装与使用 首先需要安装一个vim-gtk 命令$sudo apt-get ...
- 探索性数据分析EDA综述
目录 1. 数据探索的步骤和准备 2. 缺失值处理 为什么需要处理缺失值 Why data has missing values? 缺失值处理的技术 3. 异常值检测和处理 What is an ou ...
- hadoop中使用的Unsafe.java
今天查看hadoop源代码, 发现有个Unsafe.java 稍微总结下 优势 1 减少线程调度开销, Unsafe.java 通过采用非堵塞原子方式来减少线程调度开销 2 传统线程通信 ...
- pycharm中常用设置
当安装时检查版本过低 首先 pip --help 进入帮助,找到 复制,然后 pip install --disable-pip-version-check 要安装的包 这样就会跳过版本检测. 在py ...