hibernate对于数据库的操作,全部利用面向对象的思维来理解和实现的。一般的单独表的映射,相信大家都没有问题,但是对于一些表之间的特殊关系,Hibernate提供了一些独特的方式去简化它。

今天就来说说多对一的关联映射。

数据库中有多对一的关系,Hibernate自然也有对象的多对一的关联关系。比如用户和用户组,一个用户只属于一个组,一个组有多名用户。我们就可以说用户和用户组的关系就是多对一的关系。用对象的uml图表示一下:

在Hibernate中如何来实现呢?首先定义这两个实体类:

  1. package com.bjpowernode.hibernate;
  2. /**
  3. * 用户组
  4. * @author Longxuan
  5. *
  6. */
  7. public class Group {
  8. private int id;
  9. private String name;
  10. public int getId() {
  11. return id;
  12. }
  13. public void setId(int id) {
  14. this.id = id;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. }
  23. package com.bjpowernode.hibernate;
  24. /**
  25. * 用户类
  26. * @author Longxuan
  27. *
  28. */
  29. public class User {
  30. private int  id;
  31. private String name;
  32. private Group group;
  33. public Group getGroup() {
  34. return group;
  35. }
  36. public void setGroup(Group group) {
  37. this.group = group;
  38. }
  39. public int getId() {
  40. return id;
  41. }
  42. public void setId(int id) {
  43. this.id = id;
  44. }
  45. public String getName() {
  46. return name;
  47. }
  48. public void setName(String name) {
  49. this.name = name;
  50. }
  51. }

hibernate.cfg.xml配置文件:

  1. <!DOCTYPE hibernate-configuration PUBLIC
  2. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  4. <hibernate-configuration>
  5. <session-factory name="foo">
  6. <property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>
  7. <property name="hibernate.show_sql">true</property><!-- 设置是否显示生成sql语句 -->
  8. <property name="hibernate.format_sql">false</property><!-- 设置是否格式化sql语句-->
  9. <mapping resource="com/bjpowernode/hibernate/Tables.hbm.xml" />
  10. </session-factory>
  11. </hibernate-configuration>

hibernate.properties配置文件:

  1. ## MySQL
  2. hibernate.dialect org.hibernate.dialect.MySQLDialect
  3. #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
  4. #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
  5. hibernate.connection.driver_class com.mysql.jdbc.Driver
  6. hibernate.connection.url jdbc:mysql://localhost:3306/hibernate_many2one
  7. hibernate.connection.username root
  8. hibernate.connection.password root

这是最基础的准备工作,多对一映射在对数据进行更改时,会有一些限制。当没有该用户组时,添加用户,就会出错,当该用户组有用户时,删除该用户组也会报错。

我们当然可以按一般的方法来做。添加的时候,先手动添加组,再添加用户。删除时,先删除所有的用户,再删除用户组。但是Hibernate为我们提供了一种便捷的方式——many-to-one。在映射文件hbm.xml中配置后,就可以不用再想那些限制了。Hibernate会自动添加上所引用的数据。

给出映射文件:

  1. <?xml version="1.0"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.bjpowernode.hibernate.User" table="t_user">
  7. <id name="id">
  8. <generator class="native" />
  9. </id>
  10. <property name="name"></property>
  11. <many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>
  12. </class>
  13. <class name="com.bjpowernode.hibernate.Group" table="t_group">
  14. <id name="id">
  15. <generator class="native" />
  16. </id>
  17. <property name="name"></property>
  18. </class>
  19. </hibernate-mapping>

配置了many-to-one会自动在t_user表中创建外键groupid,与t_group的id映射。

many-to-one标签用到了cascade,指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。其属性值如下:

  • all:在所有的情况下都执行级联操作;
  • none:在所有情况下都不执行级联操作;
  • save-update:在保存和更新的时候执行级联操作;、
  • delete:在删除的时候执行级联操作。

测试类Many2OneTest:

  1. package com.bjpowernode.hibernate;
  2. import junit.framework.TestCase;
  3. import org.hibernate.Session;
  4. public class Many2OneTest extends TestCase {
  5. /**
  6. * 测试添加用户
  7. */
  8. public void testSave3(){
  9. Session session = null;
  10. try{
  11. session = HibernateUtils.getSession();
  12. session.beginTransaction();
  13. Group group = new Group();
  14. group.setName("提高班");
  15. User user1 = new User();
  16. user1.setName("张三");
  17. user1.setGroup(group);
  18. User user2 = new User();
  19. user2.setName("李四");
  20. user2.setGroup(group);
  21. //普通方法 :必须先保存group,再保存user
  22. //配置了many-to-one 则不用再手动save group了。
  23. //session.save(group);
  24. session.save(user1);
  25. session.save(user2);
  26. session.getTransaction().commit();
  27. }catch(Exception e){
  28. e.printStackTrace();
  29. session.getTransaction().rollback();
  30. }finally{
  31. HibernateUtils.closeSession(session);
  32. }
  33. }
  34. }

结果图:

执行测试前:  , 执行测试后: 

用many-to-one进行配置后,hibernate会自动去添加外键,而我们做的任何操作都不需要去考虑它的结构,也不用手动去维护这个关系,关系由Hibernate自动维护。这就是Hibernate的魅力所在。

一口一口吃掉Hibernate(四)——多对一单向关联映射的更多相关文章

  1. 【SSH系列】Hibernate映射-- 多对一单向关联映射

    在hibernate中非常重要的就是映射,在前面的博文中,小编简单的介绍了基本映射,基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关系,将关联关系映射到数据库中,所谓的关联关系在对象模型 ...

  2. Hibernate从入门到精通(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映射之前,首先看 ...

  3. Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  4. Hibernate(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的 相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映 射之前,首 ...

  5. Hibernate(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本 次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类 似,只是 ...

  6. [置顶] Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  7. [置顶] Hibernate从入门到精通(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映射之前,首先看 ...

  8. Hibernate 单项多对一的关联映射

    在日常开发中会出现很对多对一的情况,本文介绍hibernate中多对一的关联映射. 1.设计表结构 2.创建student对象 3.创建Grade对象 4.写hbm.xml文件 5.生成数据库表 生成 ...

  9. Hibernate之关于多对多单向关联映射

    [Hibernate]之关于多对多单向关联映射 老师和学生,最典型的多对多关联, Teacher和Student.所谓单向意思就是说.老师知道自己的教的是哪些学生而学生不知道是哪些老师教. 也能够这么 ...

随机推荐

  1. HTTP协议的消息头:Content-Type和Accept的作用

    一.背景知识 1.概述 Http报头分为通用报头,请求报头,响应报头和实体报头. 请求方的http报头结构:通用报头|请求报头|实体报头 响应方的http报头结构:通用报头|响应报头|实体报头 Acc ...

  2. SSO的全方位解决方案 - Kerberos协议(RFC 1510)

    一.桌面SSO和WEB-SSO的局限性 前面我们的解决方案(桌面SSO和WEB-SSO)都有一个共性:要想将一个应用集成到我们的SSO解决方案中,或多或少的需要修改应用程序. Web应用需要配置一个我 ...

  3. ejs注释问题

    项目中遇到一个问题: 代码如下: 但是代码如下时,却不会出现bug: bug的导火索是ejs的注释: 因为我没有用对注释,所以被注释部分的if语句仍旧生效了. bug的根本原因是没有对mod类型进行判 ...

  4. Spring 环境与profile(三)——利用maven的resources、filter和profile实现不同环境使用不同配置文件

    基本概念 profiles定义了各个环境的变量id filters中定义了变量配置文件的地址,其中地址中的环境变量就是上面profile中定义的值 resources中是定义哪些目录下的文件会被配置文 ...

  5. 【Java入门提高篇】Day15 Java泛型再探——泛型通配符及上下边界

    上篇文章中介绍了泛型是什么,为什么要使用泛型以及如何使用泛型,相信大家对泛型有了一个基本的了解,本篇将继续讲解泛型的使用,让你对泛型有一个更好的掌握和更深入的认识. 上篇中介绍完泛型之后,是不是觉得泛 ...

  6. [Micropython]TPYBoard v10x拼插编程实验 点亮心形点阵

    一.什么是TPYBoard开发板 TPYBoard是以遵照MIT许可的MicroPython为基础,由TurnipSmart公司制作的一款MicroPython开发板,它基于STM32F405单片机, ...

  7. Jenkins: Can't connect to Docker daemon解决办法

    Jenkins安装后首次使用报错: Jenkins: Can't connect to Docker daemon 解决办法: 参照StackOverflow 添加jenkins用户到dockergr ...

  8. C# 传统四舍五入保留两位小数(网上流传好多错误的版本)

    关于C#里面的Math.Round,很多人都会用到,而且以为是四舍五入,其实不是这样的: C#里面的Math.Round是符合IEEE标准的“四舍五入”,其实是五舍六入. 网上好多流传的下面这种方式实 ...

  9. java.sql.SQLException: null, message from server: "Host '192.168.126.100' is not allowed to connect to this MySQL server"

  10. [ Java学习基础 ] Java对象的创建和销毁

    类实例化可生成对象,实例方法就是对象方法,实例变量就是对象属性.一个对象的生命周期包括三个阶段:创建.使用和销毁. 创建对象 创建对象包括两个步骤:声明和实例化. 声明 声明对象与声明普通变量没有区别 ...