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
配置多对一的单向关联关系 示例
1 package cn.happy.entity;
2
3 import javax.persistence.Basic;
4 import javax.persistence.Column;
5 import javax.persistence.Entity;
6 import javax.persistence.FetchType;
7 import javax.persistence.GeneratedValue;
8 import javax.persistence.GenerationType;
9 import javax.persistence.Id;
10 import javax.persistence.JoinColumn;
11 import javax.persistence.ManyToOne;
12 import javax.persistence.SequenceGenerator;
13 import javax.persistence.Table;
14 import javax.persistence.Transient;
15
16 @Entity
17 @Table(name = "EMP")
18 public class Emp {
19 @Id
20 @Column(name = "EMPNO")
21 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "emp_num")
22 @SequenceGenerator(name = "emp_num", sequenceName = "emp_num_id", allocationSize = 1, initialValue = 1)
23 private Integer empNo;
24
25 @Column(name = "EMPNAME")
26 private String empName;
27
28 @ManyToOne()
29 @JoinColumn(name = "DEPTNO")
30 /*@Basic(fetch=FetchType.LAZY)*/
31 private Dept dept;
32
33
34 public Emp() {
35 super();
36 }
37
38 public Emp(Integer empNo, String empName) {
39 super();
40 this.empNo = empNo;
41 this.empName = empName;
42 }
43
44 public Integer getEmpNo() {
45 return empNo;
46 }
47
48 public void setEmpNo(Integer empNo) {
49 this.empNo = empNo;
50 }
51
52 public String getEmpName() {
53 return empName;
54 }
55
56 public void setEmpName(String empName) {
57 this.empName = empName;
58 }
59
60 public Dept getDept() {
61 return dept;
62 }
63
64 public void setDept(Dept dept) {
65 this.dept = dept;
66 }
67 }
1 package cn.happy.entity;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import javax.persistence.CascadeType;
7 import javax.persistence.Column;
8 import javax.persistence.Entity;
9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.JoinColumn;
13 import javax.persistence.OneToMany;
14 import javax.persistence.SequenceGenerator;
15 import javax.persistence.Table;
16 import javax.persistence.Transient;
17
18 import org.hibernate.annotations.Cascade;
19
20 @Entity
21 @Table(name = "DEPT")
22 public class Dept {
23 @Id
24 @Column(name = "DEPTNO")
25 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
26 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
27 private Integer deptNo;
28
29 @Column(name = "DEPTNAME")
30 private String deptName;
31
32
33 public Integer getDeptNo() {
34 return deptNo;
35 }
36
37 public void setDeptNo(Integer deptNo) {
38 this.deptNo = deptNo;
39 }
40
41 public String getDeptName() {
42 return deptName;
43 }
44
45 public void setDeptName(String deptName) {
46 this.deptName = deptName;
47 }
48 }
1 /**
2 * 注解测试多对一映射 员工表(多)对应部门表(一)的映射,即只在员工表中植入部门表的信息
3 * */
4 @Test
5 public void manytooneSingle(){
6
7 /**
8 * 查询操作
9 * **/
10 /*SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
11 Session session = sf.openSession();
12
13 Emp emp=(Emp)session.load(Emp.class, 4);
14
15 System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());*/
16
17 /**
18 * 添加操作
19 * **/
20 SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory();
21 Session session = sf.openSession();
22 Transaction tx = session.beginTransaction();
23 Dept dept = (Dept)session.load(Dept.class, 3);
24
25 Emp emp=new Emp();
26 emp.setEmpName("户梦艳");
27 emp.setEmpNo(001);
28 emp.setDept(dept);
29
30 Emp emp2=new Emp();
31 emp2.setEmpName("户梦艳2");
32 emp2.setEmpNo(002);
33 emp2.setDept(dept);
34
35 session.save(emp);
36 session.save(emp2);
37 tx.commit();
38 session.close();
39
40
41 }
一对多双单向配置
1 package cn.happy.entity;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import javax.persistence.CascadeType;
7 import javax.persistence.Column;
8 import javax.persistence.Entity;
9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.JoinColumn;
13 import javax.persistence.OneToMany;
14 import javax.persistence.SequenceGenerator;
15 import javax.persistence.Table;
16 import javax.persistence.Transient;
17
18
19 @Entity
20 @Table(name="Dept")
21 public class Dept {
22 @Id
23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
25 private Integer deptNo;
26 @Column
27 private String deptName;
28
29
30 @OneToMany(cascade={CascadeType.ALL})
31 @JoinColumn(name="deptno")
32 private Set<Emp> emps=new HashSet<Emp>();
33
34 public Set<Emp> getEmps() {
35 return emps;
36 }
37
38 public void setEmps(Set<Emp> emps) {
39 this.emps = emps;
40 }
41
42 public Integer getDeptNo() {
43 return deptNo;
44 }
45
46 public void setDeptNo(Integer deptNo) {
47 this.deptNo = deptNo;
48 }
49
50 public String getDeptName() {
51 return deptName;
52 }
53
54 public void setDeptName(String deptName) {
55 this.deptName = deptName;
56 }
57 }
1 package cn.happy.entity;
2
3 import javax.persistence.Basic;
4 import javax.persistence.Column;
5 import javax.persistence.Entity;
6 import javax.persistence.FetchType;
7 import javax.persistence.GeneratedValue;
8 import javax.persistence.GenerationType;
9 import javax.persistence.Id;
10 import javax.persistence.JoinColumn;
11 import javax.persistence.ManyToOne;
12 import javax.persistence.SequenceGenerator;
13 import javax.persistence.Table;
14 import javax.persistence.Transient;
15
16 import org.hibernate.bytecode.javassist.FieldHandled;
17 import org.hibernate.bytecode.javassist.FieldHandler;
18
19
20 @Entity
21 @Table(name = "EMP")
22 public class Emp {
23
24
25
26 @Id
27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
29 private Integer empNo;
30
31 @Column
32 private String empName;
33
34
35 // @ManyToOne
36 // @JoinColumn(name="deptno")
37 // @Basic(fetch=FetchType.LAZY)
38 // private Dept dept;
39 //
40 // public Dept getDept() {
41 // return dept;
42 // }
43 //
44 // public void setDept(Dept dept) {
45 // this.dept = dept;
46 // }
47
48 public Emp() {
49 super();
50 }
51
52 public Emp(Integer empNo, String empName) {
53 super();
54 this.empNo = empNo;
55 this.empName = empName;
56 }
57
58 public Integer getEmpNo() {
59 return empNo;
60 }
61
62 public void setEmpNo(Integer empNo) {
63 this.empNo = empNo;
64 }
65
66 public String getEmpName() {
67 return empName;
68 }
69
70 public void setEmpName(String empName) {
71 this.empName = empName;
72 }
73
74
75 }
1 /**
2 * 测试一对多单向添加操作
3 * */
4 @Test
5 public void insertOneToManySingle(){
6 Emp emp=new Emp();
7 emp.setEmpName("李小鹏");
8
9 Emp emp2=new Emp();
10 emp2.setEmpName("王想想");
11
12 Dept dept=new Dept();
13 dept.setDeptName("教务部");
14 //设置级联操作
15 dept.getEmps().add(emp);
16 dept.getEmps().add(emp2);
17
18 session.save(dept);
19 tx.commit();
20 System.out.println("insert ok");
21
22 }
1 /**
2 * 测试一对多单向查询操作
3 * */
4 @Test
5 public void selectOneToManySingle(){
6 Dept dept = (Dept)session.load(Dept.class, 1);
7 System.out.println("======================");
8 System.out.println("部门名称:"+dept.getDeptName());
9 System.out.println("=======================");
10 //体现了延迟加载
11 for (Emp emp : dept.getEmps()) {
12 System.out.println("雇员名称:"+emp.getEmpName());
13 }
14 //Emp emp = (Emp)session.load(Emp.class, 1);
15
16
17 }
一对多双向配置
1 package cn.happy.entity;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 import javax.persistence.CascadeType;
7 import javax.persistence.Column;
8 import javax.persistence.Entity;
9 import javax.persistence.GeneratedValue;
10 import javax.persistence.GenerationType;
11 import javax.persistence.Id;
12 import javax.persistence.JoinColumn;
13 import javax.persistence.OneToMany;
14 import javax.persistence.SequenceGenerator;
15 import javax.persistence.Table;
16 import javax.persistence.Transient;
17
18
19 @Entity
20 @Table(name="Dept")
21 public class Dept {
22 @Id
23 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="dept_num")
24 @SequenceGenerator(name="dept_num",sequenceName="dept_num_no",allocationSize=1,initialValue=1)
25 private Integer deptNo;
26 @Column
27 private String deptName;
28
29
30 @OneToMany(mappedBy="dept",cascade={CascadeType.ALL})
31
32 private Set<Emp> emps=new HashSet<Emp>();
33
34 public Set<Emp> getEmps() {
35 return emps;
36 }
37
38 public void setEmps(Set<Emp> emps) {
39 this.emps = emps;
40 }
41
42 public Integer getDeptNo() {
43 return deptNo;
44 }
45
46 public void setDeptNo(Integer deptNo) {
47 this.deptNo = deptNo;
48 }
49
50 public String getDeptName() {
51 return deptName;
52 }
53
54 public void setDeptName(String deptName) {
55 this.deptName = deptName;
56 }
57 }
1 package cn.happy.entity;
2
3 import javax.persistence.Basic;
4 import javax.persistence.Column;
5 import javax.persistence.Entity;
6 import javax.persistence.FetchType;
7 import javax.persistence.GeneratedValue;
8 import javax.persistence.GenerationType;
9 import javax.persistence.Id;
10 import javax.persistence.JoinColumn;
11 import javax.persistence.ManyToOne;
12 import javax.persistence.SequenceGenerator;
13 import javax.persistence.Table;
14 import javax.persistence.Transient;
15
16 import org.hibernate.bytecode.javassist.FieldHandled;
17 import org.hibernate.bytecode.javassist.FieldHandler;
18
19
20 @Entity
21 @Table(name = "EMP")
22 public class Emp {
23
24
25
26 @Id
27 @GeneratedValue(strategy=GenerationType.SEQUENCE,generator="emp_num")
28 @SequenceGenerator(name="emp_num",sequenceName="emp_num_no",allocationSize=1,initialValue=9)
29 private Integer empNo;
30
31 @Column
32 private String empName;
33
34
35 @ManyToOne
36 @JoinColumn(name="deptno")
37 @Basic(fetch=FetchType.LAZY)
38 private Dept dept;
39
40 public Dept getDept() {
41 return dept;
42 }
43
44 public void setDept(Dept dept) {
45 this.dept = dept;
46 }
47
48 public Emp() {
49 super();
50 }
51
52 public Emp(Integer empNo, String empName) {
53 super();
54 this.empNo = empNo;
55 this.empName = empName;
56 }
57
58 public Integer getEmpNo() {
59 return empNo;
60 }
61
62 public void setEmpNo(Integer empNo) {
63 this.empNo = empNo;
64 }
65
66 public String getEmpName() {
67 return empName;
68 }
69
70 public void setEmpName(String empName) {
71 this.empName = empName;
72 }
73
74
75 }
1 /**
2 * 双向一对多的添加操作
3 * */
4 @Test
5 public void oneToManyDouble(){
6 Dept dept=new Dept();
7 dept.setDeptName("财务部");
8
9 Emp emp=new Emp();
10 emp.setEmpName("邹乐");
11 emp.setDept(dept);
12
13 Emp emp2=new Emp();
14 emp2.setEmpName("范子阳");
15 emp2.setDept(dept);
16
17
18 dept.getEmps().add(emp);
19 dept.getEmps().add(emp2);
20
21 session.save(dept);
22 tx.commit();
23 }
24
1 /**标签:Hibernate,dept,关联,public,emp,import,注解,javax,persistence From: https://blog.51cto.com/u_13363083/5979320
2 * 双向一对多的查询操作
3 * */
4 @Test
5 public void selectOneToManyDouble(){
6
7 Dept dept = (Dept)session.load(Dept.class, 1);
8 System.out.println("部门名称:"+dept.getDeptName());
9 for (Emp emp : dept.getEmps()) {
10 System.out.println("职工姓名:"+emp.getEmpName());
11 }
12
13 System.out.println("==================================================");
14
15 Emp emp = (Emp)session.load(Emp.class, 1);
16 System.out.println("职工姓名:"+emp.getEmpName()+"\t部门名称:"+emp.getDept().getDeptName());
17 }
18