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

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

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

1.数据模型

2.表定义sql

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

POJO类
TUser.java

package cn.blogjava.start;  
 
import java.util.Set;  
 
public class TUser  implements java.io.Serializable {  
    // Fields      
     private Integer id;  
     private Integer age;  
     private String name;  
     private Set address;  
 
 
    // Constructors  
 
    public Integer getAge() {  
        return age;  
    }  
 
    public void setAge(Integer age) {  
        this.age = age;  
    }  
 
 
    public Set getAddress() {  
        return address;  
    }  
 
    public void setAddress(Set address) {  
        this.address = address;  
    }  
 
    /** default constructor */  
    public TUser() {  
    }  
      
    /** constructor with id */  
    public TUser(Integer id) {  
        this.id = id;  
    }  
 
    // Property accessors  
 
    public Integer getId() {  
        return this.id;  
    }  
      
    public void setId(Integer id) {  
        this.id = id;  
    }  
 
    public String getName() {  
        return this.name;  
    }  
      
    public void setName(String name) {  
        this.name = name;  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.

TAddress.java

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

3.配置文件
TUser.hbm.xml

xml version="1.0"?> 

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

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

xml version="1.0"?> 

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

4.测试代码

package cn.blogjava.start;  
 
import java.util.HashSet;  
import java.util.Iterator;  
import java.util.List;  
 
import junit.framework.Assert;  
import junit.framework.TestCase;  
 
import org.hibernate.HibernateException;  
import org.hibernate.Session;  
import org.hibernate.SessionFactory;  
import org.hibernate.Transaction;  
import org.hibernate.cfg.Configuration;  
 
 
public class HibernateTest extends TestCase {  
      
    Session session = null;  
 
    protected void setUp() {  
        try {  
            Configuration config = new Configuration().configure();  
            SessionFactory sessionFactory = config.buildSessionFactory();  
            session = sessionFactory.openSession();  
              
        } catch (HibernateException e) {  
            e.printStackTrace();  
        }          
    }  
 
    protected void tearDown() {  
        try {  
            session.close();          
        } catch (HibernateException e) {  
            e.printStackTrace();  
        }          
    }      
      
    /**  
     * 对象持久化测试(Insert方法)  
     */          
    public void testInsert() {  
        Transaction tran = null;  
        try {  
          
            TUser user = new TUser();  
            user.setName("byf");  
            user.setAge(new Integer(26));  
              
            TAddress addr = new TAddress();  
            addr.setTel("1123");  
            addr.setZipcode("233123");  
            addr.setAddress("HongKong");  
              
            TAddress addr2 = new TAddress();  
            addr2.setTel("139");  
            addr2.setZipcode("116001");  
            addr2.setAddress("dalian");              
 
            TAddress addr3 = new TAddress();  
            addr3.setTel("136");  
            addr3.setZipcode("100080");  
            addr3.setAddress("beijing");  
              
            //设置关联  
            HashSet set = new HashSet();  
            set.add(addr);  
            set.add(addr2);  
            set.add(addr3);  
            user.setAddress(set);  
                                     
            tran = session.beginTransaction();                                  
            //插入user信息  
            session.save(user);  
            session.flush();  
            tran.commit();  
            Assert.assertEquals(user.getId().intValue()>0 ,true);  
        } catch (HibernateException e) {  
            e.printStackTrace();  
            Assert.fail(e.getMessage());  
            if(tran != null) {  
                try {  
                    tran.rollback();  
                } catch (Exception e1) {  
                    e1.printStackTrace();  
                }  
            }  
        }  
    }  
      
    /**  
     * 对象读取测试(Select方法)  
     */              
    public void testSelect(){  
        String hql = " from TUser where name='byf'";  
        try {  
            List userList = session.createQuery(hql).list();  
            TUser user = (TUser)userList.get(0);  
            System.out.println("user name is " + user.getName());  
              
            for (Iterator iter = user.getAddress().iterator(); iter.hasNext();) {  
                TAddress addr = (TAddress) iter.next();  
                System.out.println("user address is " + addr.getAddress());                  
            }  
            Assert.assertEquals(user.getName(), "byf");  
        } catch (Exception e) {  
            e.printStackTrace();  
            Assert.fail(e.getMessage());  
        }  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.

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

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

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

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

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

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

宽带路由上网故障

2009-09-22 17:32:38

Hibernate A

2010-07-07 08:33:09

SQL Server学

2009-06-26 10:15:54

面试HR

2009-07-21 17:31:39

iBATIS一对多映射

2012-02-23 09:24:52

大数据云计算

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技术栈公众号