Hibernate使用注解配置持久化类和关联关系

Hibernate提供注解来进行对象一一关系映射,他可以代替大量的hbm.xml文件,使得Hibernate程序的文件数量大大精简。使用注解,可以直接将映射信息定义在持久化类中,而无需编写对应的.*hbm.xml

配置持久化类的常用注解

  • @Entity 将一个类声明为一个持久化类,默认所有属性都映射在数据表中
  • @Table 为持久化类映射指定表(table),目录catalog 和schema的名称,默认值持久化类名,不带包名
  • @Id 声明了持久化类的标识属性(相当于数据表的主键)
  • @GeneratedValue 定义标识属性值的生成策略
  • @UniqueConstraint 定义表的唯一约束
  • @Lob 标识属性将被持久化为Blob或Clob属性
  • @Column 将属性映射到数据库字段
  • @Transient 指定可以忽略的属性,不用持久化到数据库

使用Hibernate注解,需要导入javax.persistence包,常用注解都存放在这个包,javax.persistence包是JPA ORM规范的组合部分,JPA 全称
Java Persistence API ,他是通过JDK5.0注解或XML描述对象一一关系表的映射关系,并将运行时对象持久化到数据库中。Hibernate提供对JPA的实现

package com.pojo;


import javax.persistence.*;

@Entity
@Table(name = "student",catalog = "project")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "stuId")
    private Integer stuId;

    @Column(name = "stuName")
    private String stuName;

    @Transient
    private Teacher teacher;

    public Student() {
    }

    public Student(String stuName, Teacher teacher) {
        this.stuName = stuName;
        this.teacher = teacher;
    }

    public Integer getStuId() {
        return stuId;
    }

    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}


package com.pojo;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(catalog = "project", name = "teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "teaId")
    private Integer teaId;

    @Column(name = "teaName")
    private String teaName;

    @Transient
    private Set students = new HashSet<>();

    public Teacher() {
    }

    public Teacher(String teaName, Set students) {
        this.teaName = teaName;
        this.students = students;
    }

    public Integer getTeaId() {
        return teaId;
    }

    public void setTeaId(Integer teaId) {
        this.teaId = teaId;
    }

    public String getTeaName() {
        return teaName;
    }

    public void setTeaName(String teaName) {
        this.teaName = teaName;
    }

    public Set getStudents() {
        return students;
    }

    public void setStudents(Set students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "teaId=" + teaId +
                ", teaName='" + teaName + '\'' +
                ", students=" + students +
                '}';
    }
}

  • @Table 可以省略,省略时默认表名于持久化类名相同
  • @GeneratedValue 指定了OID的生成策略,如果不使用此注解,默认OID由程序赋值相当于映射文件中指定assigned。JPA提供4种标准用法
    (1)AUTO:根据不同的数据库选择不同的策略相当于映射文件中的native
    (2)TABLE:使用表保存id值
    (3)IDENTITY:使用数据库自动生成主键值(主要时自动增长型:MySQL,SQL Server)
    (4)SEQUENCE:使用序列生成主键值(如Oracle),genertor="uuid"指定生成器是uuid
  • @SequenceGenerator设置了序列生成器,name="seq"定义了序列生成器名是seq;sequenceName="seq_id"指定了序列的名称seq_id;initialValue设置主键起始值;allocationSize设置了生成器分配id时的增量
  • @Column 用于指定属性映射的数据库字段名,若不指定,则默认字段名和属性名相同
  • @Transient用于忽略不需要持久化到数据库的属性,只是起到用于查询时封装查询数据
  • @Entity 默认所有属性都会被映射到数据库表中的同名字段

使用注解定义的持久化类,在hibernate.cfg.xml的mapping元素中要使用class属性进行声明,以指定该持久化类的全类名

Hibernate注解配置关联关系

  • @OneToOne 建立持久化类之间的一对一关联关系
  • @OneToMany 建立持久化类之间一对多关联关系
  • @ManyToOne建立持久化类之间多对一关联关系
  • @ManyToMany建立持久化类之间多对多关联关系

注解开发双向一对多关联关系

package com.pojo;


import javax.persistence.*;

@Entity
@Table(name = "student", catalog = "project")
public class Student {

    @Id
    @Column(name = "stuId")
    private Integer stuId;

    @Column(name = "stuName")
    private String stuName;

