一对多

创建两个类  Manager(一这一端) Worker(多这一端)  即一个经理下有多个员工

package com.hibernate.n21;import java.util.HashSet;
import java.util.Set;public class Manager {private Integer mgrId;private String mgrName;/** 1. 声明集合类型时, 需使用接口类型, 因为 hibernate 在获取* 集合类型时, 返回的是 Hibernate 内置的集合类型, 而不是 JavaSE 一个标准的* 集合实现. * 2. 需要把集合进行初始化, 可以防止发生空指针异常*/private Set<Worker> workers = new HashSet<>();public Integer getMgrId() {return mgrId;}public void setMgrId(Integer mgrId) {this.mgrId = mgrId;}public String getMgrName() {return mgrName;}public void setMgrName(String mgrName) {this.mgrName = mgrName;}public Set<Worker> getWorkers() {return workers;}public void setWorkers(Set<Worker> workers) {this.workers = workers;}}package com.hibernate.n21;public class Worker {private Integer id;private String name;private Manager manager;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Manager getManager() {return manager;}public void setManager(Manager manager) {this.manager = manager;}@Overridepublic String toString() {return "Worker [id=" + id + ", name=" + name + ", manager=" + manager + "]";}}

xml文件

<!--1这一端-->
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-10 7:47:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping><class name="com.hibernate.n21.Manager" table="MANAGER"><id name="mgrId" type="java.lang.Integer"><column name="MGR_ID" /><generator class="native" /></id><property name="mgrName" type="java.lang.String"><column name="MGR_NAME" /></property><!-- 映射 1 对多的那个集合属性 --><!-- set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致 --><!-- inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系 --><!-- order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名  --><set name="workers" table="WORKER" inverse="true"><!-- 执行多的表中的外键列的名字 --><key><column name="MGR_ID" /></key><!-- 指定映射类型 --><one-to-many class="com.hibernate.n21.Worker" /></set></class>
</hibernate-mapping>

<!--多这端-->
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-10 7:47:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping><class name="com.hibernate.n21.Worker" table="WORKER"><id name="id" type="java.lang.Integer"><column name="ID" /><generator class="native" /></id><property name="name" type="java.lang.String"><column name="NAME" /></property><!-- 映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 name: 多这一端关联的一那一端的属性的名字class: 一那一端的属性对应的类名column: 一端对应的数据表中的外键的名字--><many-to-one name="manager" class="com.hibernate.n21.Manager" fetch="join"><column name="MGR_ID" /></many-to-one></class>
</hibernate-mapping>

测试代码

package com.hibernate.n21;import static org.junit.Assert.*;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;public class Test {private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();}@org.junit.Testpublic void test() {fail("Not yet implemented");}@org.junit.Testpublic void testMany2OneGet(){//1. 若查询多的一端的一个对象(Worker), 则默认情况下, 只查询了多的一端的对象,不查询一的一端对象(Manager)Worker worker = (Worker) session.get(Worker.class, 1);System.out.println(worker.getName());System.out.println(worker.getManager().getClass());//session.close();//2. 在需要使用到关联的对象时, 才发送对应的 SQL 语句. /*Manager manager = worker.getManager();System.out.println(manager.getMgrName());*/ //3. 在查询对象时, 由多的一端导航到 1 的一端时, //若此时 session 已被关闭, 会发生 LazyInitializationException 异常//4. 获取 Worker 对象时, 默认情况下, 其关联的 Manager对象是一个代理对象!
        }@org.junit.Testpublic void testMany2OneSave() {Worker worker = new Worker();worker.setName("worker-1");Worker worker2 = new Worker();worker2.setName("worker-2");Worker worker3 = new Worker();worker3.setName("worker-3");System.out.println(worker);System.out.println(worker2);System.out.println(worker3);Manager manager = new Manager();manager.setMgrName("MMM");//设定关联关系
        worker.setManager(manager);worker2.setManager(manager);worker3.setManager(manager);//先插入 1 的一端, 再插入 n 的一端, 只有 INSERT 语句.//反过来插入开始Manner的mgrId未生成会产生update语句
        session.save(manager);session.save(worker);session.save(worker2);session.save(worker3);}}

数据库截图

一对一关系外键

Manager 和  Department  一个经理一个部门

