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

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

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

    一對多數據關聯

    一.單向一對多數據關聯
    一個用戶有多個地址,在用戶類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-05 15:13 knowhow 閱讀(556) 評論(1)  編輯  收藏 所屬分類: ORM:Hibernate及其他
    主站蜘蛛池模板: 日韩av无码成人无码免费 | 亚洲精品无码成人片久久| 在线观看亚洲天天一三视| 亚洲精品午夜无码电影网| 亚洲AV成人一区二区三区AV| 亚洲国色天香视频| 亚洲爆乳大丰满无码专区| 九九久久国产精品免费热6| a级毛片高清免费视频就| 亚洲高清视频免费| 蜜臀91精品国产免费观看| 亚洲欧洲国产成人综合在线观看| 亚洲成AV人片在线观看WWW| 亚洲伦理一二三四| 免费一级毛suv好看的国产网站| av永久免费网站在线观看| 四虎永久在线观看免费网站网址| 国产成人免费片在线观看| 亚洲一区无码中文字幕| 亚洲噜噜噜噜噜影院在线播放| 狠狠入ady亚洲精品| 国产一区二区三区免费| 成人男女网18免费视频| 国产亚洲日韩一区二区三区| 亚洲宅男天堂a在线| 日亚毛片免费乱码不卡一区| 57pao一国产成永久免费| 四虎影视精品永久免费网站| 亚洲日本中文字幕区| 日韩色日韩视频亚洲网站| 麻豆成人久久精品二区三区免费| 在线看片无码永久免费aⅴ| 亚洲AV综合色一区二区三区| 亚洲精品国产第一综合99久久| 大地资源网高清在线观看免费| 性一交一乱一视频免费看| 亚洲无线码一区二区三区| 亚洲精品精华液一区二区| 91禁漫免费进入| 亚洲一级特黄大片无码毛片| 中文文字幕文字幕亚洲色|