课程地址


使用hibernate注解的目的

为了简化ORM映射文件(*.hbm)繁琐的配置。

注解需要做的是映射文件要做的。

JPA与Hibernate

Java Persistence API

Java持久化接口

JPA是标准接口,HIbernate是JPA的实现,但是功能是JAP的超集。

Hibernate注解分类

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

一,类级别注解

1. @Entity

Hibernate-Annotation_java Entity

1. 编写Entity

设置主键,打在getter上@Id

2. class添加注解@Entity

3. 在核心配置文件中配置

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

2. @Table

Hibernate-Annotation_ooc_02 @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

Hibernate-Annotation_java_03 @Id


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

2. @GeneratedValue

Hibernate-Annotation_hibernate_04 GeneratedValue

Hibernate-Annotation_hibernate_05 example

3. @GeneratedValue

4. @Column

Hibernate-Annotation_ooc_06 Column

5. @Embedded,@EmbeddedId

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

Hibernate-Annotation_ooc_07 @Embedded

6. @Transient

Hibernate-Annotation_ooc_08 @Transient

三,关系映射级别注解

Hibernate-Annotation_java_09 关系映射级别注解

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

Hibernate-Annotation_hibernate_10 一对一单向外键关联

//主表
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. 多对多单向外键

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

Hibernate-Annotation_ooc_11 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. 多对多双向外键关联

Hibernate-Annotation_java_12 Many2Many

总结

Hibernate-Annotation_hibernate_13 image.png

Hibernate-Annotation_java_14 image.png