Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射。在Hibernate3.3之前,需单独下载注解开发包

配置持久化类

配置关联关系

下面我们先从多对一单向关联关系讲起,多对一单向关联就是在多的一方植入一的一方的主键作为外键,下面我们先进行初始配置,

在配置的过程中我们会遇到一个问题  就是无论用load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在用的时候才加载对应的信息,节约内存

hibernate中,延迟加载大致可以分为两类,一类是延迟属性加载,另一类是延迟关联实体加载。

普通属性:分两种情况,一种是集合属性,一种是非集合属性(如String、Integer......)

集合属性的延迟加载通过PersistentSet、 PersistentList、PersistentBag、PersistentMap、PersistentSortedMap、 PersistentSortedSet作为代理类来实现,代理类中保存了session以及owner属性,owner属性表示了集合属性所属的one 侧的实体。

非集合类属性的延迟加载相对比较复杂。仅通过@Basic(fetch = FetchType.LAZY)注解是无法实现延迟加载的。需要让实体实现FieldHandled接口,声明FieldHandler属性,通过拦截器 原理注入对应的FieldHandler属性,起到类似于上述代理类的作用,FieldHandler同样也保持了session,以及需要延迟加载的属 性。

我们发现对非集合属性即时设置了@Basic(fetch = FetchType.LAZY)仍无法实现延迟加载,可以看生成的sql语句

接下来 我们会对一对多单向关联进行测试,验证对集合类属性,是否可以起到延迟加载的功能

注意:不可以对有关联关系的属性设置@Transient

配置多对一的单向关联关系  示例

 package cn.happy.entity;

 import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; @Entity
@Table(name = "EMP")
public class Emp {
@Id
@Column(name = "EMPNO")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_num")
@SequenceGenerator(name = "emp_num", sequenceName = "emp_num_id", allocationSize = , initialValue = )
private Integer empNo; @Column(name = "EMPNAME")
private String empName; @ManyToOne()
@JoinColumn(name = "DEPTNO")
/*@Basic(fetch=FetchType.LAZY)*/
private Dept dept; public Emp() {
super();
} public Emp(Integer empNo, String empName) {
super();
this.empNo = empNo;
this.empName = empName;
} public Integer getEmpNo() {
return empNo;
} public void setEmpNo(Integer empNo) {
this.empNo = empNo;
} public String getEmpName() {
return empName;
} public void setEmpName(String empName) {
this.empName = empName;
} public Dept getDept() {
return dept;
} public void setDept(Dept dept) {
this.dept = dept;
}
}
 package cn.happy.entity;

 import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; import org.hibernate.annotations.Cascade; @Entity
@Table(name = "DEPT")
public class Dept {
@Id
@Column(name = "DEPTNO")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
@SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
private Integer deptNo; @Column(name = "DEPTNAME")
private String deptName; public Integer getDeptNo() {
return deptNo;
} public void setDeptNo(Integer deptNo) {
this.deptNo = deptNo;
} public String getDeptName() {
return deptName;
} public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
 /**
* 注解测试多对一映射 员工表(多)对应部门表(一)的映射,即只在员工表中植入部门表的信息
* */
@Test
public void manytooneSingle(){ /**
* 查询操作
* **/
/*SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession(); Emp emp=(Emp)session.load(Emp.class, 4); System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());*/ /**
* 添加操作
* **/
SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
Session session = sf.openSession();
Transaction tx = session.beginTransaction();
Dept dept = (Dept)session.load(Dept.class, 3); Emp emp=new Emp();
emp.setEmpName("户梦艳");
emp.setEmpNo(001);
emp.setDept(dept); Emp emp2=new Emp();
emp2.setEmpName("户梦艳2");
emp2.setEmpNo(002);
emp2.setDept(dept); session.save(emp);
session.save(emp2);
tx.commit();
session.close(); }

一对多双单向配置

 package cn.happy.entity;

 import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; @Entity
@Table(name="Dept")
public class Dept {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
@SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=,initialValue=)
private Integer deptNo;
@Column
private String deptName; @OneToMany(cascade={CascadeType.ALL})
@JoinColumn(name="deptno")
private Set<Emp> emps=new HashSet<Emp>(); public Set<Emp> getEmps() {
return emps;
} public void setEmps(Set<Emp> emps) {
this.emps = emps;
} public Integer getDeptNo() {
return deptNo;
} public void setDeptNo(Integer deptNo) {
this.deptNo = deptNo;
} public String getDeptName() {
return deptName;
} public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
 package cn.happy.entity;

