Hibernate学习笔记③

数据库关系

多对多:通过第三张表来建立关系

第三张表至少包含两个字段作为外键且字段是其他两张表的主键

Hibernate一对多的操作

(1)一对多映射配置

    步骤:

  1. 首先创建两个存在一对多关系的实体类
  2. 两个实体类需要建立一对多的关系:在多的一方使用一的一方的对象表示所属一的类;在一的一方使用Set集合表示全部属于一的多的实体类;Hibernate中规定必须使用set集合来表示属于一的多的实体类,Set的特点是:无顺序、不重复;
  3. 建立两个实体类的映射表【配置文件】
public class Contacter {private Integer lid;private String lName;private String lPhone;private Client lClient;    //在多的一方使用一的一方的实体类建立关系public class Client {private Integer cid;private String cName;private String cLevel;//Hibernate要求在多的里面使用set表示,不使用list//Set是无序的,不可重复的集合private Set<Contacter> belongContecter = new HashSet<Contacter>();   //在多的一方使用Set集合包含属于一的一方的多的实体类,建立关系

配置文件【一对多中一的一方】

<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入XML dtd 约束 -->
<!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="tech.youngs.entity.Client" table="t_client"><id name="cid" column="cid"><generator class="native"></generator></id><property name="cName" column="cName"></property><property name="cLevel" column="cLevel"></property><!-- 使用set标签表示所有的多【联系人】 @param name 在实体类中表示多的set集合的属性名--><set name="belongContecter"><!-- 一对多建表 要有外键 hibernate规定双方都要配置外键 --><!-- @param column 外键的名称 --><key column="fk_cl"></key><!-- 使用one-to-many表示一对多关系中 一的那一方  --><!-- @param class 一对多的多的实体类的全路径 --><one-to-many class="tech.youngs.entity.Contacter"/></set></class>
</hibernate-mapping>

配置文件【一对多中多的一方】

 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入XML dtd 约束 -->
<!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="tech.youngs.entity.Contacter" table="t_contacter"><id name="lid" column="lid"><generator class="native"></generator></id><property name="lName" column="lName"></property><property name="lPhone" column="lPhone"></property><!-- 表示一对多 多所属的一 --><!-- @param name 在实体类中表示所属的一的实体类的属性名 --><!-- @param class 一对多 多所属的一的实体类的全路径 --><!-- @param column 外键的名称 与一的配置文件中定义的相同 --><many-to-one name="lClient" class="tech.youngs.entity.Client" column="fk_cl"></many-to-one></class>
</hibernate-mapping>

(2)一对多级联操作

包括级联保存和级联删除

  • 级联保存:创建一个客户及多个联系人
  • 级联删除:删除客户以及其联系人,传统的做法需要删除所有联系人后才能删除客户

级联保存第一种方式:

            //第一步 创建客户和联系人对象Client client = new Client();Contacter contacter = new Contacter();client.setcName("Baidu");client.setcLevel("vip");contacter.setlName("Lucy");contacter.setlPhone("15191082682");//第二步 体现出两个实体类的一对多关系//把联系人对象放到客户的Set集合里面去
            client.getBelongContecter().add(contacter);//把客户对象方法放到联系人中去
            contacter.setlClient(client);//第三步 保存到数据库中
            session.save(client);session.save(contacter);

级联保存第二种方法:

第一步,在客户实体类的映射配置代码中的<set>中添加cascade属性 cascade="save-update"

<set name="belongContecter" cascade="save-update"><!-- 一对多建表 要有外键 hibernate规定双方都要配置外键 --><!-- @param column 外键的名称 --><key column="fk_cl"></key><!-- 使用one-to-many表示一对多关系中 一的那一方  --><!-- @param class 一对多的多的实体类的全路径 --><one-to-many class="tech.youngs.entity.Contacter"/></set>

第二步 只需要将联系人放到客户里面就可以了,最终只保存客户就行了。

            //第二步 把联系人对象放到客户的Set集合里面去
            client.getBelongContecter().add(contacter);//第三步 保存到数据库中session.save(client);

级联删除操作

第一步:在一对多的一的映射配置文件中的<set>标签的cascade属性设置为delete即可

         cascade设置多属性,属性和属性之间用逗号隔开

第二步:直接删除即可

Client client = session.get(Client.class, 1);
session.delete(client);

Hibernate级联删除的SQL执行过程

Hibernate: updatet_contacter setfk_cl=null wherefk_cl=?
Hibernate: delete fromt_contacter wherelid=?
Hibernate: delete fromt_client wherecid=?

 一对多的修改

