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

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

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

    一對多數(shù)據(jù)關(guān)聯(lián)

    一.單向一對多數(shù)據(jù)關(guān)聯(lián)
    一個用戶有多個地址,在用戶類TUser中包含地址類TAddress集合。

    1.數(shù)據(jù)模型

    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");
    ????????????
    ????????????
    //設(shè)置關(guān)聯(lián)
    ????????????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());
    ????????}
    ????}
    }

    說明:
    一個問題,由于是單向關(guān)聯(lián),為了保持關(guān)聯(lián)關(guān)系,我們只能通過主控方對被動方進行級聯(lián)更新。如果被關(guān)聯(lián)方的字段為NOT NULL屬性,當Hibernate創(chuàng)建或者更新關(guān)聯(lián)關(guān)系時,可能出現(xiàn)約束違例。
    例子中T_Address表中的user_id 為NOT NULL,如果在TAddress.hbm.xml映射了全部字段時。創(chuàng)建一個用戶并賦予她地址信息,對于T_Address表而言,hibernate會執(zhí)行兩條sql語句來保存地址信息。

    要執(zhí)行兩條SQL語句,是因為關(guān)聯(lián)是單向的,就是說對于TAddress對象而言,并不知道自己應(yīng)該與那一個TUser對象關(guān)聯(lián),只能先將user_id設(shè)為一個空值。
    之后,根據(jù)配置文件
    ????????<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,這樣導(dǎo)致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時,就會出現(xiàn)約束違例。

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

    但是這些都是權(quán)宜之計,用兩條SQL語句完成一次數(shù)據(jù)庫操作,性能低下。
    而雙向一對多解決了這個問題。
    下面來實現(xiàn)雙向關(guān)聯(lián):
    修改配置文件
    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>

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

    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不維護關(guān)聯(lián)關(guān)系,需要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);
    ????????????
    ????????????
    //設(shè)置關(guān)聯(lián)
    ????????????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 閱讀(555) 評論(1)  編輯  收藏 所屬分類: ORM:Hibernate及其他
    主站蜘蛛池模板: 亚洲av永久无码天堂网| 亚洲a一级免费视频| 亚洲激情电影在线| 国产亚洲精品不卡在线| 免费无码又爽又刺激高潮的视频| 国产午夜无码精品免费看| 国产亚洲综合精品一区二区三区| 亚洲一区二区三区在线| 亚洲精选在线观看| 亚洲欧洲日产国码av系列天堂| 国产成人免费福利网站| 免费观看黄网站在线播放| 最近免费中文字幕mv电影| 两个人的视频www免费| 美女被免费视频网站| 精品国产亚洲一区二区三区在线观看| 亚洲成人网在线观看| 精品亚洲成AV人在线观看| 亚洲色偷偷综合亚洲AVYP| 亚洲妓女综合网99| 日本高清免费网站| 午夜福利不卡片在线播放免费| 免费精品99久久国产综合精品| 国产99精品一区二区三区免费| 男男gvh肉在线观看免费| 亚洲日本一线产区和二线| 亚洲熟妇无码av另类vr影视| 国产成+人+综合+亚洲专| 亚洲国产精品无码久久久| 亚洲电影在线免费观看| 亚洲精品美女在线观看| 亚洲精品国产肉丝袜久久| 亚洲欧洲精品在线| 亚洲毛片免费观看| 亚洲精品456在线播放| 中文字幕亚洲免费无线观看日本| 久久伊人久久亚洲综合| 亚洲AV无一区二区三区久久| 亚洲情a成黄在线观看动漫尤物| 亚洲尹人香蕉网在线视颅| 亚洲图片校园春色|