package com.hibernate.n21;public class Department {private Integer deptId;private String deptName;private Manager mgr;public Integer getDeptId() {return deptId;}public void setDeptId(Integer deptId) {this.deptId = deptId;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}public Manager getMgr() {return mgr;}public void setMgr(Manager mgr) {this.mgr = mgr;}}package com.hibernate.n21;import java.util.HashSet;
import java.util.Set;public class Manager {private Integer mgrId;private String mgrName;/** 1. 声明集合类型时, 需使用接口类型, 因为 hibernate 在获取* 集合类型时, 返回的是 Hibernate 内置的集合类型, 而不是 JavaSE 一个标准的* 集合实现. * 2. 需要把集合进行初始化, 可以防止发生空指针异常*/private Set<Worker> workers = new HashSet<>();private Department dept; //在上面的代码上加了这行public Integer getMgrId() {return mgrId;}public void setMgrId(Integer mgrId) {this.mgrId = mgrId;}public String getMgrName() {return mgrName;}public void setMgrName(String mgrName) {this.mgrName = mgrName;}public Set<Worker> getWorkers() {return workers;}public void setWorkers(Set<Worker> workers) {this.workers = workers;}public Department getDept() {return dept;}public void setDept(Department dept) {this.dept = dept;}}

xml文件

<!--在部门这端生成外键--><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-10 9:04:21 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping><class name="com.hibernate.n21.Department" table="DEPARTMENT"><id name="deptId" type="java.lang.Integer"><column name="DEPTID" /><generator class="native" /></id><property name="deptName" type="java.lang.String"><column name="DEPTNAME" /></property><!-- 使用 many-to-one 的方式来映射 1-1 关联关系 --><many-to-one name="mgr" class="com.hibernate.n21.Manager" column="MGR_ID" unique="true"></many-to-one></class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-10 7:47:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping><class name="com.hibernate.n21.Manager" table="MANAGER"><id name="mgrId" type="java.lang.Integer"><column name="MGR_ID" /><generator class="native" /></id><property name="mgrName" type="java.lang.String"><column name="MGR_NAME" /></property><!-- 映射 1 对多的那个集合属性 --><!-- set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致 --><!-- inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系 --><!-- order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名  --><set name="workers" table="WORKER" inverse="true"><!-- 执行多的表中的外键列的名字 --><key><column name="MGR_ID" /></key><!-- 指定映射类型 --><one-to-many class="com.hibernate.n21.Worker" /></set><!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 --><!-- 没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段--><!-- 在原来的代码上加上一对一关系 --><one-to-one name="dept" class="com.hibernate.n21.Department"property-ref="mgr"></one-to-one></class>
</hibernate-mapping>

Test

@org.junit.Testpublic void testGet(){//1. 默认情况下对关联属性使用懒加载Department dept = (Department) session.get(Department.class, 1);System.out.println(dept.getDeptName()); //2. 会出现懒加载异常的问题.
//        session.close();//3. 查询 Manager 对象的连接条件应该是 dept.manager_id = mgr.manager_id
//而不应该是 dept.dept_id = mgr.manager_id所以在xml文件中加入property-ref="mgr"Manager mgr = dept.getMgr();System.out.println(mgr.getMgrName()); }@org.junit.Testpublic void testSave(){Department department = new Department();department.setDeptName("DEPT-BB");Manager manager = new Manager();manager.setMgrName("MGR-BB");//设定关联关系
        department.setMgr(manager);manager.setDept(department);//保存操作//建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
        session.save(manager);session.save(department);}

基于主键

修改Department的xml即可 (删除Manager xml里的property-ref="mgr")

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-8-10 9:04:21 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping><class name="com.hibernate.n21.Department" table="DEPARTMENT"><id name="deptId" type="java.lang.Integer"><column name="DEPT_ID" /><!-- 使用外键的方式来生成当前的主键 --><generator class="foreign"><!-- property 属性指定使用当前持久化类的哪一个属性的主键作为外键 --><param name="property">mgr</param></generator></id><property name="deptName" type="java.lang.String"><column name="DEPTNAME" /></property><!-- 使用 many-to-one 的方式来映射 1-1 关联关系 --><!--  采用 foreign 主键生成器策略的一端增加 one-to-one 元素映射关联属性,其 one-to-one 节点还应增加 constrained=true 属性, 以使当前的主键上添加外键约束--><one-to-one name="mgr" class="com.hibernate.n21.Manager" constrained="true"></one-to-one></class>
</hibernate-mapping>

多对多

public class Category {private Integer id;private String name;private Set<Item> items = new HashSet<>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Item> getItems() {return items;}public void setItems(Set<Item> items) {this.items = items;}}public class Item {private Integer id;private String name;private Set<Category> categories = new HashSet<>();public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Category> getCategories() {return categories;}public void setCategories(Set<Category> categories) {this.categories = categories;}}@Testpublic void testGet(){Category category = (Category) session.get(Category.class, 1);System.out.println(category.getName()); //需要连接中间表Set<Item> items = category.getItems();System.out.println(items.size()); }@Testpublic void testSave(){Category category1 = new Category();category1.setName("C-AA");Category category2 = new Category();category2.setName("C-BB");Item item1 = new Item();item1.setName("I-AA");Item item2 = new Item();item2.setName("I-BB");//设定关联关系
        category1.getItems().add(item1);category1.getItems().add(item2);category2.getItems().add(item1);category2.getItems().add(item2);item1.getCategories().add(category1);item1.getCategories().add(category2);item2.getCategories().add(category1);item2.getCategories().add(category2);//执行保存操作
        session.save(category1);session.save(category2);session.save(item1);session.save(item2);}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.hibernate.n2n"><class name="Category" table="CATEGORIES"><id name="id" type="java.lang.Integer"><column name="ID" /><generator class="native" /></id><property name="name" type="java.lang.String"><column name="NAME" /></property><!-- table: 指定中间表 --><set name="items" table="CATEGORIES_ITEMS"><key><column name="C_ID" /></key><!-- 使用 many-to-many 指定多对多的关联关系. column 执行 Set 集合中的持久化类在中间表的外键列的名称  --><many-to-many class="Item" column="I_ID"></many-to-many></set></class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.hibernate.n2n"><class name="Item" table="ITEMS"><id name="id" type="java.lang.Integer"><column name="ID" /><generator class="native" /></id><property name="name" type="java.lang.String"><column name="NAME" /></property><set name="categories" table="CATEGORIES_ITEMS" inverse="true"><key column="I_ID"></key><many-to-many class="Category" column="C_ID"></many-to-many></set></class>
</hibernate-mapping>

转载于:https://www.cnblogs.com/lusufei/p/7325535.html

Hibernate关联关系配置(一对多,一对一,多对多)相关推荐

  1. Hibernate关联关系配置(一对多、一对一和多对多)

    第一种关联关系:一对多(多对一) "一对多"是最普遍的映射关系,简单来讲就如消费者与订单的关系. 一对多:从消费者角的度来说一个消费者可以有多个订单,即为一对多. 多对一:从订单的 ...

  2. (转)Hibernate关联映射——一对多(多对一)

    http://blog.csdn.net/yerenyuan_pku/article/details/70152173 Hibernate关联映射--一对多(多对一) 我们以客户(Customer)与 ...

  3. 【数据表间关联关系】 一对多、多对一、一对一、多对多

    关联映射:一对多/多对一 存在最普遍的映射关系,简单来讲就如球员与球队的关系: 一对多:从球队角度来说一个球队拥有多个球员 即为一对多 多对一:从球员角度来说多个球员属于一个球队 即为多对一 数据表间 ...

  4. (5)hibernate多对一,一对多,一对一,多对多

    一 多对一关联 1 映射与原理分析 2 例子结构图 3代码 3.1 Department.java package com.learning;public class Department {priv ...

  5. hibernate中的一对多和多对多的映射关系

    一多对需要注意的问题: 多看文字部分的内容,有助于理解 多 对多需要注意的问题: 转载于:https://www.cnblogs.com/wzhBlog/archive/2013/03/13/2958 ...

  6. Hibernate第四篇【集合映射、一对多和多对一】

    前言 前面的我们使用的是一个表的操作,但我们实际的开发中不可能只使用一个表的-因此,本博文主要讲解关联映射 集合映射 需求分析:当用户购买商品,用户可能有多个地址. 数据库表 我们一般如下图一样设计数 ...

  7. mybatis高级映射(一对一,一对多,多对多)

    http://www.cnblogs.com/selene/p/4627446.html 阿赫瓦里 生命对于某些人来说,一直都是美丽的,因为这些人的一生都在为某个梦想而奋斗!!! 博客园 首页 新随笔 ...

  8. Hibernate 中配置属性详解(hibernate.properties)

    转自:https://blog.csdn.net/shudaqi2010/article/details/70324843 Hibernate能在各种不同环境下工作而设计的, 因此存在着大量的配置参数 ...

  9. Hibernate关联关系映射-----双向一对多/多对一映射配置

    转自:http://blog.csdn.net/yifei12315/article/details/6985194 /// Hibernate: /// 双向关联就是有"一对多" ...

最新文章

  1. 工业4.0的十大关键词
  2. (012) java后台开发之Apache与Tomcat有什么关系和区别
  3. Oracle开发环境安装与使用
  4. Meteor资源国外优秀web APP 收藏
  5. android2.2 froyo竖屏显示
  6. python入门书?
  7. Mysql之1050错误解决办法
  8. Bat批处理脚本--常用命令
  9. qq音乐api android,QQ音乐
  10. linux 进入recovery 命令行,liunx-fastboot命令行的使用方法
  11. c语言中各个符号的意义及作用是什么,C语言各类符号意义以及用法是什么?
  12. word文档更新目录为什么更新不了?
  13. 初识strlen函数
  14. 理解“卷积” Understanding Convolutions
  15. hive注意事项01_空值处理
  16. ESP-IDF遇到的关于环境变量的问题
  17. Python pyautogui 实现自动发送消息
  18. SEO优化 - robots协议
  19. 2019,无数人改变命运的绝佳之年!(深度)
  20. 全加器在计算机的应用,两个半加器组成全加器的做法 浅谈全加器和半加器的应用...

热门文章

  1. iOS 中KVC、KVO、NSNotification、delegate 总结及区别
  2. FATAL ERROR: Could not find ./bin/my_print_defaults
  3. LAMP平台部署及应用
  4. 教你使用IOS内置的排错命令
  5. mysql with as_mysql数据库学习(第十六篇)- 视图
  6. Xamarin XAML语言教程构建进度条ProgressBar
  7. android phone驱动_[基础知识] 将 OneDrive 同步到 SD 卡等外部驱动器
  8. linux 安装gcc4.2,Linux操作系统下安装gcc4.2.*的方法
  9. python datetime计算时间差_Python中关于日期的计算总结
  10. 离开英伟达仅19个月,他交出了一块国产全功能GPU