   业务需求 将A公司的联系人lucy调整到B公司的联系人

//根据id查出调出员工和调入部门Client client = session.get(Client.class, 1);Contacter contacter = session.get(Contacter.class, 2);//持久态实体类 直接修改客户就行了//持久态可以自动更新数据库client.getBelongContecter().add(contacter);contacter.setlClient(client);

注意,由于在一对多的映射文件中,外键由双方维护,在修改的时候会重复修改外键。

解决方案:在一对多的关系里,可以让一的一方放弃对外键的维护。

实现方法:在放弃外键维护的映射文件中进行配置,在set标签上使用inverse属性,设置为true,放弃关系维护。

<set name="belongContecter" cascade="save-update,delete" inverse="true">

 

Hibernate多对多的操作

多对多映射配置(重要,常用,复杂)

 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入XML dtd 约束 -->
<!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="tech.youngs.entity.User" table="t_user"><id name="uid" column="uid"><generator class="native"></generator></id><property name="username" column="username"></property><!-- 使用set标签表示所有的多【联系人】 @param name 在实体类中表示多的set集合的属性名@param table 第三张表的名称--><set name="roleSet" table="user_role" cascade="save-update"><!-- @param column 配置的是当前的映射文件在第三张表中的外键的名称 --><key column="user_id"></key><!-- 使用many-to-many表示多对多关系 --><!-- @param class 一对多的多的实体类的全路径 --><!-- @param colunmn 表示的是多对多另外的多的第三张表的外键多的名称 --><many-to-many class="tech.youngs.entity.Role" column="role_id"></many-to-many></set></class>
</hibernate-mapping>

 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入XML dtd 约束 -->
<!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="tech.youngs.entity.Role" table="t_role"><id name="rid" column="rid"><generator class="native"></generator></id><property name="roleName" column="roleName"></property><!-- 使用set标签表示所有的多【联系人】 @param name 在实体类中表示多的set集合的属性名--><set name="userSet" table="user_role"><!-- @param column 第三张表中这个实体类的外键的名称 --><key column="role_id"></key><!-- @param class 多对多的另一个多的实体类的全路径 --><many-to-many class="tech.youngs.entity.User" column="user_id"></many-to-many></set></class>
</hibernate-mapping>

同样的,两个实体类需要建立关系,通过Set集合来建立。

多对多的增加与一对多几乎相同。

多对多中一般不使用级联删除:

      因为级联删除会将删除条目的外键的条目一并删除,在实际开发中如果要删除某个用户的某个角色我们并不希望其将角色也删除,只需要将该用户的该角色去掉即可。如果级联删除的话会将角色一并删除,其他拥有此角色的用户一并被删除,这是不现实的。

 

通过维护第三张表来表更多对多关系(重要,常用)

让某个角色拥有某个角色:在第三张表中增加uid和rid的对应关系即可,即增加User中role set的对象

实现代码:

 

            User user = session.get(User.class, 1);Role role = session.get(Role.class, 2);user.getRoleSet().add(role);

 

同理,让某个角色失去某个角色,移除User中role set中的角色即可

实现代码:

User user = session.get(User.class, 1);Role role = session.get(Role.class, 2);user.getRoleSet().remove(role);

 

转载于:https://www.cnblogs.com/youngs/p/6550160.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vba 判断文本框内容是否为空_【VBA】 数据输入 Inputbox 基本语法

在使用Excel 的过程中&#xff0c;如果需要用户输入简单的数据&#xff0c;作为“已知数”&#xff0c;那么可以使用inputbox 函数显示一个对话框&#xff0c;供用户在对话框中输入数据。 Inputbox 函数语法在一对话框来中显示提示&#xff0c;等待用户输入正文或按下按钮&…

AttributeError: ‘version_info‘ object has no attribute ‘version‘

AttributeError: ‘version_info‘ object has no attribute ‘version‘ 解决方法为&#xff1a;pip install pyparsing2.4.7

Qt删除 空格/空白符

QString str " ad dfdsf ef okkd ikk"; str.remove(QRegExp("\\s")); qDebug()<<str.remove(QRegExp("\\s")); "addfdsfefokkdikk"还有去掉前后的空白符 Example: QString str " lots\t of\nwhitespace\r\n "; …

无向图的深度优先遍历非递归_LeetCode0429: N叉树的层序遍历

题目介绍描述&#xff1a;给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。 (即从左到右&#xff0c;逐层遍历)。例如&#xff0c;给定一个 3叉树 :返回其层序遍历:[[1],[3,2,4],[5,6] ]说明:树的深度不会超过 1000。 树的节点总数不会超过 5000。解题思路&#xff1a;★ …

一条龙操作有效解决PermissionError: [WinError 5] 拒绝访问的问题

1 问题描述 当在使用pip install 安装包时&#xff0c;如&#xff1a;pip install scrapy scrapyd scrapyd-client spiderkeeper出现报错&#xff1a;PermissionError: [WinError 5] 拒绝访问。: ‘c:\programdata\anaconda3\lib\site-packages\dateutil\easter.py’ 2 解决办…

儿童书

我要做好孩子转载于:https://www.cnblogs.com/thingk/p/6558903.html

预订态势图

//预订态势图JS//根据日期得到对应星期几 function getWeekByDay(riqi){//2017-01-23;var getWeek "";var arys1 new Array(); arys1riqi.split(-); //日期为输入日期&#xff0c;格式为 2013-3-10var ssdatenew Date(arys1[0],parseInt(arys1[1]-1),arys1…

altera fpga sdi输出方案_FPGA在电力电子中的应用有哪些?

大家好&#xff0c;很抱歉上周末没有及时更新公众号&#xff0c;本来这期想聊聊IGBT的拖尾电流&#xff0c;但是由于周末去深圳高交会(高新技术成果交易会)逛了一天&#xff0c;时间给耽搁了&#xff0c;感觉要想把拖尾电流讲清楚也不太容易&#xff0c;还得需要点时间&#xf…

【Pytorch神经网络理论篇】 39 Transformers库中的BERTology系列模型

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

linux dump_stack

dump_stack():打印出10条函数的调用关系。 定位故障代码:arm-eabi-gdb out/target/product/msm8625/obj/KERNEL_OBJ/vmlinuxgdb) l * i2c_device_probe0xc4

