淺析Hibernate一對多數(shù)據(jù)關(guān)聯(lián)的問題(二)
Hibernate一對多數(shù)據(jù)關(guān)聯(lián)。指的是單向一對多數(shù)據(jù)關(guān)聯(lián)一個用戶有多個地址,在用戶類TUser中包含地址類TAddress集合。
Hibernate如果上手了,那么所謂的一對多,多對一,多對多,一對一這些關(guān)系,應(yīng)該很快能理解.下面主要介紹Hibernate一對多的問題。
1.由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時,就會出現(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"?>
- "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" />
- < SPAN>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">
- < SPAN>key>
- <one-to-many class="cn.blogjava.start.TAddress" />
- < SPAN>set>
- < SPAN>class>
- < SPAN>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"?>
- "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" />
- < SPAN>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"
- />
- < SPAN>class>
- < SPAN>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;
- }
- }
3.測試代碼
既然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());
- }
- }
- }
以上介紹Hibernate一對多數(shù)據(jù)關(guān)聯(lián)。
【編輯推薦】