A:先讲讲一对一的关系(欲知其他关系,请看下篇)

a:主键关联的一对一关系

一对一关系一般用主键关联,也就是说用主键值来维护两者的关系,一个表的主键存放另一个表的主键值。例如在员工与帐号中,我们取员工表的主键值作为帐号的主键值。

我们一员工表和账号表为例:(员工表是主表,账号表是从表)

对持久化的对象的封装和get,set方法已省略,值得注意的是:vo中必须相互写上对方的对象:如在employee中要定义private AccountVo account,在account中也要写上对应的employee,   我们只对映射文件与测试编写

主表的mapping配置:使用了one-to-one

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ysq.vo">
<class name="EmployeeVo" table="employee">
<id name="oid">
<generator class="sequence">
<param name="sequence">dept_seq</param> <!-- 使用的Oracle数据库,主键增长方式是sequence-->
</generator>
</id>
<property name="deptid">
<column name="deptid"/>
</property>
<property name="empName">
<column name="empName" length="20"/>
</property>
<property name="sex">
<column name="sex" length="2"/>
</property>
<property name="birthday">
<column name="birthday" length="30"/>
</property>
<property name="school">
<column name="school" length="20"/>
</property>
<property name="major">
<column name="major" length="10"/>
</property>
<property name="degree">
<column name="degree"/>
</property>
<property name="phone">
<column name="phone" length="12"/>
</property> <one-to-one name="account" class="AccountVo" cascade="all"></one-to-one>
</class>
</hibernate-mapping>

从表的mapping配置:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ysq.vo">
<class name="AccountVo" table="account">
<id name="oid" type="java.lang.Integer">
<column name="oid" />
<generator class="foreign" ><!-- 采用外键方式生成主键值 -->
<param name="property">employee</param><!-- 表示取员工的主键值作为帐号的主键值,这里的employee要跟下面的<one-to-one>的name属性值一致 -->
</generator>
</id>
<property name="username" type="java.lang.String">
<column name="username" length="20" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" />
</property>
<property name="email" type="java.lang.String">
<column name="email" length="100" />
</property>
<property name="inactive" type="java.lang.String">
<column name="inactive" length="1" />
</property>
<one-to-one name="employee" class= "EmployeeVo" constrained="true"></one-to-one>
</class>
</hibernate-mapping>

对应的测试类:

 //添加员工信息,同时也添加了对应的账号
@Test
public void addEmployee(){
EmployeeVo employee = new EmployeeVo();
AccountVo account = new AccountVo(); account.setUsername("zhangsan21");
account.setEmail("csw-java@163.com");
account.setPassword("123"); employee.setBirthday("2003-09-09");
employee.setEmpName("lizi21");
employee.setPhone("1232132"); Session session = SessionFactoryUtils.getSession();
Transaction tr = session.beginTransaction();
try {
tr.begin();
/* //保存员工
session.save(employee);
//保存帐号
account.setEmployee(employee);
session.save(account);*/ //也可以进行双向关联,对主表进行save()
account.setEmployee(employee);
employee.setAccount(account);
session.save(employee);//保存员工时,级联保存了账号
tr.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
session.close();
} }
@Test    //修改和删除
public void updateEmp(){
.......
try {
tr.begin();
//设置了双向关联,当对员工修改时,对account也进行了修改
employee.setAccount(account);
account.setEmployee(employee);
session.update(employee);
tr.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
session.close();
} }
@Test
public void deleteEmp(){
........
Session session = SessionFactoryUtils.getSession();
Transaction tr = session.beginTransaction();
try {
tr.begin();
//设置双向关联
employee.setAccount(account);
account.setEmployee(employee);
 
 
               session.delete(employee);
tr.commit();
} catch (HibernateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
session.close();
}
}
@Test   //查询信息
public void findEmployeeById(){
Session session = SessionFactoryUtils.getSession();
//一对一默认的延迟加载 get(class clazz,id)只针对通过id查询
EmployeeVo employee = (EmployeeVo)session.get(EmployeeVo.class, 6); session.close(); System.out.println(employee);
System.out.println(employee.getAccount().getUsername());//注意:我这里的打印是引用了vo中的toString()方法,但只能在一个封装类中写toString()方法,同时写两个会报错的
} @SuppressWarnings("unchecked")
@Test
public void findEmployee(){
Session session = SessionFactoryUtils.getSession();
//一对一默认的延迟加载[HQL]
List<EmployeeVo> emps = session.createQuery("from EmployeeVo").list(); session.close();
for (EmployeeVo employee2 : emps) {
System.out.println(employee2);
System.out.println(employee2.getAccount().getUsername());
System.out.println();
}
}

b:使用外键关联一对一的关系

