`
sw1982
  • 浏览: 504583 次
  • 性别: 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对象.

 

 

分享到:
评论

相关推荐

    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配置关系的笔记

    Hibernate笔记 马士兵

    第9课 Hibernate的重点学习:Hibernate的对象关系映射 12 一、对象---关系映射模式 12 二、常用的O/R映射框架: 13 第10课 模拟Hibernate原理(OR模拟) 13 一、 项目名称 13 二、 原代码 13 第11课 Hibernate基础配置...

    Hibernate_容器映射技术笔记

    Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记

    hibernate笔记

    8 关系映射(重点) 5 9 Hibernate査询(HQL) 5 10 在Struts基础上继续完善BBS200 5 11 性能优化(重点) 5 12 补充话题 5 风格 5 1 先脉络,后细节 5 2 先操作,后原理 5 3 重Annotation,轻xml配置文件 5 资源 5 1 ...

    hibernate学习笔记

    hibernate多对一关联映射(Hibernate_Many2One) 7 hibernate一对一主键关联映射(单向关联Person----&gt;IdCard) 8 hibernate一对一主键关联映射(双向关联Person&lt;----&gt;IdCard) 9 hibernate一对一唯一外键关联映射...

    hibernate初学者笔记

    关于hibernate的Session,向数据插入时的事务隔离级别,持久化对象的状态,对应关系的映射文件,表与表之间的多种映射关系,以及hibernate的二级缓存的笔记。

    javaEE框架笔记,识货人下

    54留言管理程序_Struts + Spring + Hibernate笔记.pdf 6-Struts标签-BEAN标签笔记.pdf 7-Struts标签 -LOGIC标签笔记.pdf 8-Struts标签- HTML标签笔记.pdf 9-Struts高级部分(1)(解决重复提交、上传组件)笔记.pdf

    Hibernate中单一映射笔记

    Hibernate开发过程(单一映射体) 1创建持久类XXXX.java(要有oid字段:唯一且不具有业务含义;所有属性都有getter/setter方法;空的构造方法;不含oid的构造方法) 2创建映射文件XXXX.hbm.xml(包,类,id,字段) 3...

    Hibernate学习笔记和资料

    hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...

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

    感觉JPA关联映射实现感觉比Hibernate配置文件的关联映射几乎一样,只是引入了“零配置”这个概念。劣者自己在做一个东西的时候用到了关联映射,在此将它做一个总结。留给自己回顾用。

    Hibernate3 学习笔记.ppt

    Hibernate3 学习笔记.ppt 一、O/R Mapping 二、Hibernate入门 三、Hibernate映射申明(Mapping declaration) 四、Hibernate Annotations 五、持久化对象的状态和生命周期 六、Hibernate查询 七、Hibernate最佳实践 ...

    Hibernate - 学习笔记

    使用Hibernate对数据进行操作时会牵涉到3种类型的文件:Java类(实体类),映射文件(test.hbm.xml),数据库的表结构(表结构的创建).从理论上说只要知道其中一个,另外两个就可以从知道的那个文件中生成出来,这就涉及到先...

    Hibernate学习笔记

    001 Hibernate 简介(开源 O/R 映射框架) 002 第一个 Hibernate 示例 003 hibernate 主要接口介绍 004 持久对象的生命周期介绍 005 query 接口初步 006 开源 O/R 映射框架内容回顾 007 Hibernate 基本映射标签和属性...

    Hibernate实体映射

    里面包含Hibernate实体映射的具体实例代码,还有相关教程笔记,喜欢的可以学习学习。

    hibernate 笔记

    hibernate 笔记 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以...

Global site tag (gtag.js) - Google Analytics