数据库关系

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

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

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

Hibernate学习笔记③相关推荐

  1. hibernate学习笔记二

    上一篇关于hibernate学习笔记一,主要是作为hibernate的入门知识.没有和spring发生任何关系,这一篇我将把spring集成进去,看spring如何管理hibernate,还有和未使用 ...

  2. hibernate学习笔记(总结)

    hibernate学习笔记 课程内容 6 1 HelloWorld 6 2 Hibernate原理模拟-什么是O/R Mapping以及为什么要有O/R Mapping 6 3 常见的0/R框架(了解 ...

  3. 马士兵Hibernate学习笔记

    马士兵hibernate学习笔记 课程内容 6课程内容 1 HelloWorld 6 2 Hibernate原理模拟-什么是O/R Mapping以及为什么要有O/R Mapping 6 3 常见的0 ...

  4. Hibernate学习笔记Session.evict(user)方法

    @[TOC]Hibernate学习笔记Session.evict(user)方法 Hibernate学习笔记Session.evict(user)方法 首先我们要明白Session.flush(use ...

  5. Hibernate学习笔记(一)----针对不同的数据库不同的配置

    Hibernate初学笔记 l Hibernate初步配置: 1 新建项目 2 学习建立user-library-hibernate,并加入相应的jar包(hibernate核心jar包,lib下的所 ...

  6. Hibernate 学习笔记

    学生时代就这样玩完了,哈哈.. 不过学习却是还要继续.. 就这样发发牢骚吧..... 1.hibernate未毕业之时也曾看过,具体看到哪儿也全忘了,笔记也因为重装系统丢了,索性毕业就记在这儿吧. 首 ...

  7. hibernate 学习笔记1

    今天开始学习hibernate,碰到的几个问题在这里记录一下. 1>导入hibernate5.2.10的hibernate-release-5.2.10.Final\hibernate-rele ...

  8. Hibernate学习笔记(二)

    Hibernate概述: 什么是Hibernate:是一个持久层的ORM的框架 什么是ORM: ORM:对象关系映射,指的是将一个java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可 ...

  9. Hibernate学习笔记(一)

    ####1.1Hibernate框架的学习路线 第一天:Hibernate的入门(Hibernate的环境搭建.Hibernate的API.Hibernate的CRUD) 第二天:Hibernat ...

  10. Hibernate学习笔记_查询

    HQL vs EJBQL 1         NativeSQL >HQL.> EJBQL(JPQL 1.0) > QBC(Query By Criteria) > QBE(Q ...

最新文章

  1. idea的tomcat配置文件在哪里修改_MyBatis配置文件详解
  2. Eclipse创建JavaWeb工程
  3. spring的aop名词解释
  4. 《leetcode》reverse-integer
  5. 基于HtmlParser的网络爬虫
  6. Storm之路-WordCount-实例
  7. mysql double 转 字符串_没想到!在MySQL数据库中的数据有这三种类型!
  8. Hbase Cellutil源码
  9. pandas之combine_first() 合并重叠数据(修补)
  10. 关于Linux进程优先级数字混乱的彻底澄清
  11. apache常用模块介绍
  12. Extjs4.2里Grid显示日期类型数据
  13. 股票基金历史数据下载接口集合
  14. 数据库系统概论第五版学习笔记
  15. python协成_python基础26 -----python进程及协成
  16. linux 内核通知,[Linux] 内核通知链 notifier
  17. 弘辽科技:淘宝直通车推广无展现?该从何入手?
  18. java 查找大写字母_在Java中查找字符串的所有大写字母
  19. 算法进化历程之剪刀石头布
  20. poj3616 Miking Time dp

热门文章

  1. [BZOJ 3236] [Ahoi2013] 作业 [BZOJ 3809] 【莫队(+分块)】
  2. SQL Server 索引和表体系结构(三)
  3. 基于java的数据结构学习——数组实现的栈以及简单应用
  4. 深入vuex原理(上)
  5. 从P560小型机B181201B故障代码识别手把手详解
  6. think queue 消息队列初体验
  7. [C++]宏定义#define A B C
  8. linux输出文字的颜色特效
  9. 32为Linux安卓AVD启动报错
  10. 图像传感器之CMOS(2)