Hibernate一对多数据关联是什么
本篇内容主要讲解“Hibernate一对多数据关联是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate一对多数据关联是什么”吧!
Hibernate一对多数据关联。指的是单向一对多数据关联一个用户有多个地址,在用户类TUser中包含地址类TAddress集合。
Hibernate如果上手了,那么所谓的一对多,多对一,多对多,一对一这些关系,应该很快能理解.下面主要介绍Hibernate一对多的问题。
由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"?> "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"?> "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>
对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; } }
测试代码
既然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(); } } 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(); } } } } 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一对多数据关联是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341