<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    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)
    );


    3.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;
        }
    }

    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;
        }

    }

    3.配置文件
    TUser.hbm.xml
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "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>

    TAddress.hbm.xml
    注意:沒有配置user_id字段。
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "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>

    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());
            }
        }
    }

    說明:
    一個問題,由于是單向關聯,為了保持關聯關系,我們只能通過主控方對被動方進行級聯更新。如果被關聯方的字段為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>
    由TUser對象將自身的id賦給addr.user_id,這樣導致addr屬性值變動,在事物提交的時候,會進行update。

    1)當save該用戶的時候,
    insert into t_address  (user_id, address, zipcode, tel) value (null, "HongKong", "233123", "1123")

    2)當tx.commit()時:
    update t_address user_id="1", address="HongKong", zipcode="233123",tel="1123" where id=2;

    這樣,在save user時,就會出現約束違例。

    調整方法:
    可以在定義數據表字段時候,不加NOT NULL約束。或者在開始為user_id隨意賦一個非空值(因為還要update,不正確也沒關系),或者將user_id字段從TAddress.hbm.xml中刪除(本例就是這樣實現)。

    但是這些都是權宜之計,用兩條SQL語句完成一次數據庫操作,性能低下。
    而雙向一對多解決了這個問題。
    下面來實現雙向關聯:
    修改配置文件
    TUser.hbm.xml
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "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" 
                inverse
    ="true"
                cascade
    ="all" 
                order-by
    ="zipcode asc"
                
    >
                
    <key column="user_id">
                
    </key>
                
    <one-to-many class="cn.blogjava.start.TAddress" />
            
    </set>
        
    </class>
    </hibernate-mapping>

    設定inverse="true",表明將TUser類作為被動類,將數據關聯的維護工作交給關聯對象TAddress來管理。
    在one-to-many模型中,將many一方設為主控方有助于性能的改善。(讓總理記住每個人困難,但是每個人記住總理方便)

    TAddress.hbm.xml
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "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" />
            
    <many-to-one
                      
    name="user" 
                      class
    ="cn.blogjava.start.TUser"

                      cascade
    ="none"
                      outer-join
    ="auto"
                      update
    ="true"                  
                      insert
    ="true"

                      access
    ="property"
                      column
    ="user_id"
                      not-null
    ="true"
            
    />
        
    </class>
    </hibernate-mapping>

    2.對TAddress.java做如下改造:
    去掉user_id字段,增加user字段,和getter,setter方法。
    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 idx;
        
    private TUser user;
        
        
    public TUser getUser() {
            
    return user;
        }
        
    public void setUser(TUser user) {
            
    this.user = user;
        }
        
    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 String getZipcode() {
            
    return zipcode;
        }
        
    public void setZipcode(String zipcode) {
            
    this.zipcode = zipcode;
        }

    }

    4.測試代碼
    既然TUser不維護關聯關系,需要TAddress需要自己來維護TUser,所以需要addr.setUser(user);
    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");
                addr.setUser(user);
                
                TAddress addr2 
    = new TAddress();
                addr2.setTel(
    "139");
                addr2.setZipcode(
    "116001");
                addr2.setAddress(
    "dalian");       
                addr2.setUser(user);

                TAddress addr3 
    = new TAddress();
                addr3.setTel(
    "136");
                addr3.setZipcode(
    "100080");
                addr3.setAddress(
    "beijing");
                addr3.setUser(user);
                
                
    //設置關聯
                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());
            }

        }

    }

    posted on 2006-07-04 14:45 baim 閱讀(2684) 評論(5)  編輯  收藏 所屬分類: 開源軟件框架

    評論

    # re: Hibernate一對多數據關聯 2008-01-07 19:22 pretender

    很全面,很感謝!!  回復  更多評論   

    # re: Hibernate一對多數據關聯 2008-02-12 18:33 Asmer

    精辟!贊@!!  回復  更多評論   

    # re: Hibernate一對多數據關聯[未登錄] 2008-09-24 20:09 kk

    收藏,推薦
    感激,學習  回復  更多評論   

    # re: Hibernate一對多數據關聯 2009-09-24 14:27 贊你

    簡單就是美  回復  更多評論   

    # re: Hibernate一對多數據關聯 2009-10-20 17:36 很高

    很屁精  回復  更多評論   

    <2009年10月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    常用鏈接

    隨筆分類(27)

    隨筆檔案(28)

    搜索

    最新評論

    主站蜘蛛池模板: 色噜噜噜噜亚洲第一| 亚洲伊人久久大香线蕉综合图片| 亚洲AV中文无码字幕色三| 色综合久久精品亚洲国产| 西西大胆无码视频免费| 最新亚洲春色Av无码专区| 亚洲狠狠爱综合影院婷婷| 亚洲人成网站18禁止久久影院| 久久免费精彩视频| 亚洲欧美日韩综合俺去了| 好吊妞788免费视频播放| 91av免费在线视频| 亚洲综合色7777情网站777| 亚洲午夜精品久久久久久浪潮| 男女啪啪免费体验区| 亚洲欧洲日产国码www| 真实国产乱子伦精品免费| 久久久久久亚洲精品成人| 免费不卡中文字幕在线| 16女性下面扒开无遮挡免费| 免费中文字幕视频| 亚洲中文无码a∨在线观看| 在线观看亚洲成人| 免费看片A级毛片免费看| 久久大香伊焦在人线免费| 无套内射无矿码免费看黄| 精品国产亚洲男女在线线电影 | 成人免费视频一区二区| 亚洲高清视频免费| 永久免费AV无码国产网站| 青青操在线免费观看| 亚洲av无一区二区三区| 亚洲电影在线播放| 亚洲国产精华液网站w| 免费视频爱爱太爽了| 三年片免费观看大全国语| 日韩亚洲翔田千里在线| 亚洲三级中文字幕| 亚洲色图综合网站| 国产高清在线免费视频| aa级一级天堂片免费观看|