全面解析Hibernate框架--小白必看3
来源:互联网 发布:sql选取第一行 编辑:程序博客网 时间:2024/05/23 00:08
关联映射
多张表之间有哪些关系?多个实体类
1.一对一关系 市民—社保卡 一个公民—身份证
2.一对多关系 班级—学生
3.多对多关系 老师—学生
表
与表之间关联之一对一关联:
思路:
1. 这两个关联的实体,谁来维护二者之间的关系。一对一关系,随便选择一端维护。选择wife维护关系。
2. 考虑关联,关联就是你中有我,我中有你
Husband代码:package com.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;@Entity@Table(name="husband",schema="chidianwei")public class Husband { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; private String name; @OneToOne(mappedBy="husband") private Wife wife; public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}Wife代码:package com.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name="wife",schema="chidianwei")public class Wife { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; private String name; @ManyToOne @JoinColumn(name="husband_id",unique=true) private Husband husband; public int getId() { return id; } public Husband getHusband() { return husband; } public void setHusband(Husband husband) { this.husband = husband; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }}一般情况下谁持有外键,就让谁维护。/* @Test public void testOne2One() { Husband h=new Husband(); h.setName("husband"); Wife w=new Wife(); w.setName("wife"); w.setHusband(h);//wife维护二者一对一关系 session.save(h); session.save(w); Husband h=(Husband)session.get(Husband.class, 61); System.out.println(h.getWife().getName()); }*/
表与表之间关联之一对多关联
单项一对多
相对于学生来说是多对一,相对于班级来说是一对多。
一般总结出来的最佳实践是:有外键的一端也就是多的一端来维护二者的关系,也就是,没有外键的那一端一般情况是一的一端,只要写一个mappedBy注解即可。具体有对方维护关系。
双向一对多关联
维护关系的一端,也叫被控端student映射类代码:package com.entity;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Entity@Table(name="student",schema="chidianwei")public class Student{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; public int getId() { return id; } public void setId(int id) { this.id = id; }private String name;private int age;@ManyToOne@JoinColumn(name="class_id")private Classes classes;public Classes getClasses() { return classes;}public void setClasses(Classes classes) { this.classes = classes;}public String getName() { return name;}public void setName(String name) { this.name = name;}public int getAge() { return age;}public void setAge(int age) { this.age = age;}}主控端代码:package com.entity;import java.util.ArrayList;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToMany;import javax.persistence.Table;@Entity@Table(name="classes",schema="chidianwei")public class Classes{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @OneToMany(mappedBy="classes") private List<Student> students=new ArrayList<Student>(); public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}持久化代码片段 @Test public void testOne2Many() { /* Classes c=new Classes(); c.setName("Java班"); Student s1=new Student(); s1.setName("张三"); s1.setAge(22); s1.setClasses(c); Student s2=new Student(); s2.setName("李四"); s2.setAge(25); s2.setClasses(c);// 保存 session.save(c); session.save(s1); session.save(s2);*/ Classes c=(Classes)session.get(Classes.class, 63); System.out.println("班级:"+c.getName()); List<Student> students=c.getStudents(); for(Student s:students){ System.out.println(s.getName()); } }
一对多关系默认加载班级的时候会采用懒加载去设置students属性,也就是学生集合会在真正使用的时候加载。
可以对懒加载进行修改:
@OneToMany(mappedBy=”classes”,fetch=FetchType.EAGER)
这样就不会采用懒加载。
表与表之间关联之多对多
中间的关联表除了两端的外键,还有其他字段,形成了两个一对多关系,对于两端来说,就是多对多关系,就是前边涉及的一对多双向关联,只不过是两对
中间的关联表只有两端的外键,无需对应实体类
主控端:大学生实体类package com.entity;import java.util.ArrayList;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name="undergraduate",schema="chidianwei")public class Undergraduate { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @ManyToMany @JoinTable( schema="chidianwei", name="undergraduate_course", //关联表的表名 //关联当前表的外键名 joinColumns=@JoinColumn(name="undergraduate_id"), //关联对方表的外键名 inverseJoinColumns=@JoinColumn(name="course_id") ) private List<Course> courses=new ArrayList<Course>(); public List<Course> getCourses() { return courses; } public void setCourses(List<Course> courses) { this.courses = courses; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}另一端课程实体类:package com.entity;import java.util.ArrayList;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.ManyToMany;import javax.persistence.Table;@Entity@Table(name="courses",schema="chidianwei")public class Course { @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @ManyToMany(mappedBy="courses") private List<Undergraduate> students=new ArrayList<Undergraduate>(); public List<Undergraduate> getStudents() { return students; } public void setStudents(List<Undergraduate> students) { this.students = students; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}由于是多对多关系,所以谁来当维护关系一端区别不大,缓过来让Course来当维护关系一端也未尝不可。持久化代码: /*@Test public void testMany2Many() { Course c1=new Course(); c1.setName("语文"); Course c2=new Course(); c2.setName("大学英语"); //学生 Undergraduate s1=new Undergraduate(); s1.setName("张三"); Undergraduate s2=new Undergraduate(); s2.setName("李四"); Undergraduate s3=new Undergraduate(); s3.setName("王五"); //学生选课 List<Course> courses=new ArrayList<Course>(); List<Course> courses1=new ArrayList<Course>(); courses.add(c2); courses.add(c1); courses1.add(c1); s1.setCourses(courses); s2.setCourses(courses); s3.setCourses(courses1); //保存 session.save(c1); session.save(c2); session.save(s1); session.save(s2); session.save(s3); } */
解释小问题
1.懒加载
lazy属性,延迟加载,即是否立刻查询并加载当前对象关联的对象
XxxToYyy的关系中都有,配置方式类似:
@OneToMany(fetch=FetchType.LAZY)
@OneToMany(fetch=FetchType.EAGER)
凡是@xxxToOne,默认都是EAGER
凡是@xxxToMany,默认都是LAZY
session关闭后再去加载关联对象,会报抛出LazyInitializationException
写法是: @OneToMany(mappedBy=”classes”,fetch=FetchType.EAGER)
2.级联
cascade属性,级联操作,指的是操作当前实体对象时,关联对象是否执行同步操作,例如:Classes对象删除时,相关联的Student是否同时全部删除
例如:@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE}))
CascadeType枚举值:
PERSIST:在执行persist方法时进行级联操作
MERGE:在执行merge方法时进行级联操作(类似saveOrUpdate方法)
REMOVE:在执行delete方法时进行级联操作
REFRESH:在执行refresh方法时进行级联操作
DETACH:在执行detach方法时进行级联操作
ALL:在执行以上所有操作时都进行级联操作
不设置:所有情况下均不进行级联
SAVE
UPDATE
DELETE 红色的是hibernate的。
这里特别注意,如果准备用JPA注解做级联,必须调用响应的session方法,比如级联值为persist则必须session.persist才生效,save就会不产生级联,如果非要使用session.save或者session.saveOrUpdate,则应该采用Hibernate的级联。@Cascade(value = org.hibernate.annotations.CascadeType.SAVE_UPDATE)
增删改查放在下一篇吧,太多了大家不爱看
- 全面解析Hibernate框架--小白必看3
- 全面解析Hibernate框架--小白必看
- 全面解析Hibernate框架--小白必看 2
- 全面解析Hibernate框架--小白必看 4
- hibernate注解全面解析
- 全面解析Hibernate、Struts、Spring技术
- 全面解析Hibernate、Struts、Spring技术
- 【框架基础】:全面解析Java注解(一)
- 【框架基础】:全面解析Java注解(二)
- Linux下I2C驱动框架全面解析
- android Fragmentation框架源码全面解析一
- 亲,hibernate持久化对象的状态图全面解析!
- 全面解析回溯法:算法框架与问题求解
- 全面解析回溯法:算法框架与问题求解
- 全面解析回溯法:算法框架与问题求解
- 全面解析回溯法:算法框架与问题求解
- 全面解析回溯法:算法框架与问题求解
- 大数据批处理框架 Spring Batch全面解析
- JS / jQuery宽高的理解和应用
- 20161213C语言基础07_常量
- CSS3中REM使用详解
- logstash 高级配置
- Azure 上通过 SendGrid 发送邮件
- 全面解析Hibernate框架--小白必看3
- 手机/移动前端开发需要注意的20个要点
- 时区设置相关
- AJAX协议传输,并调取数据库返回值
- mysql 批量执行update语句最佳方案思考
- AngularJS ocLazyLoad按需加载控制器/js文件的延迟加载(一)
- c operate time
- Android自动打包工具aapt详解
- git 常见报错解决方法