Hibernate-Annotation

课程地址

使用hibernate注解的目的

为了简化ORM映射文件(*.hbm)繁琐的配置。
注解需要做的是映射文件要做的。

JPA与Hibernate

Java Persistence API
Java持久化接口
JPA是标准接口,HIbernate是JPA的实现,但是功能是JAP的超集。

Hibernate注解分类

  1. 类级别注解
    1. @Entity
    2. @Table
    3. @Embeddable(嵌入类)
  2. 属性级别注解
  3. 映射关系注解

一,类级别注解

1. @Entity

Entity

1. 编写Entity
设置主键,打在getter上@Id
2. class添加注解@Entity
3. 在核心配置文件中配置

<!--映射文件-->
        <mapping class="Entity.Student"/>

2. @Table

@Table

@Tabel(name="")和@Entity(name="")

@Table's name attribute is the actual table name. @Entitiy's name is useful if you have two @Entity classes with the same name and you need a way to differentiate them when running queries.
From Stack Overflow

3. @Embeddable

表示一个非Entity类可以嵌套到另一个Entity中,作为另一个Entity的属性。

package Entity;

import javax.persistence.Embeddable;

/**
 * Created by futao on 2017/9/27.
 */

/**
 * 嵌入类,不会生成表,可能在其他表作为属性存在
 */
@Embeddable
public class Gf {
    private String name;
    private int age;

    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 Entity;

/**
 * Created by futao on 2017/9/26.
 */

import javax.persistence.Column;
import javax.persistence.Entity;    //JPA注解
import javax.persistence.Id;
import javax.persistence.Table;
import java.sql.Timestamp;


/**
 * 学生实体类
 */
@Entity
@Table(name = "imooc_student1")
public class Student {
    /**
     * 主键
     */
    @Column(name = "sid")
    private int sid;
    /**
     * 姓名
     */
    @Column(name = "sname")
    private String sname;
    /**
     * 性别
     */
    @Column(name = "gender")
    private String gender;
    /**
     * 生日
     */
    @Column(name = "birthday")
    private Timestamp birthday;
    /**
     * 专业
     */
    @Column(name = "major")
    private String major;
    /**
     * 地址
     */
    private String address;

    //组件属性
    private Gf gf;

    @Id
    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public Gf getGf() {
        return gf;
    }

