浅析Hibernate一对多数据关联的问题(一)

开发 后端
Hibernate一对多数据关联。指的是单向一对多数据关联一个用户有多个地址,在用户类TUser中包含地址类TAddress集合。

Hibernate一对多数据关联。指的是单向一对多数据关联一个用户有多个地址,在用户类TUser中包含地址类TAddress集合。

1.数据模型

2.表定义sql

  1. use sample;  
  2.  
  3. DROP TABLE T_Address;  
  4. DROP TABLE T_User;  
  5.  
  6. CREATE TABLE T_User (  
  7.        id INT NOT NULL AUTO_INCREMENT  
  8.      , name VARCHAR(50)  
  9.      , age INT  
  10.      , PRIMARY KEY (id)  
  11. );  
  12.  
  13. CREATE TABLE T_Address (  
  14.        id INT NOT NULL AUTO_INCREMENT  
  15.      , address VARCHAR(200)  
  16.      , zipcode VARCHAR(10)  
  17.      , tel VARCHAR(20)  
  18.      , type VARCHAR(20)  
  19.      , user_id INT NOT NULL  
  20.      , idx INT  
  21.      , PRIMARY KEY (id)  
  22.      , INDEX (user_id)  
  23.      , CONSTRAINT FK_T_Address_1 FOREIGN KEY (user_id)  
  24.                   REFERENCES T_User (id)  
  25. );  

