我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Hibernate关联关系怎么实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Hibernate关联关系怎么实现

这篇文章主要介绍“Hibernate关联关系怎么实现”,在日常操作中,相信很多人在Hibernate关联关系怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate关联关系怎么实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一, 一对多的单向关联关系

[@more@]

首先先建立Customer和Order类,代码如下:

Customer类:

package mypack;

import java.io.Serializable;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Customer implements Serializable {

   private Long id;

   private String name;

   public Customer(String name) {

       this.name = name;

   }

   public Customer() {

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getName() {

       return this.name;

   }

   public void setName(String name) {

       this.name = name;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

Order类:

package mypack;

import java.io.Serializable;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Order implements Serializable {

   private Long id;

   private String orderNumber;

   private mypack.Customer customer;

   public Order(String orderNumber, mypack.Customer customer) {

       this.orderNumber = orderNumber;

       this.customer = customer;

   }

   public Order() {

   }

   public Order(mypack.Customer customer) {

       this.customer = customer;

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getOrderNumber() {

       return this.orderNumber;

   }

   public void setOrderNumber(String orderNumber) {

       this.orderNumber = orderNumber;

   }

   public mypack.Customer getCustomer() {

       return this.customer;

   }

   public void setCustomer(mypack.Customer customer) {

       this.customer = customer;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

Customer和Order类的配置文件分别是Customer.hbm.xml和Order.hbm.xml

Customer.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

 <class name="mypack.Customer" table="CUSTOMERS" >

   <id name="id" type="long" column="ID">

     <generator class="increment"/>

   id>

   <property name="name" type="string" >

       <column name="NAME" length="15" />

   property>

     

 class>

</hibernate-mapping>

Order.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

  <class name="mypack.Order" table="ORDERS">

   

     <id name="id" type="long" column="ID">

       <generator class="increment"/>

     id>

 

     <property name="orderNumber" type="string" >

       <column name="ORDER_NUMBER" length="15" />

     property>

    <many-to-one

       name="customer"

       column="CUSTOMER_ID"

       class="mypack.Customer"

       not-null="true"

    />

   class>

hibernate-mapping>

在Order.hbm.xml中<many-to-one>元素建立了Customer和ORDERS表的外键CUSTOMER_ID之间

的映射。

它包括如下属性。

●  name:设定待映射的持久化类的属性名,此处为Order类的customer属性。

● column:设定和持久化类的属性对应的表的外键,此处为ORDERS表的外键CUSTOMER_ID。

●  class:设定持久化类的属性的类型,此处设定customer属性为Customer类。

●  not-null:如果为ture,表示customer属性不能为null,默认为false。

接下来我们持久化一个Customer对象以及和他关联的Order对象:

(以下代码并非是完整代码,只是简单把逻辑列出)

     

      Configuration config = new Configuration();

                        config.addClass(Customer.class)

            .       addClass(Order.class);

      sessionFactory = config.buildSessionFactory();

      Session session = sessionFactory.openSession();

      Transaction tx = null;

      tx = session.beginTransaction();

      Customer customer=new Customer("Jack");

      session.save(customer);

      Order order1=new Order("Jack_Order001",customer);

      Order order2=new Order("Jack_Order002",customer);

      session.save(order1);

      session.save(order2);

      tx.commit();

当我们要持久化一个Customer对象以及和他关联的Order对象的时候一定要先建立Customer对象并持久化它,否则当创建Order持久对象的时候会抛出异常,如果把session.save(customer)

注销将会在session.save(order1)抛出PropertyValueException异常。分析产生异常原因:在调用session.save(order1)方法之前,order1和customer对象都是临时对象,临时对象就是刚刚用new创建出来,但是还没有持久会的对象,而Hibernate不会自动持久化order1关联的customer对象,在数据库中意味着仅仅向ORDERS表中插入了一条记录,并且该记录的CUSTOMER_ID字段为null,违反了数据库完整性约束,因为不允许ORDERS表的CUSTOMER_ID字段为null。

从上面的例子可以看出当Hibernate持久化一个临时对象时,在默认情况下,它不会自动持久化所关联的其他临时对象,所以会抛出PropertyValueException异常。如果希望当Hibernate持久化Order对象时自动持久化所关联的Customer对象,可以把<many-to-one>的cascade属性设为“save-update”,cascade属性默认为“none”:

                   

           <many-to-one

         name="customer"    

          column="CUSTOMER_ID"

         class="mypack.Customer"

         cascade=“save-update”

          not-null="true"

               />

这样就能够在Hibernate持久化Order对象时自动持久化所关联的Customer对象了。

二, 一对多的双向关联关系

我们依然使用前面的Customer和Order的例子,由于是双向关联,Order类代码如上面一样,由于Customer类中有Order的关联对象,因此Customer类改为如下:

package mypack;

import java.io.Serializable;

import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Customer implements Serializable {

   private Long id;

   private String name;

   private Set orders;

   public Customer(String name, Set orders) {

       this.name = name;

       this.orders = orders;

   }

   public Customer() {

  }

   public Customer(Set orders) {

       this.orders = orders;

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getName() {

       return this.name;

   }

   public void setName(String name) {

       this.name = name;

   }

   public Set getOrders() {

       return this.orders;

   }

   public void setOrders(Set orders) {

       this.orders = orders;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

如何在映射文件中映射集合类型的order属性呢?由于在CUSTOMERS表中没有直接与order属性对应的字段,因此不能用<property>元素来映射order属性,而是要使用<set>元素:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

 <class name="mypack.Customer" table="CUSTOMERS" >

   <id name="id" type="long" column="ID">

     <generator class="increment"/>

   </id>

   <property name="name" type="string" >

       <column name="NAME" length="15" />

   </property>

   <set

       name="orders"

       cascade="save-update"

     

       >

       

       <key column="CUSTOMER_ID" />

       <one-to-many class="mypack.Order" />

    </set>  

 </class>

</hibernate-mapping>

<set>元素还包含两个子元素:<key>和<one-to-many>,<one-to-many>元素设定所关联的持久化类,此处为Order类,<key>元素设定与所关联的持久化对应的表的外键,此处为ORDERS表的CUSTOMERS_ID字段。

它包括如下属性:

●  <set>元素表明Customer类的orders属性为java.util.Set集合类型。

●  <one-to-many>表明orders集合中存放的是一组Order对象。

●  <key>属性表明ORDERS表通过外键CUSTOMERS_ID参照CUSTOMERS表。

●  cascade 属性取值为"save-update",表明当保存或更新Customer对象时,会级联保存或更新orders集合中的所有Order对象。  

接下来我们持久化一个Customer对象以及和他关联的Order对象:

             Session session = sessionFactory.openSession();

         Transaction tx = null;

          tx = session.beginTransaction();

           Customer customer=new Customer("Tom",new HashSet());

         Order order=new Order();

         order.setOrderNumber("Tom_Order001");

           order.setCustomer(customer);

         customer.getOrders().add(order);

           session.save(customer);

         tx.commit();

当<set>元素的cascade属性为"save-update"时,Hibernate在持久化Customer对象时,会自动持久化关联的Order对象。

如果是加载持久化对象,然后再建立关联关系,那又该怎么做呢?如下所示:

Session session = sessionFactory.openSession();

Transaction tx = null;

tx = session.beginTransaction();

Customer customer=(Customer)session.load(Customer.class,new Long(2));

Order order=(Order)session.load(Order.class,new Long(2));

order.setCustomer(customer);

customer.getOrders().add(order);

tx.commit();

Hibernate会自动清理缓存中的所有持久化对象,按照持久化对象状态改变来同步更新数据库,Hibernate在清理以上Customer对象和Order对象时执行了以下两条SQL语句:

    update ORDERS set ORDER_NUMBER='Jack_Order001',CUSTOMER_ID=2 where ID=2;

      update ORDERS set CUSTOMER_ID=2 where ID=2;

尽管只是修改了ORDERS表的一条记录,但是以上SQL语句表明Hibernate执行了两次update操作这是因为HIbernate根据内存中持久化对象的状态变化来决定需要执行的SQL语句,order.setCustomer(customer)执行的相应SQL语句为:

update ORDERS set ORDER_NUMBER='Jack_Order001',CUSTOMER_ID=2 where ID=2;

customer.getOrders().add(order)执行的相应SQL语句为:

update ORDERS set CUSTOMER_ID=2 where ID=2;

重复执行对于的SQL语句会影响应用程序的性能,那么解决的办法是把<set>元素的inverse属性设置为true,默认为false:

<set

       name="orders"

       cascade="save-update"

         inverse="ture"

       >

       

       <key column="CUSTOMER_ID" />

       <one-to-many class="mypack.Order" />

    set>

因此在映射一对多双向关联关系时,应该在"one"方把inverse属性设为“ture”,这样可以提高性能。

三,一对多双向自身关联关系

以食品为例,它代表商品类别,存在一对多双向自身关联关系。如下图所示,水果类别属于食品类别,同时它又包含两个子类别:苹果类别和桔子类别。

图中每一种商品代表一个Category对象,这些对象形成了树型数据结构。每个Category<span style="FONT-FAMILY:

到此,关于“Hibernate关联关系怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Hibernate关联关系怎么实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Hibernate关联关系怎么实现

这篇文章主要介绍“Hibernate关联关系怎么实现”,在日常操作中,相信很多人在Hibernate关联关系怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate关联关系怎么实现”的疑惑有所
2023-06-03

Hibernate多表关联查询怎么实现

本篇内容介绍了“Hibernate多表关联查询怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、Hibernate简介Hiberna
2023-06-17

如何获取Hibernate关联关系

这篇文章主要介绍了如何获取Hibernate关联关系,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。获取Hibernate关联关系的pojo。我是指例如一个User(用户)拥有
2023-06-17

Hibernate一对多数据关联怎么实现

本篇内容主要讲解“Hibernate一对多数据关联怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate一对多数据关联怎么实现”吧!1.数据模型2.表定义sqluse samp
2023-06-17

Hibernate映射一对多关联关系是什么

这篇文章主要讲解了“Hibernate映射一对多关联关系是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate映射一对多关联关系是什么”吧!在域模型中,类和类之间最普通的关系
2023-06-17

Hibernate映射关联是什么

这篇文章主要讲解了“Hibernate映射关联是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate映射关联是什么”吧!Hibernate映射关联关系和我们现实世界里事物的关
2023-06-17

利用Hibernate怎么实现一个多对一单项关联

这期内容当中小编将会给大家带来有关利用Hibernate怎么实现一个多对一单项关联,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间
2023-05-31

MyBatis怎么实现自定义映射关系和关联查询

本篇内容介绍了“MyBatis怎么实现自定义映射关系和关联查询”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、使用注解实现自定义映射关系当
2023-07-06

Hibernate一对多数据关联是什么

本篇内容主要讲解“Hibernate一对多数据关联是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate一对多数据关联是什么”吧!Hibernate一对多数据关联。指的是单向一对
2023-06-17

Mybatis Plus关联查询怎么实现

本篇内容介绍了“Mybatis Plus关联查询怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Mybatis-Plus 简介什么是
2023-06-22

Android中怎么实现文件关联

本篇文章给大家分享的是有关Android中怎么实现文件关联,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、mineTypemineType媒体类型,一般是[type]/[su
2023-05-30

mysql关联删除数据怎么实现

MySQL中可以通过使用外键约束和ON DELETE CASCADE来实现关联删除数据。首先,在两个表之间设置外键约束。例如,如果表A中有一个外键指向表B的主键:ALTER TABLE AADD CONSTRAINT fk_b_id
mysql关联删除数据怎么实现
2024-03-06

oracle跨库关联查询怎么实现

在Oracle中,可以使用以下几种方法实现跨库关联查询:使用数据库链接(Database Link):首先在目标数据库中创建一个数据库链接,然后使用该链接在当前数据库中执行查询。例如,假设有两个数据库A和B,需要在数据库A中查询数据库B中的
oracle跨库关联查询怎么实现
2024-04-09

Hibernate操作延迟加载的关联是什么

这篇文章主要讲解了“Hibernate操作延迟加载的关联是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate操作延迟加载的关联是什么”吧!默认情况下,Hibernate 3
2023-06-17

excel怎么实现自动数据关联

Excel可以通过使用函数或者公式来实现自动数据关联。以下是一些常用的方法:1. 使用VLOOKUP函数:VLOOKUP函数可以根据一个值在一个数据范围中查找并返回相应的值。例如,如果你有一个订单表格和一个产品表格,你可以使用VLOOKUP
2023-09-12

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录