    public void setGf(Gf gf) {
        this.gf = gf;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Timestamp getBirthday() {
        return birthday;
    }

    public void setBirthday(Timestamp birthday) {
        this.birthday = birthday;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

二,属性级别注解

添加方式
1.写在属性字段上面
2.写在getter上面

@Id
@SequenceGenerator
@GeneratedValue
@Column
@Embedded
@EmbeddedId
@Lob
@Version
@Basic
@Transient

1. @Id

@Id

可以给一个Entity设置两个主键,不过要实现Serializable接口

2. @GeneratedValue

GeneratedValue
example

3. @GeneratedValue

4. @Column

Column

5. @Embedded,@EmbeddedId

打在被标记为@Embeddable的嵌入类的实例上,或者getter上

@Embedded

6. @Transient

@Transient

三,关系映射级别注解

关系映射级别注解

1. 一对一单向外键关联(两张表都要在hibernate住配置文件中进行配置)

一对一单向外键关联
//主表
package Entity;

import javax.persistence.*;
import java.sql.Timestamp;

/**
 * Created by futao on 2017/9/27.
 */
@Entity
@Table(name = "imooc_student")
public class Student {
    /**
     * 主键,学号
     */
    @Id
    @GeneratedValue
    private int sid;
    /**
     * 性别
     */
    private String gender;
    /**
     * 生日
     */
    private Timestamp birthday;
    /**
     * 专业
     */
    private String major;
    /**
     * 身份证对象
     */
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "pid",unique = true)
    private IdCard idCard;

    public IdCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IdCard idCard) {
        this.idCard = idCard;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }


    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Timestamp getBirthday() {
        return birthday;
    }

    public void setBirthday(Timestamp birthday) {
        this.birthday = birthday;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}

//关联表
package Entity;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
 * Created by futao on 2017/9/27.
 */
@Entity
@Table(name = "imoooc_id_card")
public class IdCard {
    @Id
    @GeneratedValue(generator = "pid")
    @GenericGenerator(name="pid",strategy = "assigned")
    @Column(length = 18)
    private String pid;
    private String sname;
    private String address;

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
//Test
    @Test
    fun dbtest() {
        session.save(IdCard().apply {
            pid = "11"
            sname = "熊anger"
            address = "上海小二房"
        })
        session.save(Student().apply {
            gender = "男"
            birthday = Timestamp(DateTime.now().millis)
            major = "计算机"
            idCard = session.get(Student::class.java, 2) as IdCard
        })
    }

2. 不推荐使用双向外键关联

3. 多对一单向外键关联

//多的那一方
package ManyToOne;

import javax.persistence.*;
import java.sql.Timestamp;

/**
 * Created by futao on 2017/9/28.
 */

/**
 * 学生实体类
 */
@Entity
@Table(name = "imooc_senior_student")
public class Student {

    @Id
    @GeneratedValue
    private int sid;
    private String gender;
    private Timestamp birthday;
    private String major;

    /**
     * 一对多单向外键关联关系
     * 级联关系:全级连
     * 抓取策略
     */
//@joinColumn(name="对用生成的表中的字段名",referencedColumnName="一的那一方的主键名")
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "fuckyou",referencedColumnName ="cid" )
    private Classroom classroom;

    public Classroom getClassroom() {
        return classroom;
    }

    public void setClassroom(Classroom classroom) {
        this.classroom = classroom;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Timestamp getBirthday() {
        return birthday;
    }

    public void setBirthday(Timestamp birthday) {
        this.birthday = birthday;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}

//一的那一方
package ManyToOne;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
 * Created by futao on 2017/9/28.
 */

/**
 * 班级实体类
 */
@Entity
@Table(name = "imooc_senior_classroom")
public class Classroom {
    @Id
    @GeneratedValue(generator = "cid")
    @GenericGenerator(name = "cid",strategy = "assigned")
    @Column(length = 4)
    private String cid;
    private String cname;

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }
}

4. 多对多单向外键

多对多会生成一张中间表存储对应关系

ManyToMany
package Many2Many;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Set;

/**
 * Created by futao on 2017/9/28.
 */
@Entity
@Table(name = "many2many_student")
public class Student {

    @Id
    @GeneratedValue
    private int sid;
    private String name;
    private String gender;
    private Timestamp birthday;
    private String major;

    /**
     * 学生持有教师的集合
     */
    @ManyToMany
    @JoinTable(
            //中间表的名字
            name = "student_teacher",
            joinColumns = {@JoinColumn(name = "sid")},
            inverseJoinColumns = {@JoinColumn(name = "tid")}
    )
    private Set<Teacher> teacherSet;

    public Set<Teacher> getTeacherSet() {
        return teacherSet;
    }

    public void setTeacherSet(Set<Teacher> teacherSet) {
        this.teacherSet = teacherSet;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Timestamp getBirthday() {
        return birthday;
    }

    public void setBirthday(Timestamp birthday) {
        this.birthday = birthday;
    }

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }
}

package Many2Many;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

/**
 * Created by futao on 2017/9/28.
 */
@Entity
@Table(name = "many2many_teacher")
public class Teacher {
    @Id
    @GeneratedValue(generator = "tid")
    @GenericGenerator(name = "tid", strategy = "assigned")
    @Column(length = 4)
    private String tid;
    private String tname;

    public String getTid() {
        return tid;
    }

    public void setTid(String tid) {
        this.tid = tid;
    }

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }
}

@Test
    fun many2many(){
        val t1=Teacher().apply {
            tid="T001"
            tname="张老师"
        }
        val t2=Teacher().apply {
            tid="t999"
            tname="吴彦祖"
        }

        val teachers=HashSet<Teacher>()
        teachers.add(t1)
        teachers.add(t2)

        val s1=Many2Many.Student().apply {
            name="熊老一"
            gender="男"
            birthday= Timestamp(DateTime.now().millis)
            major="计算机"
            teacherSet=teachers
        }
        val s2= Many2Many.Student().apply {
            name="熊老二"
            gender="男"
            birthday= Timestamp(DateTime.now().millis)
            major="软件工程"
        }
        val s3=Many2Many.Student().apply {
            name="李子"
            gender="女"
            birthday= Timestamp(DateTime.now().millis)
            major="建筑学"
            teacherSet=teachers
        }

        session.save(t1)
        session.save(t2)
        session.save(s1)
        session.save(s2)
        session.save(s3)
    }

5. 多对多双向外键关联

Many2Many

总结

image.png
image.png

推荐阅读更多精彩内容