    /**
     * 一对多关联关系
     * 延迟加载
     * 关联外键
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "teaId")
    private Teacher teacher;

    public Student() {
    }

    public Student(Integer stuId, String stuName, Teacher teacher) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.teacher = teacher;
    }

    public Integer getStuId() {
        return stuId;
    }

    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

public class StudentDao extends BaseDao{
    public void save(Student student)
    {
        this.getCurrentSession().save(student);
    }
}
public class StudentBiz {
    private StudentDao studentDao = new StudentDao();

    public void save(Student student) {
        Transaction tx = null;
        try {
            tx = studentDao.getCurrentSession().beginTransaction();
            studentDao.save(student);
            tx.commit();
        } catch (HibernateException ex) {
            ex.printStackTrace();
            if (tx != null) {
                tx.rollback();
            }
        }
    }
}
public class StudentTest {
    private StudentBiz studentBiz=new StudentBiz();
    @Test
    public void save()
    {
        Student student=new Student();
        student.setStuId(8);
        student.setStuName("王八");
        Teacher teacher=new Teacher();
        teacher.setTeaId(1);
        student.setTeacher(teacher);
        studentBiz.save(student);
    }
}

package com.pojo;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(catalog = "project", name = "teacher")
public class Teacher {

    @Id
    @Column(name = "teaId")
    private Integer teaId;

    @Column(name = "teaName")
    private String teaName;

    /**
     * 一对多关联关系
     * 延迟加载
     * inverse="true" 值是Student类中与Teacher关联的属性名
     * 级联cascade
     */
    @OneToMany(fetch = FetchType.LAZY,mappedBy = "teacher",cascade = CascadeType.ALL)
    private Set students = new HashSet<>();

    public Teacher() {
    }

    public Teacher(Integer teaId, String teaName, Set students) {
        this.teaId = teaId;
        this.teaName = teaName;
        this.students = students;
    }

    public Integer getTeaId() {
        return teaId;
    }

    public void setTeaId(Integer teaId) {
        this.teaId = teaId;
    }

    public String getTeaName() {
        return teaName;
    }

    public void setTeaName(String teaName) {
        this.teaName = teaName;
    }

    public Set getStudents() {
        return students;
    }

    public void setStudents(Set students) {
        this.students = students;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "teaId=" + teaId +
                ", teaName='" + teaName + '\'' +
                ", students=" + students +
                '}';
    }
}

public class TeacherDao extends BaseDao {
    public void save(Teacher teacher)
    {
        this.getCurrentSession().save(teacher);
    }
}
public class TeacherBiz {
    private TeacherDao teacherDao=new TeacherDao();
    public void save(Teacher teacher)
    {
        Transaction tx=null;
        try {
          tx=teacherDao.getCurrentSession().beginTransaction();
          teacherDao.save(teacher);
          tx.commit();
        }catch (HibernateException ex)
        {
            ex.printStackTrace();
            if(tx!=null)
            {
                tx.rollback();
            }
        }
    }
}
public class TeacherTest {
    private TeacherBiz teacherBiz = new TeacherBiz();

    @Test
    public void save() {
        Student s1 = new Student();
        s1.setStuId(9);
        s1.setStuName("柳九");
        Student s2 = new Student();
        s2.setStuId(10);
        s2.setStuName("剑十");
        Teacher teacher = new Teacher();
        teacher.setTeaId(2);
        teacher.setTeaName("王老");
        teacher.getStudents().add(s1);
        teacher.getStudents().add(s2);
        s1.setTeacher(teacher);
        s2.setTeacher(teacher);
        teacherBiz.save(teacher);
    }
}

使用@ManyToOne注解配置Student类和Teacher类之间的多对一关联。注解属性fetch=FetchType.Lazy设置多对一关联级别采用懒加载策略;若不指定,该属性的默认值是EAGER,查询Student将采用左外连接将相关Teacher对象一并查出。注解@JoinColumn(name="teaId")指定维护关系的外键字段是Student表中的teaId
使用@OneToMany配置Teacher类和Student类之间的一对多关系,属性mappedBy="teacher"将关联关系的控制权交给Student这一方,相当于配置文件的inverse="true"。mappedBy属性的值是Student类中与Teacher类关联的属性名。属性cascade={CascadeType.ALL}设置了级联操作的类型

  • CascadeType.REMOVE :级联删除
  • CascadeType.PERSIST :persist()方法级联
  • CascadeType.MERGE :级联更新
  • CascadeType.REFRESH :级联刷新
  • CascadeType.ALL 包含所有级联操作

注解开发双向多对多关联关系

package com.pojo;


import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "student", catalog = "project")
public class Student {

    @Id
    @Column(name = "stuId")
    private Integer stuId;

    @Column(name = "stuName")
    private String stuName;


    @ManyToMany(mappedBy = "students", fetch = FetchType.LAZY)
    private Set subjects = new HashSet<>();


    public Student() {
    }

    public Student(Integer stuId, String stuName, Set subjects) {
        this.stuId = stuId;
        this.stuName = stuName;
        this.subjects = subjects;
    }

    public Integer getStuId() {
        return stuId;
    }

    public void setStuId(Integer stuId) {
        this.stuId = stuId;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public Set getSubjects() {
        return subjects;
    }

    public void setSubjects(Set subjects) {
        this.subjects = subjects;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", stuName='" + stuName + '\'' +
                ", subjects=" + subjects +
                '}';
    }
}

package com.pojo;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;


@Entity
@Table(name = "subject", catalog = "project")
public class Subject {
    @Id
    @Column(name = "subId")
    private Integer subId;

    @Column(name = "subName")
    private String subName;