 import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; import org.hibernate.bytecode.javassist.FieldHandled;
import org.hibernate.bytecode.javassist.FieldHandler; @Entity
@Table(name = "EMP")
public class Emp { @Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
@SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=,initialValue=)
private Integer empNo; @Column
private String empName; // @ManyToOne
// @JoinColumn(name="deptno")
// @Basic(fetch=FetchType.LAZY)
// private Dept dept;
//
// public Dept getDept() {
// return dept;
// }
//
// public void setDept(Dept dept) {
// this.dept = dept;
// } public Emp() {
super();
} public Emp(Integer empNo, String empName) {
super();
this.empNo = empNo;
this.empName = empName;
} public Integer getEmpNo() {
return empNo;
} public void setEmpNo(Integer empNo) {
this.empNo = empNo;
} public String getEmpName() {
return empName;
} public void setEmpName(String empName) {
this.empName = empName;
} }
 /**
* 测试一对多单向添加操作
* */
@Test
public void insertOneToManySingle(){
Emp emp=new Emp();
emp.setEmpName("李小鹏"); Emp emp2=new Emp();
emp2.setEmpName("王想想"); Dept dept=new Dept();
dept.setDeptName("教务部");
//设置级联操作
dept.getEmps().add(emp);
dept.getEmps().add(emp2); session.save(dept);
tx.commit();
System.out.println("insert ok"); }
     /**
* 测试一对多单向查询操作
* */
@Test
public void selectOneToManySingle(){
Dept dept = (Dept)session.load(Dept.class, );
System.out.println("======================");
System.out.println("部门名称:"+dept.getDeptName());
System.out.println("=======================");
//体现了延迟加载
for (Emp emp : dept.getEmps()) {
System.out.println("雇员名称:"+emp.getEmpName());
}
//Emp emp = (Emp)session.load(Emp.class, 1); }

一对多双向配置

 package cn.happy.entity;

 import java.util.HashSet;
import java.util.Set; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; @Entity
@Table(name="Dept")
public class Dept {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
@SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=,initialValue=)
private Integer deptNo;
@Column
private String deptName; @OneToMany(mappedBy="dept",cascade={CascadeType.ALL}) private Set<Emp> emps=new HashSet<Emp>(); public Set<Emp> getEmps() {
return emps;
} public void setEmps(Set<Emp> emps) {
this.emps = emps;
} public Integer getDeptNo() {
return deptNo;
} public void setDeptNo(Integer deptNo) {
this.deptNo = deptNo;
} public String getDeptName() {
return deptName;
} public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
 package cn.happy.entity;

 import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient; import org.hibernate.bytecode.javassist.FieldHandled;
import org.hibernate.bytecode.javassist.FieldHandler; @Entity
@Table(name = "EMP")
public class Emp { @Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
@SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=,initialValue=)
private Integer empNo; @Column
private String empName; @ManyToOne
@JoinColumn(name="deptno")
@Basic(fetch=FetchType.LAZY)
private Dept dept; public Dept getDept() {
return dept;
} public void setDept(Dept dept) {
this.dept = dept;
} public Emp() {
super();
} public Emp(Integer empNo, String empName) {
super();
this.empNo = empNo;
this.empName = empName;
} public Integer getEmpNo() {
return empNo;
} public void setEmpNo(Integer empNo) {
this.empNo = empNo;
} public String getEmpName() {
return empName;
} public void setEmpName(String empName) {
this.empName = empName;
} }
     /**
* 双向一对多的添加操作
* */
@Test
public void oneToManyDouble(){
Dept dept=new Dept();
dept.setDeptName("财务部"); Emp emp=new Emp();
emp.setEmpName("邹乐");
emp.setDept(dept); Emp emp2=new Emp();
emp2.setEmpName("范子阳");
emp2.setDept(dept); dept.getEmps().add(emp);
dept.getEmps().add(emp2); session.save(dept);
tx.commit();
}
 /**
* 双向一对多的查询操作
* */
@Test
public void selectOneToManyDouble(){ Dept dept = (Dept)session.load(Dept.class, );
System.out.println("部门名称:"+dept.getDeptName());
for (Emp emp : dept.getEmps()) {
System.out.println("职工姓名:"+emp.getEmpName());
} System.out.println("=================================================="); Emp emp = (Emp)session.load(Emp.class, );
System.out.println("职工姓名:"+emp.getEmpName()+"\t部门名称:"+emp.getDept().getDeptName());
}