POJO类
TUser.java

  1. package cn.blogjava.start;  
  2.  
  3. import java.util.Set;  
  4.  
  5. public class TUser  implements java.io.Serializable {  
  6.     // Fields      
  7.      private Integer id;  
  8.      private Integer age;  
  9.      private String name;  
  10.      private Set address;  
  11.  
  12.  
  13.     // Constructors  
  14.  
  15.     public Integer getAge() {  
  16.         return age;  
  17.     }  
  18.  
  19.     public void setAge(Integer age) {  
  20.         this.age = age;  
  21.     }  
  22.  
  23.  
  24.     public Set getAddress() {  
  25.         return address;  
  26.     }  
  27.  
  28.     public void setAddress(Set address) {  
  29.         this.address = address;  
  30.     }  
  31.  
  32.     /** default constructor */  
  33.     public TUser() {  
  34.     }  
  35.       
  36.     /** constructor with id */  
  37.     public TUser(Integer id) {  
  38.         this.id = id;  
  39.     }  
  40.  
  41.     // Property accessors  
  42.  
  43.     public Integer getId() {  
  44.         return this.id;  
  45.     }  
  46.       
  47.     public void setId(Integer id) {  
  48.         this.id = id;  
  49.     }  
  50.  
  51.     public String getName() {  
  52.         return this.name;  
  53.     }  
  54.       
  55.     public void setName(String name) {  
  56.         this.name = name;  
  57.     }  

TAddress.java

  1. package cn.blogjava.start;  
  2.  
  3. import java.io.Serializable;  
  4.  
  5. public class TAddress implements Serializable {  
  6.       
  7.     private Integer id;  
  8.     private String address;  
  9.     private String zipcode;  
  10.     private String tel;  
  11.     private String type;  
  12.     private Integer userId;  
  13.     private Integer idx;  
  14.       
  15.     public Integer getId() {  
  16.         return id;  
  17.     }  
  18.     public void setId(Integer id) {  
  19.         this.id = id;  
  20.     }  
  21.     public String getAddress() {  
  22.         return address;  
  23.     }  
  24.     public void setAddress(String address) {  
  25.         this.address = address;  
  26.     }  
  27.     public Integer getIdx() {  
  28.         return idx;  
  29.     }  
  30.     public void setIdx(Integer idx) {  
  31.         this.idx = idx;  
  32.     }  
  33.     public String getTel() {  
  34.         return tel;  
  35.     }  
  36.     public void setTel(String tel) {  
  37.         this.tel = tel;  
  38.     }  
  39.     public String getType() {  
  40.         return type;  
  41.     }  
  42.     public void setType(String type) {  
  43.         this.type = type;  
  44.     }  
  45.     public Integer getUserId() {  
  46.         return userId;  
  47.     }  
  48.     public void setUserId(Integer userId) {  
  49.         this.userId = userId;  
  50.     }  
  51.     public String getZipcode() {  
  52.         return zipcode;  
  53.     }  
  54.     public void setZipcode(String zipcode) {  
  55.         this.zipcode = zipcode;  
  56.     }  
  57.  
  58. }  

3.配置文件
TUser.hbm.xml

  1. xml version="1.0"?> 
  2. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3. <hibernate-mapping> 
  4.     <class name="cn.blogjava.start.TUser" table="T_User" catalog="sample" 
  5.      dynamic-update="true" dynamic-insert="true" 
  6.     > 
  7.         <id name="id" type="integer"> 
  8.             <column name="id" /> 
  9.             <generator class="native" /> 
  10.         id> 
  11.         <property name="name" type="string" column="name" /> 
  12.         <property name="age" type="java.lang.Integer" column="age" /> 
  13.  
  14.         <set name="address" table="t_address" cascade="all" order-by="zipcode asc"> 
  15.             <key column="user_id"> 
  16.             key> 
  17.             <one-to-many class="cn.blogjava.start.TAddress" /> 
  18.         set> 
  19.     class> 
  20. hibernate-mapping> 

TAddress.hbm.xml
注意:没有配置user_id字段。

  1. xml version="1.0"?> 
  2. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3. <hibernate-mapping> 
  4.     <class name="cn.blogjava.start.TAddress" table="T_Address" catalog="sample"> 
  5.         <id name="id" type="integer"> 
  6.             <column name="id" /> 
  7.             <generator class="native" /> 
  8.         id> 
  9.         <property name="address" type="string" column="address" /> 
  10.         <property name="zipcode" type="string" column="zipcode" /> 
  11.         <property name="tel" type="string" column="tel" /> 
  12.         <property name="type" type="string" column="type" /> 
  13.         <property name="idx" type="java.lang.Integer" column="idx" /> 
  14.     class> 
  15. hibernate-mapping> 

4.测试代码

  1. package cn.blogjava.start;  
  2.  
  3. import java.util.HashSet;  
  4. import java.util.Iterator;  
  5. import java.util.List;  
  6.  
  7. import junit.framework.Assert;  
  8. import junit.framework.TestCase;  
  9.  
  10. import org.hibernate.HibernateException;  
  11. import org.hibernate.Session;  
  12. import org.hibernate.SessionFactory;  
  13. import org.hibernate.Transaction;  
  14. import org.hibernate.cfg.Configuration;  
  15.  
  16.  
  17. public class HibernateTest extends TestCase {  
  18.       
  19.     Session session = null;  
  20.  
  21.     protected void setUp() {  
  22.         try {  
  23.             Configuration config = new Configuration().configure();  
  24.             SessionFactory sessionFactory = config.buildSessionFactory();  
  25.             session = sessionFactory.openSession();  
  26.               
  27.         } catch (HibernateException e) {  
  28.             e.printStackTrace();  
  29.         }          
  30.     }  
  31.  
  32.     protected void tearDown() {  
  33.         try {  
  34.             session.close();          
  35.         } catch (HibernateException e) {  
  36.             e.printStackTrace();  
  37.         }          
  38.     }      
  39.       
  40.     /**  
  41.      * 对象持久化测试(Insert方法)  
  42.      */          
  43.     public void testInsert() {  
  44.         Transaction tran = null;  
  45.         try {  
  46.           
  47.             TUser user = new TUser();  
  48.             user.setName("byf");  
  49.             user.setAge(new Integer(26));  
  50.               
  51.             TAddress addr = new TAddress();  
  52.             addr.setTel("1123");  
  53.             addr.setZipcode("233123");  
  54.             addr.setAddress("HongKong");  
  55.               
  56.             TAddress addr2 = new TAddress();  
  57.             addr2.setTel("139");  
  58.             addr2.setZipcode("116001");  
  59.             addr2.setAddress("dalian");              
  60.  
  61.             TAddress addr3 = new TAddress();  
  62.             addr3.setTel("136");  
  63.             addr3.setZipcode("100080");  
  64.             addr3.setAddress("beijing");  
  65.               
  66.             //设置关联  
  67.             HashSet set = new HashSet();  
  68.             set.add(addr);  
  69.             set.add(addr2);  
  70.             set.add(addr3);  
  71.             user.setAddress(set);  
  72.                                      
  73.             tran = session.beginTransaction();                                  
  74.             //插入user信息  
  75.             session.save(user);  
  76.             session.flush();  
  77.             tran.commit();  
  78.             Assert.assertEquals(user.getId().intValue()>0 ,true);  
  79.         } catch (HibernateException e) {  
  80.             e.printStackTrace();  
  81.             Assert.fail(e.getMessage());  
  82.             if(tran != null) {  
  83.                 try {  
  84.                     tran.rollback();  
  85.                 } catch (Exception e1) {  
  86.                     e1.printStackTrace();  
  87.                 }  
  88.             }  
  89.         }  
  90.     }  
  91.       
  92.     /**  
  93.      * 对象读取测试(Select方法)  
  94.      */              
  95.     public void testSelect(){  
  96.         String hql = " from TUser where name='byf'";  
  97.         try {  
  98.             List userList = session.createQuery(hql).list();  
  99.             TUser user = (TUser)userList.get(0);  
  100.             System.out.println("user name is " + user.getName());  
  101.               
  102.             for (Iterator iter = user.getAddress().iterator(); iter.hasNext();) {  
  103.                 TAddress addr = (TAddress) iter.next();  
  104.                 System.out.println("user address is " + addr.getAddress());                  
  105.             }  
  106.             Assert.assertEquals(user.getName(), "byf");  
  107.         } catch (Exception e) {  
  108.             e.printStackTrace();  
  109.             Assert.fail(e.getMessage());  
  110.         }  
  111.     }  

说明:
一个问题,由于是单向关联,为了保持关联关系,我们只能通过主控方对被动方进行级联更新。如果被关联方的字段为NOT NULL属性,当Hibernate一对多创建或者更新关联关系时,可能出现约束违例。

例子中T_Address表中的user_id 为NOT NULL,如果在TAddress.hbm.xml映射了全部字段时。创建一个用户并赋予她地址信息,对于T_Address表而言,Hibernate一对多会执行两条sql语句来保存地址信息。

要执行两条SQL语句,是因为关联是单向的,就是说对于TAddress对象而言,并不知道自己应该与那一个TUser对象关联,只能先将user_id设为一个空值。
之后,根据配置文件

  1. <set name="address" table="t_address" cascade="all" order-by="zipcode asc"> 
  2.             <key column="user_id"> 
  3.             key> 
  4.             <one-to-many class="cn.blogjava.start.TAddress" /> 
  5.         set> 

Hibernate一对多数据关联是Hibernate中比较典型的问题,这里只是简单介绍。

【编辑推荐】

  1. 浅析Hibernate一对多数据关联的问题(二)
  2. 对Hibernate中get()与load()不同点分析
  3. Struts-Spring-Hibernate案例
  4. 简述Hibernate配置连接池
  5. 对Hibernate中get()与load()不同点分析
责任编辑:仲衡 来源: baidu
相关推荐

2009-09-23 10:57:02

Hibernate一对

2012-03-21 11:43:41

JavaHibernate

2012-02-08 13:34:08

HibernateJava

2009-09-22 09:55:58

Hibernate实例

2009-06-04 10:34:19

Hibernate一对一对多关系配置

2009-06-04 16:14:22

Hibernate一对Hibernate一对Hibernate多对

2009-06-03 16:27:27

Hibernate一对一关系

2010-04-15 09:09:02

Hibernate

2009-08-17 10:34:51

NHibernate一

2009-06-03 16:18:16

Hibernate关系代码实例

2009-12-23 09:31:11

宽带路由上网故障

2010-07-07 08:33:09

SQL Server学

2009-09-22 17:32:38

Hibernate A

2012-02-23 09:24:52

大数据云计算

2009-06-26 10:15:54

面试HR

2009-07-21 17:31:39

iBATIS一对多映射

2018-04-11 15:33:59

大数据块链去中心化

2009-06-24 07:58:52

Hibernate多数

2009-06-17 14:55:26

Hibernate数据

2022-02-18 11:05:25

Jpa配置Address
点赞
收藏

51CTO技术栈公众号