    /**
     * 多对多关联关系
     * 懒加载
     * 中间表
     * 当前对象id在中间表的列名
     * 关联的另一个表在中间表的列名
     */
    @ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
    @JoinTable(name = "sub_stu",//中间表名
            joinColumns = {@JoinColumn(name = "sub_id", referencedColumnName = "subId")},//当前对象id在中间表的列名
            inverseJoinColumns = {@JoinColumn(name = "stu_id", referencedColumnName = "stuId")}//关联的另一个表在中间表的列名
    )

    private Set students = new HashSet<>();

    public Subject() {
    }

    public Subject(Integer subId, String subName, Set students) {
        this.subId = subId;
        this.subName = subName;
        this.students = students;
    }

    public Integer getSubId() {
        return subId;
    }

    public void setSubId(Integer subId) {
        this.subId = subId;
    }

    public String getSubName() {
        return subName;
    }

    public void setSubName(String subName) {
        this.subName = subName;
    }

    public Set getStudents() {
        return students;
    }

    public void setStudents(Set students) {
        this.students = students;
    }


    @Override
    public String toString() {
        return "Subject{" +
                "subId=" + subId +
                ", subName='" + subName + '\'' +
                ", students=" + students +
                '}';
    }
}

public class SubDao extends BaseDao{
    public void save(Subject subject)
    {
        this.getCurrentSession().save(subject);
    }
}
public class SubBiz {
    private SubDao subDao=new SubDao();
    public void save(Subject subject)
    {
        Transaction tx=null;
        try {
            tx=subDao.getCurrentSession().beginTransaction();
            subDao.save(subject);
            tx.commit();
        }catch (HibernateException ex)
        {
            ex.printStackTrace();
            if(tx!=null)
            {
                tx.rollback();
            }
        }
    }
}
public class SubTest {
    private SubBiz subBiz = new SubBiz();

    @Test
    public void save() {
        Subject sub1 = new Subject();
        sub1.setSubId(1);
        sub1.setSubName("语文");
        Subject sub2 = new Subject();
        sub2.setSubId(2);
        sub2.setSubName("数学");


        Student stu1 = new Student();
        stu1.setStuId(1);
        stu1.setStuName("学生1");
        Student stu2 = new Student();
        stu2.setStuId(2);
        stu2.setStuName("学生2");


        sub1.getStudents().add(stu1);
        sub1.getStudents().add(stu2);
        sub2.getStudents().add(stu1);
        sub2.getStudents().add(stu2);


        stu1.getSubjects().add(sub1);
        stu1.getSubjects().add(sub2);
        stu2.getSubjects().add(sub1);
        stu2.getSubjects().add(sub2);


        subBiz.save(sub1);
        subBiz.save(sub2);
    }
}

Hibernate:
select
student_.stuId,
student_.stuName as stuName6_
from
project.student student_
where
student_.stuId=?
Hibernate:
select
student_.stuId,
student_.stuName as stuName6_
from
project.student student_
where
student_.stuId=?
Hibernate:
insert
into
project.subject
(subName, subId)
values
(?, ?)
Hibernate:
insert
into
project.student
(stuName, stuId)
values
(?, ?)
Hibernate:
insert
into
project.student
(stuName, stuId)
values
(?, ?)
Hibernate:
insert
into
sub_stu
(sub_id, stu_id)
values
(?, ?)
Hibernate:
insert
into
sub_stu
(sub_id, stu_id)
values
(?, ?)
Hibernate:
select
student_.stuId,
student_.stuName as stuName6_
from
project.student student_
where
student_.stuId=?
Hibernate:
select
student_.stuId,
student_.stuName as stuName6_
from
project.student student_
where
student_.stuId=?
Hibernate:
insert
into
project.subject
(subName, subId)
values
(?, ?)
Hibernate:
insert
into
sub_stu
(sub_id, stu_id)
values
(?, ?)
Hibernate:
insert
into
sub_stu
(sub_id, stu_id)
values
(?, ?)

使用@ManyToMany注解配置科目和学生的多对多关联关系fetch = FetchType.LAZY设置多对多关联级别采用延迟加载策略,属性cascade = {CascadeType.ALL}设置级联操作类型。
使用@JoinTable注解配置中间表关联Sub表和Stu表,属性name = "sub_stu"生成sub_stu中间表,属性joinColumns = {@JoinColumn(name = "sub_id", referencedColumnName = "subId")}生成当前对象id在中间表的列名,属性 inverseJoinColumns = {@JoinColumn(name = "stu_id", referencedColumnName = "stuId")}关联的另一个对象id在中间表的列名

使用@ManyToMany注解配置学生和科目的多对多关联关系,属性fetch = FetchType.LAZY设置多对多关联级别采用延迟加载策略,属性mappedBy = "students"将关联关系的控制权交给Subject这一方,相当于配置关系的inverse="true",mappedBy属性的值是Subject类中与Student类关联的属性名。

你可能感兴趣的:(Hibernate使用注解配置持久化类和关联关系)