全面解析Hibernate框架--小白必看3

关联映射

多张表之间有哪些关系?多个实体类

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值