只需要包对应的mapping文件中修改一些就可以了

如:employee中的:<one-to-one name="account" class="AccountVo" cascade="all"></one-to-one>需要修改如下:

<!--因为现在员工对帐号是采用外键关联,所以在这里得加一个属性property-ref="employee"指定对方many-to-one 的name属性值-->
     <one-to-one name="account" class="AccountVo" property-ref="employee" cascade="all"></one-to-one>

account中的:<one-to-one name="employee" class= "EmployeeVo" constrained="true"></one-to-one>  需要修改如下:

<many-to-one name="employee" class="EmployeeVo" column="empid" unique="true"></many-to-one><!--在这边不再配置one-to-one了,而是用many-to-one,并且在many-to-one中加了unique="true"属性,表示唯一的多对一,也就成了一对一了,这里还得注意必须得指定外键column="empid" -->

Hibernate中的一对一关系详解(1)的更多相关文章

  1. 分享知识-快乐自己:Hibernate 中Criteria Query查询详解

    1):Hibernate 中Criteria Query查询详解 当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中. 此外,Hibernate还支持Cr ...

  2. Hibernate中的事务处理流程详解

    一.Hibernate操作的基本流程 使用 Hibernate 进行数据持久化操作,通常有如下步骤: 1.编写持久化类: POJO + 映射文件 2.获取 Configuration 对象 3.获取 ...

  3. Hibernate 中Criteria Query查询详解【转】

    当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中.此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询 ...

  4. Hibernate中的多对多关系详解(3)​

    前面两节我们讲到了一对一的关系,一对多,多对一的关系,相对来说,是比较简单的,但有时,我们也会遇到多对多的关系,比如说:角色与权限的关系,就是典型的多对多的关系,因此,我有必要对这种关系详解,以便大家 ...

  5. Hibernate中的一对一映射关系

    Hibernate中的一对一映射关系有两种实现方法(单向一对一,和双向一对一)(一对一关系:例如一个department只能有一个manager) 单向和双向有什么区别呢??例如若是单向一对一,比如在 ...

  6. Hibernate配置文件和映射文件详解

    Hibernate是一个彻底的ORM(Object Relational Mapping,对象关系映射)开源框架. 我们先看一下官方文档所给出的,Hibernate 体系结构的高层视图: 其中PO=P ...

  7. slf4j log4j logback关系详解和相关用法

    slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...

  8. c++中vector的用法详解

    c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...

  9. 【转】UML类图与类的关系详解

    UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(D ...

随机推荐

  1. 站在巨人的肩膀上学习Android开发

    我们知道,一開始最好的学习方法是模仿,尤其是模仿巨人. 那说到Android开发的模仿自然就是分析并研究主流程序的布局.实现方法.进而提升自己的技术. 第一招----逆向project 要分析&quo ...

  2. MVC中一般为什么用IQueryable而不是用IList

    IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实 ...

  3. 系统的启动模式(启动级别)的改动---使用upstart启动机制的

    /*********************************************************************  * Author  : Samson  * Date   ...

  4. ATL 工程下添加右击菜单

    首先在dllmain.cpp中添加如下声明 HINSTANCE g_hInstance;  g_hInstance = hInstance; 源码如下: CPoint point;  ::GetCur ...

  5. 分分钟解决iOS开发中App启动广告的功能

    前不久有朋友需要一个启动广告的功能,我说网上有挺多的,他说,看的不是很理想.想让我写一个,于是乎,抽空写了一个,代码通俗易懂,简单的封装了一下,各种事件用block回调的,有俩种样式的广告,一种是全屏 ...

  6. java 流程执行 循环 foreach循环

    一. if分支 1. 结构  if  else if   else 2.执行原则 if  if  if 结构  会一直去执行()里的判断语句 if else if  else if 结构  只要一条( ...

  7. Pivotal Cloud Foundry学习笔记(1)

    PCF是一个PAAS平台 注册PCF账号 https://account.run.pivotal.io/sign-up 安装cf CLI 访问 https://console.run.pivotal. ...

  8. 使用gradle构建java项目

    gradle是什么东东 gradle是继ant,maven之后另外一种的面向java的自动化项目构建工具,他是基于groovy语言的.相对于ant,maven,gradle显得更加简单. 安装grad ...

  9. file的name值

    在picturelibrary中取一张jpg文件, 其Name值为  "NoThumbnail.jpg",注意后面的.jpg             foreach (SPFile ...

  10. python基础知识三

    在考虑它们的运算时,一定要想到python是一门面向对象语言,它对类型的要求是不那么严格的,因为在完全面向对象的语言中,一切都是对象. 那么让我们重新 考虑+ -  *  /等操作,不再拘泥于传统的数 ...