`
sw1982
  • 浏览: 511502 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hibernate笔记2--映射对象之间的关系

阅读更多

 今天心情好。。建了一个比笔记1那篇更简单的表来演示Foo程序:)

 

一。数据库格式

user表

address表

address表持有user_id外键,由此应该可以看出两张表表示的关系为: “1个用户可以拥有多个地址”

 

二。双向关联

下面生成POJO对象:

  1. package model;
  2. /**
  3.  * Address entity.
  4.  * 
  5.  * @author MyEclipse Persistence Tools
  6.  */
  7. public class Address implements java.io.Serializable {
  8.     // Fields
  9.     private Integer addressId;
  10.     private User user;
  11.     private String addressDetail;
  12.     // Constructors
  13.     /** default constructor */
  14.     public Address() {
  15.     }
  16.     /** minimal constructor */
  17.     public Address(User user) {
  18.         this.user = user;
  19.     }
  20.     /** full constructor */
  21.     public Address(User user, String addressDetail) {
  22.         this.user = user;
  23.         this.addressDetail = addressDetail;
  24.     }
  25.     // Property accessors
  26.     public Integer getAddressId() {
  27.         return this.addressId;
  28.     }
  29.     public void setAddressId(Integer addressId) {
  30.         this.addressId = addressId;
  31.     }
  32.     public User getUser() {
  33.         return this.user;
  34.     }
  35.     public void setUser(User user) {
  36.         this.user = user;
  37.     }
  38.     public String getAddressDetail() {
  39.         return this.addressDetail;
  40.     }
  41.     public void setAddressDetail(String addressDetail) {
  42.         this.addressDetail = addressDetail;
  43.     }
  44. }
  1. package model;
  2. import java.util.HashSet;
  3. import java.util.Set;
  4. /**
  5.  * User entity.
  6.  * 
  7.  * @author MyEclipse Persistence Tools
  8.  */
  9. public class User implements java.io.Serializable {
  10.     // Fields
  11.     private Integer userId;
  12.     private String userName;
  13.     private Set addresses = new HashSet(0);
  14.     // Constructors
  15.     /** default constructor */
  16.     public User() {
  17.     }
  18.     /** minimal constructor */
  19.     public User(String userName) {
  20.         this.userName = userName;
  21.     }
  22.     /** full constructor */
  23.     public User(String userName, Set addresses) {
  24.         this.userName = userName;
  25.         this.addresses = addresses;
  26.     }
  27.     // Property accessors
  28.     public Integer getUserId() {
  29.         return this.userId;
  30.     }
  31.     public void setUserId(Integer userId) {
  32.         this.userId = userId;
  33.     }
  34.     public String getUserName() {
  35.         return this.userName;
  36.     }
  37.     public void setUserName(String userName) {
  38.         this.userName = userName;
  39.     }
  40.     public Set getAddresses() {
  41.         return this.addresses;
  42.     }
  43.     public void setAddresses(Set addresses) {
  44.         this.addresses = addresses;
  45.     }
  46. }

由于是双向关联,因此生成的2个POJO对象都会持有对方对象。并且1对N中,1方持有N方Set集合,N方持有1方单个对象。

 

下面是生成的映射配置:

Address.hbm.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="model.Address" table="address" catalog="email">
  9.         <id name="addressId" type="java.lang.Integer">
  10.             <column name="address_id" />
  11.             <generator class="identity" />
  12.         </id>
  13.         <many-to-one name="user" class="model.User" fetch="select">
  14.             <column name="user_id" not-null="true" />
  15.         </many-to-one>
  16.         <property name="addressDetail" type="java.lang.String">
  17.             <column name="address_detail" length="45" />
  18.         </property>
  19.     </class>
  20. </hibernate-mapping>
User.hbm.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="model.User" table="user" catalog="email">
  9.         <id name="userId" type="java.lang.Integer">
  10.             <column name="user_id" />
  11.             <generator class="identity" />
  12.         </id>
  13.         <property name="userName" type="java.lang.String">
  14.             <column name="user_name" length="45" not-null="true" />
  15.         </property>
  16.         <set name="addresses" inverse="true">
  17.             <key>
  18.                 <column name="user_id" not-null="true" />
  19.             </key>
  20.             <one-to-many class="model.Address" />
  21.         </set>
  22.     </class>
  23. </hibernate-mapping>

双向1:N关系基本配置很容易套格式,要注意的是在1方配置inverse="true",意思就是将控制方向交给N方会比较高效一点:)。具体后面解释inverse的概念。

 

下面是一个简单的TestCase,演示保存操作:)

  1. import java.util.HashSet;
  2. import java.util.Set;
  3. import model.Address;
  4. import model.User;
  5. import org.hibernate.HibernateException;
  6. import org.hibernate.Session;
  7. import org.hibernate.SessionFactory;
  8. import org.hibernate.cfg.Configuration;
  9. import org.junit.Before;
  10. import org.junit.Test;
  11. public class TestCase2 {
  12.     Session session = null;
  13.     @Before
  14.     // 读取classpath下的配置文件hibernate.cfg.xml
  15.     // current_session_context_class=thread,show_sql=true
  16.     public void getSession() {
  17.         try {
  18.             Configuration cfg = new Configuration().configure();
  19.             SessionFactory sf = cfg.buildSessionFactory();
  20.             session = sf.getCurrentSession();
  21.         } catch (HibernateException e) {
  22.             e.printStackTrace();
  23.         }
  24.     }
  25.     
  26.     @Test
  27.     public void BothSide() {
  28.         session.beginTransaction();
  29.         User u = new User();
  30.         u.setUserName("hello");
  31.         
  32.         //new Address
  33.         Address add = new Address();
  34.         add.setAddressDetail("luoyu road 1037#");
  35.         u.getAddresses().add(add);
  36.         
  37.         session.save(u);
  38.         session.getTransaction().commit();
  39.     }
  40. }

BothSide()方法中创建了一个User,一个Address,然后save,run一下用例,查看到Hibernate执行了下面的操作:

    insert     into      user         (user_name)      values         (?)

只保存了user,如果目的就是象方法所写 save(u),那么就是对的。但是更新了User的同时也想保存这个Address怎么办?

 

想同时保存User和Address,需要做如下两处修改:

1.在User.hbm.xml 17行写上cascade="all"(对User的所有操作均级联到Address表上)

2.在BothSide() 39-40行中添加  add.setUser(u); (由于address的user_id外键字段不需为空,不给它赋值就会报错)

具体见下:

User.hbm.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools
  6. -->
  7. <hibernate-mapping>
  8.     <class name="model.User" table="user" catalog="email">
  9.         <id name="userId" type="java.lang.Integer">
  10.             <column name="user_id" />
  11.             <generator class="identity" />
  12.         </id>
  13.         <property name="userName" type="java.lang.String">
  14.             <column name="user_name" length="45" not-null="true" />
  15.         </property>
  16.         <set name="addresses" inverse="true" cascade="all">
  17.             <key>
  18.                 <column name="user_id" not-null="true" />
  19.             </key>
  20.             <one-to-many class="model.Address" />
  21.         </set>
  22.     </class>
  23. </hibernate-mapping
  1.     @Test
  2.     public void BothSide() {
  3.         session.beginTransaction();
  4.         User u = new User();
  5.         u.setUserName("hello");
  6.         
  7.         //new Address
  8.         Address add = new Address();
  9.         add.setAddressDetail("luoyu road 1037#");
  10.         add.setUser(u);
  11.         //add Address to user
  12.         u.getAddresses().add(add);
  13.         
  14.         session.save(u);
  15.         session.getTransaction().commit();
  16.     }

      上面这段代码之所以需要添加add.setUser(u),最根本的原因就是上面提到的:我在在User方配置了inverse=true.意思就是“双方的关系交给Address你来管理,User我不负责维护关系”,因此User也不会主动去填充Address方的user_id.

      然而,在维护关系的Address一方,我们访问每一个Address对象的时候,都可以获取到User对象.

 

 

分享到:
评论

相关推荐

    hibernate笔记--云图智联

    注解是使用Hibernate进行对象关系映射的一种方式,它可以减少配置文件的编写,直接在实体类上标注映射信息。 ###Hibernate查询深入 Hibernate提供了Criteria API,可以在代码中创建查询条件,进行复杂的查询操作,...

    Hibernate映射笔记

    Hibernate映射是ORM(对象关系映射)框架中的一项关键技术,它允许开发者在数据库表和Java对象之间建立映射关系,从而简化了数据访问层的开发工作。映射文件通常是`.hbm.xml`格式的XML文档,遵循特定的DTD(Document...

    hibernate学习笔记-01helloword

    Hibernate是一款强大的Java对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据库。 在"01_HelloWord"这个例子中,通常会包含以下几个关键知识点: 1. **环境搭建**:首先...

    Hibernate---我的Hibernate学习笔记.doc

    ORM技术实现对象与关系数据库之间的自动和透明持久化,通过元数据描述对象与数据库表的映射关系,使开发者能以面向对象的方式操作数据库。 ##### Hibernate Hibernate作为成熟的ORM框架,提供了强大的对象与关系...

    J2EE三大框架_笔记_a

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    J2EE框架_笔记_c

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    J2EE框架_笔记_b

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    Hibernate学习笔记特别详细

    Hibernate是一个Java库,它允许开发人员在Java对象和关系数据库之间进行映射。ORM框架的目标是消除传统的JDBC代码,通过提供一种抽象层来处理数据库交互。它将Java类与数据库表关联,将对象实例与数据库记录对应,...

    hibernate总结--云图智联

    Hibernate是一个在Java环境中广泛使用的数据持久化工具,它支持对象关系映射(ORM)技术,将Java对象映射到关系型数据库的表中。Hibernate允许开发者通过面向对象的方式来操作数据库,避免了直接使用SQL语句的繁琐...

    Hibernate笔记完整版

    Hibernate是一个开源的、基于XML配置的、用于对象关系映射的组件,它自动完成对象与数据库表之间的映射,并负责数据的持久化。Hibernate的核心组件包括: 1. POJO类:即标准的Java Bean,是业务逻辑层的对象,不...

    hibernate笔记.txt

    “自上而下的依赖,单向依赖,层与层之间最好依赖抽象”,这一描述实际上触及了软件架构设计中的关键原则,特别是在使用Hibernate这样的ORM(对象关系映射)框架时。 ### 自上而下的依赖 自上而下的依赖,通常指的...

    MLDN_J2EE框架_笔记--精华---(包括jsp struts hibernate spring).rar

    3. **Hibernate**:Hibernate是一个对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作。通过Hibernate,开发者可以使用面向对象的方式来操作数据库,而无需关心底层SQL语句。Hibernate的主要功能有实体...

    JPA学习笔记-EJB-04JPA关联映射总结

    本篇笔记主要聚焦于JPA的关联映射,这是JPA中一个重要的概念,用于定义实体之间的关系。 关联映射允许我们将数据库中的表关系映射到Java对象的关联上。在Hibernate中,这些关系通常通过XML配置文件来定义,而在JPA...

    hibernate笔记

    Hibernate 是一个开源的 Java 平台上的对象关系映射(ORM)框架,它简化了数据库操作,使开发者能够通过面向对象的方式来管理和操作数据。本笔记将深入探讨 Hibernate 的核心概念、配置、实体映射、查询语言及缓存...

    Hibernate,hibernate笔记

    Hibernate 是一个开源的对象关系映射(ORM)框架,它允许Java开发者使用面向对象的方式来操作数据库。这个框架将数据库操作转化为对Java对象的操作,简化了数据持久化的复杂度。以下是对Hibernate的一些关键知识点的...

    Struts+spring+hibernate学习笔记! - Struts原理与实践 - JavaEye知识库.files

    Hibernate 通过实体类(Entity)、持久化属性(Fields)、映射文件(Hibernate Mapping File)等组件,建立了对象与数据库表之间的对应关系。开发者可以通过 Session 对象进行增删查改操作,Hibernate 会自动处理 ...

    尚学堂hibernate笔记

    ### 尚学堂Hibernate笔记知识点详解 #### 一、项目初始化与环境搭建 1. **新建项目**:在IDE中创建一个新的Java项目。 2. **构建用户库并添加所需的JAR包**: - 右键点击项目 -&gt; `Build Path` -&gt; `Configure ...

    韩顺平.2011版.hibernate笔记.zip

    Hibernate是Java开发领域中广泛使用的对象关系映射(ORM)框架,它极大地简化了数据库操作,使开发者能够更加专注于业务逻辑,而不是数据库层面的细节。这份笔记涵盖了Hibernate的核心概念、配置、实体管理、会话...

Global site tag (gtag.js) - Google Analytics