Hibernate实体关系映射:单向主键一对一关联
2015-12-12 16:38
633 查看
主键单向一对一关联:
1、被控方的主键参照主控方的主键来生成
2、对应数据库表关系为被控方的主键同时参照引用主控方的主键
3、保存被控方对象,需要先保存主控方(不然怎么从native产生主键值,被控方更是获取不到了)
主控方People
People的hbm.xml文件:只是普通的映射文件
从控方IdCard的实体类:
IdCard的hbm.xml文件:负责维护关系
二、测试增删改查
(1)查询
输出效果:
注:如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。
发放
(2)添加
运行结果:
(3)删除
①删从控方
运行结果:
显然,它只删除了从控方的对象,并没有自动关联删除主控方的对象
②删主控方
运行结果:
很显然,直接删除主控方,被控方没有了外键约束关系,这是潍坊约束条件的,所以无法这样删除
③手动先删被控方,再删主控方
就是上面两个方法调用一起意思
运行结果:
这样必须四条语句了呀,没有疑问的
四、修改
运行结果:
综上,单向主键一对一映射关系:从控方的实体类和hbm文件需要负责维护关系,主控方不用;constrained属性会影响save操作和删除操作:save是先主控后从控,delete是先从控后主控。
另:这篇博文用相反的思路,可以参考:/article/1356673.html
1、被控方的主键参照主控方的主键来生成
2、对应数据库表关系为被控方的主键同时参照引用主控方的主键
3、保存被控方对象,需要先保存主控方(不然怎么从native产生主键值,被控方更是获取不到了)
主控方People
public class People implements java.io.Serializable { // Fields private long id; private String name; private long age; private String sex; // Constructors /** default constructor */ public People() { } // Property accessors public long getId() { return this.id; } public void setId(long id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public long getAge() { return this.age; } public void setAge(long age) { this.age = age; } public String getSex() { return this.sex; } public void setSex(String sex) { this.sex = sex; } }
People的hbm.xml文件:只是普通的映射文件
<hibernate-mapping> <class name="com.sjr.bean.People" table="J_PEOPLE" schema="SXBBKF"> <id name="id" type="long"> <column name="ID" precision="10" scale="0" /> <generator class="native"></generator> </id> <property name="name" type="string"> <column name="NAME" length="20" /> </property> <property name="age" type="long"> <column name="AGE" precision="10" scale="0" /> </property> <property name="sex" type="string"> <column name="SEX" length="2" /> </property> </class> </hibernate-mapping>
从控方IdCard的实体类:
public class IdCard implements java.io.Serializable { // Fields private long id; private People people; <span style="color:#ff0000;">//这里加上主控方People类型的属性</span> private String numcode; // Constructors /** default constructor */ public IdCard() { } // Property accessors public long getId() { return this.id; } public void setId(long id) { this.id = id; } public People getPeople() { return this.people; } public void setPeople(People people) { this.people = people; } public String getNumcode() { return this.numcode; } public void setNumcode(String numcode) { this.numcode = numcode; }
IdCard的hbm.xml文件:负责维护关系
<hibernate-mapping> <class name="com.sjr.bean.IdCard" table="J_IDCARD" schema="SXBBKF"> <id name="id" type="long"> <column name="ID" precision="10" scale="0" /> <generator class="foreign"> <!--<span style="color:#ff0000;">从控方的主键生成策略是 foreign 的方式,这里的param属性是它自己对应的属性名</span>--> <param name="property">people</param> </generator> </id> <property name="numcode" type="string"> <column name="NUMCODE" length="20" /> </property> <one-to-one name="people" class="com.sjr.bean.People" constrained="true"></one-to-one> </span>
<span style="font-size:14px;"><span style="white-space:pre"> </span><!--<span style="color:#ff0000;">这里需要one-to-one进行映射,后面的constrained 后面详解,主要影响save、delete的先后顺序而已,详情看这里</span>--> </class> </hibernate-mapping>
二、测试增删改查
(1)查询
//从控方idcard查询操作 public void testidcard(){ Session session=null; try{ session=HibernateUtil.getSession(); IdCard idcard=(IdCard)session.get(IdCard.class, new Long("48"));
</pre><pre name="code" class="java"> //获取IdCard中Id是48的对象,并进而通过一对一的映射关系获取其对应的people的值
System.out.println(idcard.getId()+" "+idcard.getNumcode()); System.out.println(idcard.getPeople().getId()+" "+idcard.getPeople().getName()+" "+idcard.getPeople().getAge()); }catch (Exception e) { e.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }
输出效果:
Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=? 48 3203203201 Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=? 48 张三 20
注:如果constrained=true,hibernate即会延迟加载sql,只把主表的查出来,等有用到关联表的再发sql取。
发放
(2)添加
public void testSaveIdCard(){ Session session=null; try{ session=HibernateUtil.getSession(); session.getTransaction().begin(); People people=new People(); people.setName("张三"); people.setAge(20); people.setSex("M"); //主控方的对象 //session.save(people); IdCard idcard=new IdCard(); idcard.setNumcode("3203203201"); idcard.setPeople(people); session.save(idcard); //constrained为true,则在插入从控方对象前,需要创建一个主控方People的对象,并set给从控方的IdCard对象;保存时只需要保存从控方的对象就行,一次保存2个对象。 session.getTransaction().commit(); }catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }
运行结果:
Hibernate: select hibernate_sequence.nextval from dual Hibernate: insert into SXBBKF.J_PEOPLE (NAME, AGE, SEX, ID) values (?, ?, ?, ?) Hibernate: insert into SXBBKF.J_IDCARD (NUMCODE, ID) values (?, ?)
(3)删除
①删从控方
//删除 从控方 idcard public void testRemoveIdCard(){ Session session=null; try{ session=HibernateUtil.getSession(); session.getTransaction().begin(); /*People people=new People(); people.setName("张三"); people.setAge(20); people.setSex("M");*/ //session.save(people); IdCard idcard=(IdCard)session.get(IdCard.class, new Long("48")); session.delete(idcard); session.getTransaction().commit(); }catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }
运行结果:
Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=? Hibernate: delete from SXBBKF.J_IDCARD where ID=?
显然,它只删除了从控方的对象,并没有自动关联删除主控方的对象
②删主控方
//删除 主控方 people public void testRemovepeople(){ Session session=null; try{ session=HibernateUtil.getSession(); session.getTransaction().begin(); People people=(People)session.get(People.class, new Long("49")); session.delete(people); session.getTransaction().commit(); }catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }
运行结果:
Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=? Hibernate: delete from SXBBKF.J_PEOPLE where ID=? org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update Caused by: java.sql.BatchUpdateException: ORA-02292: 违反完整约束条件 (SXBBKF.FK28F66C40613448E8) - 已找到子记录
很显然,直接删除主控方,被控方没有了外键约束关系,这是潍坊约束条件的,所以无法这样删除
③手动先删被控方,再删主控方
public void removeAll(){ testRemoveIdCard(); testRemovepeople(); }
就是上面两个方法调用一起意思
运行结果:
Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=? Hibernate: delete from SXBBKF.J_IDCARD where ID=?
Hibernate: select people0_.ID as ID1_0_, people0_.NAME as NAME1_0_, people0_.AGE as AGE1_0_, people0_.SEX as SEX1_0_ from SXBBKF.J_PEOPLE people0_ where people0_.ID=?
Hibernate: delete from SXBBKF.J_PEOPLE where ID=?
这样必须四条语句了呀,没有疑问的
四、修改
//修改 从控方 idcard public void testModifyIdCard(){ Session session=null; try{ session=HibernateUtil.getSession(); session.getTransaction().begin(); IdCard idcard=(IdCard)session.get(IdCard.class, new Long("47")); idcard.setNumcode("3203203201010101"); session.update(idcard); //取出记录,重新赋值后update一下就行,没有关联约束关系 session.getTransaction().commit(); }catch (Exception e) { session.getTransaction().rollback(); e.printStackTrace(); }finally{ HibernateUtil.closeSession(); } }
运行结果:
Hibernate: select idcard0_.ID as ID0_0_, idcard0_.NUMCODE as NUMCODE0_0_ from SXBBKF.J_IDCARD idcard0_ where idcard0_.ID=? Hibernate: update SXBBKF.J_IDCARD set NUMCODE=? where ID=?
综上,单向主键一对一映射关系:从控方的实体类和hbm文件需要负责维护关系,主控方不用;constrained属性会影响save操作和删除操作:save是先主控后从控,delete是先从控后主控。
另:这篇博文用相反的思路,可以参考:/article/1356673.html
相关文章推荐
- Hibernate框架学习之一:Hello World程序
- AdaBoost--从原理到实现
- 能量项链
- php中关于函数的小知识
- [深入浅出Windows 10]布局原理
- 转载:10个实用的但偏执的Java编程技术
- cocos2dx lua学习笔记 <一> quick 3.5定义本身C++类是必然lua
- 线段树
- hdu1969 Pie (二分)
- tomcat目录下的startup.bat不能运行
- 由动态库文件dll生成lib库文件
- [Linked List]Rotate List
- 无法从 ajax.googleapis.com 下载问题
- jquery mobile 移动web
- jQuery选择器总结
- 无源RS232转RS485(转)
- MFC中的Invalidate、OnDraw、OnPaint函数的作用
- node.js的安装以及grunt的使用
- 关于win10能上qq不能联网的问题解决方案之一
- HYSBZ - 1036 树的统计