全面解析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)


增删改查放在下一篇吧,太多了大家不爱看

0 0
原创粉丝点击