基于Hibernate注解的解读

一、综述

目前为止项目用到的实体类关系有3种:

  • 单向一对多
  • 单向多对一
  • 双向一对多(双向多对一)

二、说明

@Entity              --注释声明该类为持久类。将一个Javabean类声明为一 个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的, 要用下面的Transient来注解.
@Table(name="promotion_info")      --持久性映射的表(表名="promotion_info).@Table是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字,默认为实体bean的类名,不带包名.
@Id--注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。 
@GeneratedValue   --定义自动增长的主键的生成策略. 
@Transient             --将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错. 
@Temporal(TemporalType.TIMESTAMP)--声明时间格式 
@Enumerated         --声明枚举 
@Version                --声明添加对乐观锁定的支持 
@OneToOne            --可以建立实体bean之间的一对一的关联 
@OneToMany          --可以建立实体bean之间的一对多的关联 
@ManyToOne          --可以建立实体bean之间的多对一的关联 
@ManyToMany        --可以建立实体bean之间的多对多的关联 
@Formula               --一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等) 
@OrderBy               --Many端某个字段排序(List)

特别对于一对多的时候:

// mappedBy相当于过去的inverse="true".
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myclass")
    public Set<Student> getStudents() {
        return this.students;
    }

其中mappedBy="myclass"为关联表的外键列字段。

其类似在XML中的inverse=true。

三、双向一对多实体类配置

    假设有班级和学生2个实体类。

    对于一对多或者多对一,就删除另外一方的相关配置即可。

    MyClasss

package com.mc.entity;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Myclass entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "myclass", catalog = "test")
public class Myclass implements java.io.Serializable {

    // Fields

    private Integer id;
    private String className;
    private Set<Student> students = new HashSet<Student>(0);

    // Constructors

    /** default constructor */
    public Myclass() {
    }

    /** full constructor */
    public Myclass(String className, Set<Student> students) {
        this.className = className;
        this.students = students;
    }

    // Property accessors
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "CLASS_NAME")
    public String getClassName() {
        return this.className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    // mappedBy相当于过去的inverse="true".
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myclass")
    public Set<Student> getStudents() {
        return this.students;
    }

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

}

Student

package com.mc.entity;

import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * Student entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "student", catalog = "test")
public class Student implements java.io.Serializable {

    // Fields

    private Integer id;
    private Myclass myclass;
    private String stuName;
    private Timestamp stuBirth;

    // Constructors

    /** default constructor */
    public Student() {
    }

    /** full constructor */
    public Student(Myclass myclass, String stuName, Timestamp stuBirth) {
        this.myclass = myclass;
        this.stuName = stuName;
        this.stuBirth = stuBirth;
    }

    // Property accessors
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "ID", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "STUCLASS_ID")
    public Myclass getMyclass() {
        return this.myclass;
    }

    public void setMyclass(Myclass myclass) {
        this.myclass = myclass;
    }

    @Column(name = "STU_NAME")
    public String getStuName() {
        return this.stuName;
    }

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

    @Column(name = "STU_BIRTH", length = 19)
    public Timestamp getStuBirth() {
        return this.stuBirth;
    }

    public void setStuBirth(Timestamp stuBirth) {
        this.stuBirth = stuBirth;
    }

}

四、保存

// Hibernate: insert into test.myclass (CLASS_NAME) values (?)
    // Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
    // 有效
    public static void test2() {
        Session session = HibernateSessionFactory.getSession();
        // Hibernate必须要有这个事物才行。
        Transaction beginTransaction = session.beginTransaction();

        Student student = new Student();
        student.setStuName("LCF88");

        Myclass myclass = new Myclass();
        myclass.setClassName("JAVA88");

        myclass.getStudents().add(student);

        student.setMyclass(myclass);
        session.save(myclass);

        beginTransaction.commit();
        session.close();
    }

    // 有效,3条语句(不推荐)
    // Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
    // Hibernate: insert into test.myclass (CLASS_NAME) values (?)
    // Hibernate: update test.student set STUCLASS_ID=?, STU_BIRTH=?, STU_NAME=? where ID=?
    public static void test3() {
        Session session = HibernateSessionFactory.getSession();
        // Hibernate必须要有这个事物才行。
        Transaction beginTransaction = session.beginTransaction();

        Student student = new Student();
        student.setStuName("LCF21");

        Myclass myclass = new Myclass();
        myclass.setClassName("JAVA21");

        student.setMyclass(myclass);

        session.save(student);
        session.save(myclass);

        beginTransaction.commit();
        session.close();
    }

    // 有效,2条语句,推荐,理论上先插入class在插入student
    // Hibernate: insert into test.myclass (CLASS_NAME) values (?)
    // Hibernate: insert into test.student (STUCLASS_ID, STU_BIRTH, STU_NAME) values (?, ?, ?)
    public static void test4() {
        Session session = HibernateSessionFactory.getSession();
        // Hibernate必须要有这个事物才行。
        Transaction beginTransaction = session.beginTransaction();

        Student student = new Student();
        student.setStuName("LCF22");

        Myclass myclass = new Myclass();
        myclass.setClassName("JAVA22");

        student.setMyclass(myclass);

        session.save(myclass);
        session.save(student);

        beginTransaction.commit();
        session.close();
    }

    // 无效
    // Hibernate: insert into test.myclass (CLASS_NAME) values (?)
    public static void test5() {
        Session session = HibernateSessionFactory.getSession();
        // Hibernate必须要有这个事物才行。
        Transaction beginTransaction = session.beginTransaction();

        Student student = new Student();
        student.setStuName("LCF16");

        Myclass myclass = new Myclass();
        myclass.setClassName("JAVA16");

        student.setMyclass(myclass);

        session.save(myclass);

        beginTransaction.commit();
        session.close();
    }

推荐第4种,最容易理解,在多的一方进行多的一方的数据的维护。

Demo下载地址如下:https://yunpan.cn/cxhAb54V6BNwJ  访问密码 963b

原文地址:https://www.cnblogs.com/LiuChunfu/p/5228931.html