Unity之CharacterController2D学习笔记(1)——基础使用

在很多游戏类型中&#xff0c;玩家角色对物理行为的处理往往和场景中其它物体的行为有比较大的区别。比如角色可能会以90多公里的时速狂奔&#xff0c;同时一次跳跃能跳10多米高&#xff0c;与此同时却几乎不会有任何惯性。同时角色在正常情况下当头部碰到障碍物的时候&#xf…

前端开发中如何将文件夹中的图片变为背景图_Web中的图像技术全面总结,长文干货!...

前端开发人员在构建网站时需要做出的决定之一就是添加图片的技术。它可以是HTML &#xff0c;也可以是通过CSS背景生成的图片&#xff0c;也可以是SVG 。选择正确的技术很重要&#xff0c;并且可以在性能和可访问性方面发挥巨大作用。最简单的情况下&#xff0c;图片元素必须包…

【Pytorch神经网络实战案例】33 使用BERT模型实现完形填空任务

1 案例描述 案例&#xff1a;加载Transformers库中的BERT模型&#xff0c;并用它实现完形填空任务&#xff0c;即预测一个句子中缺失的单词。 2 代码实现&#xff1a;使用BERT模型实现完形填空任务 2.1 代码实现&#xff1a;载入词表&#xff0c;并对输入的文本进行分词转化--…

container_of宏

1.container_of宏 1> Container_of在Linux内核中是一个常用的宏&#xff0c;用于从包含在某个结构中的指针获得结构本身的指针&#xff0c;通俗地讲就是通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址。 2>接口&#xff1a; container_of(ptr, type, …

c++ string 删除字符_字符串操作的全面总结

来自公众号&#xff1a;C语言与cpp编程字符串操作看似简单&#xff0c;其实非常重要&#xff0c;不注意的话&#xff0c;经常出现代码运行结果和自己想要的不一致&#xff0c;甚至崩溃。本文总结了一些构建string对象方法、修改string对象的方法、string类型的操作函数、string…

【Pytorch神经网络理论篇】 40 Transformers中的词表工具Tokenizer

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

warning: function declaration isn’t a prototype(函数声明不是原型)的解决办法

linux驱动中定义一个无参的函数int probe_num(){....}警告&#xff1a;函数声明不是一个原型 [-Wstrict-prototypes]应对方法&#xff1a;改成int probe_num( void){....}警告消失 http://blog.csdn.net/dumgeewang/article/details/7410477

【Pytorch神经网络实战案例】34 使用GPT-2模型实现句子补全功能(手动加载)

1 GPT-2 模型结构 GPT-2的整体结构如下图&#xff0c;GPT-2是以Transformer为基础构建的&#xff0c;使用字节对编码的方法进行数据预处理&#xff0c;通过预测下一个词任务进行预训练的语言模型。 1.1 GPT-2 功能简介 GPT-2 就是一个语言模型&#xff0c;能够根据上文预测下…

电容式传感器位移性能试验报告_一文读懂什么是接近传感器?

点击上方蓝字 记得关注我们哦&#xff01;接近传感器是一种非接触式传感器&#xff0c;当目标进入传感器的视野时&#xff0c;它会检测到物体(通常称为“目标”)的存在。取决于接近传感器的类型&#xff0c;传感器可以利用声音&#xff0c;光&#xff0c;红外辐射(IR)或电磁场来…