Hibernate中用注解配置一对多双向关联和多对一单向关联的更多相关文章

  1. Hibernate笔记——关联关系配置(一对多、一对一和多对多)

    原文:http://www.cnblogs.com/otomedaybreak/archive/2012/01/20/2327695.html ============================ ...

  2. Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  3. [置顶] Hibernate从入门到精通(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类似,只是在多 ...

  4. Hibernate(七)多对一单向关联映射

    上次的博文Hibernate从入门到精通(六)一对一双向关联映射中我们介绍了一下一对一双向关联映射,本 次博文我们讲解一下多对一关联映射 多对一单向关联映射 多对一关联映射与一对一关联映射类 似,只是 ...

  5. Hibernate多对多单向关联和双向关联 --Hibernate框架

    Hibernate关联关系中相对比较特殊的就是多对多关联,多对多关联与一对一关联和一对多关联不同,多对多关联需要另外一张映射表用于保存多对多映射信息.本例介绍多对多单向关联和双向关联.单向关联 :指具 ...

  6. Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联

    2018-11-10  22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...

  7. hibernate多对一单向关联注解方式

    多对一单向关联,在多的一方加上一的一方作为外键.在程序里表现为:在多的一方加上一的引用. 小组类Group,用户User: Group: package com.oracle.hibernate; i ...

  8. Hibernate从入门到精通(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映射之前,首先看 ...

  9. Hibernate(十)多对多单向关联映射

    上一篇文章Hibernate从入门到精通(九)一对多双向关联映射中我们讲解了一下关于一对多关联映射的 相关内容,这次我们继续多对多单向关联映射. 多对多单向关联映射 在讲解多对多单向关联映 射之前,首 ...

随机推荐

  1. 易语言制作的QQ聊天中常用的GIF图片【带源码下载】

    该软件调用网页实现表情包制作,使用了精益模块. 最近比较火的王境泽.张学友.切格瓦拉.为所欲为.今天星期五.黑人问号脸.偷电瓶车.诸葛孔明.金坷垃等都可以通过此软件在线制作属于你的表情包. 太困了懒得 ...

  2. JZOJ 3534. 【NOIP2013提高组day1】货车运输

    Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的 ...

  3. openwrt(二) 配置openwrt及编译

    导航 1. 配置openwrt 2. 编译openwrt 3. 错误记录 1. 配置openwrt 在openwrt的根目录下,执行make menuconfig. 这个界面我也只是了解了这两个选项而 ...

  4. ESP-01S-ESP8266入门教程

    1.模块实物 2.引脚说明 3.连接说明,按下图将引脚连接到PC的串口(VCC接3V,GND接地,TX接串口TX,RX接串口的RX,CH_PD接3V,否则wifi不工作) 4.通过该PC串口配置WiF ...

  5. Python文章推荐1

    Table of Contents 1. 分享最近看到的python相关的几篇好文(我只是想偷懒) 1.1. 形象解释了什么是GIL 1.2. 知乎上 Pythonic 相关 1.3. evil &q ...

  6. android 布局preview 技巧

    最近开始看老外写的文章,博客,嗯,不能说比国人写的好,但是感觉看着很爽.真的,一手资料就是爽. 嗯,自己做得不错,第一次看外文博客,我知道自己怎么看的,一句话一句话看下来的,越看越有感觉. 下面这个 ...

  7. 强烈推荐android初学者,android进阶者看看这个系列教程

    强烈推荐android初学者,android进阶者看看这个系列教程 转载 2015年05月30日 23:05:44 695 为什么要研究Android,是因为它够庞大,它够复杂,他激起了我作为一个程序 ...

  8. 网易考拉Android客户端网络模块设计

    本文来自网易云社区 作者:王鲁才 客户端开发中不可避免的需要接触到访问网络的需求,如何把访问网络模块设计的更具有扩展性是每一个移动开发者不得不面对的事情.现在有很多主流的网络请求处理框架,如Squar ...

  9. 剑指Offer - 九度1512 - 用两个栈实现队列

    剑指Offer - 九度1512 - 用两个栈实现队列2013-11-29 21:23 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作.队列中的元素为int类型. 输入: 每个输入 ...

  10. 《Cracking the Coding Interview》——第18章:难题——题目9

    2014-04-29 04:18 题目:有一连串的数被读入,设计一个数据结构,能随时返回当前所有数的中位数. 解法:用一个大顶堆,一个小顶堆将数分成数量最接近的两份,就能轻松得到中位数了. 代码: / ...