Hibernate的注解分为 类级别注解、属性级别注解、关系映射级别注解。
Hibernate类级别注解主要介绍@Entity、@Table、@Embeddable三个。类级别注解只能标记在实体定义的地方,即public class 类名 上方。
@Entity 注解表明这个class是一个实体类,用于映射实体类,一般情况下类名与表名一致,如果不相同使用name属性对应数据库中映射的表名。Entity必须指定实体类的主键属性,使用@Id标记是主键的变量。
@Table 表示实体对应的数据库表的信息,和@Entity配合使用@Table标签有三个属性,分别是name、catalog、schema。name:映射表的名称,当表名与实体名不一致时填写,一致不需要写;catalog、schema是数据库的概念,分别指目录和概要。一个数据库可以有多个catalog,一个catalog下可以有多个schema,一个schema下可以有多个表、视图等。使用catalog名.schema名.表名 可以在这个数据库总确定唯一一张表。在MySql中没有catalog的概念。
@Embeddable 表示一个非Entity类,可以嵌入到另一个Entity类中作为属性存在。因为不是Entity类,所以他不会在数据库中生成对应的表。而是在被嵌入的实体对应的数据库表中增加被标注@Embeddable类的所有字段。与主从表不同,它没有主从关系,都是同一个表,只是在映射的实体中将某一部分属性拿出来作为另一个实体。例如:学生的地址属性,详细的分为省、市、区、街道、邮编。将这些属性都放到Address类中,标记为@Embeddable,在Student类中声明Address add,映射的只有一个student表,其中包含address(嵌入的类名)和Address的所有属性。
Hibernate属性级别注解,标记在属性字段上方或者是属性的get()方法上方。主要介绍@Id、@GeneratedValue、@Column、@Embedded、@EmbeddedId、@Transient几个标签。
@Id 标签定义了映射到数据库表主键的标签,一个实体类可以有一个主键也可以有多个主键。定义多个主键标签时实体类必须要实现Serializable接口。当定义的主键标签时字符串类型时,必须定义字符串的长度。因为MySql规定字符串类型的主键长度不能过长。用@Column(length=XX)来定义属性长度。
@GeneratedValue 用于定义主键的生成方式。例如:
@GeneratedValue(strategy = GenerationType.AUTO)
GenerationType.AUTO,JPA根据底层数据库自动选择生成方式,MySql遇到是int类型的默认自动递增。(默认的) 。不能定义字符串类型,因为字符串不能实现自动增长
GenerationType.INDENTITY,自动增长字段,Orcale不支持;
GenerationType.SEQUENCE,使用Sequence(序列号)生成主键;
GenerationType.TABLE,使用指定表来决定主键值,结合@TableGenerator使用。
@Column 映射到数据库表中的列,有如下属性:
name,表示数据库中该属性的字段名称,默认与数据库中的字段名称一致。
nullable,是否容许为空,默认true。
unique,是否是唯一标识,默认false。
length,标示字段的长度。
insertable,是否可以使用ORM执行数据库插入该字段,默认true。
updateable,是否可以使用ORM执行数据库修改该字段,默认true。
@Embedded 用于在被嵌入对象的类中标注嵌入的属性,必须同@Embeddable同事使用,否则报错。@Embeddable(嵌入的)表明这个类是可以嵌入到别的类中去,@Embedded(被嵌入的)用来标注这个属性是嵌入到这个类中的,实际这个属性对应一个嵌入类。
@EmbeddedId 用于标注嵌入的属性是个复合主键。与之对应的用@Embeddable标注的类是个复合主键类,该类中的属性全是被嵌入类的主键。该类必须实现Serializable接口,并且重写equals()、hasCode()方法。要定义一个public无参数的构造方法。
@Transient 加上该标签ORM会忽略这个属性,不会映射到数据库。
Hibernate关系映射级别注解,主要用于注解表与表之间的对应关系的。
实体之间的映射关系有一对一、一对多、多对多。对应的映射关系有:一对一单向外键关联、一对一双向外键关联、一对一单向外键联合主键关联、一对多单向外键关联、一对多双向外键关联、多对一双单向外键关联、多对多单向外键关联、多对多双向外键关联。
一对一单向外键关联
例如:公民个人信息和身份证是一对一的关系。将身份证单独看做一个对象IdCard,公民看做一个对象Person。保存时要先保存外键对象再保存主表对象。
IdCard.java
package com.lhzs.tpws.sys.entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import org.hibernate.annotations.Entity;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.Id;
@Entity //标注为实体
public class IdCard {
@Id //标注为主键
@GeneratedValue(generator="pid")
@GenericGenerator(name="pid",strategy="assigned") //定义pid主键为自己填写的方式增加
@Column(length=18) //主键是字符串类型必须要设置长度,身份证长18位
private String pid; //身份证号
private String name; //姓名
public IdCard(){
}
public IdCard(String pid, String name) {
super();
this.pid = pid;
this.name = name;
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person.java
package com.lhzs.tpws.sys.entity;
import java.sql.Date;
import javax.persistence.CascadeType;
import javax.persistence.GeneratedValue;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import org.hibernate.annotations.Entity;
import org.springframework.data.annotation.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id; //定义主键默认自增长
@OneToOne(cascade=CascadeType.ALL) //OneToOne定义实体是一对一的关系;cascade定义级联范围,all就是所有增删的操作的都关联
@JoinColumn(name="pid",unique=true) //joinColumn定义关联的列,也就是外键;unique表明只有这一个外键
private IdCard card;
private int age;
private Date birth;
public Person(){
}
public Person(int id, IdCard card, int age, Date birth) {
super();
this.id = id;
this.card = card;
this.age = age;
this.birth = birth;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public IdCard getCard() {
return card;
}
public void setCard(IdCard card) {
this.card = card;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
}
映射到数据库中,person表id是主键,pid是外键。idCard表pid是主键。
多对一双单向外键关联
用一个员工只能属于一个公司,一个公司可以有多个员工为例
Company.java
package com.lhzs.tpws.sys.entity;
import javax.persistence.Column;
import org.hibernate.annotations.Entity;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.data.annotation.Id;
@Entity
public class Company {
@Id
@GenericGenerator(name="cid",strategy="assigned")
@Column(length=6)
private String cid;
private String name;
public Company(){
}
public Company(String cid, String name) {
super();
this.cid = cid;
this.name = name;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person.java
package com.lhzs.tpws.sys.entity;
import java.sql.Date;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import org.hibernate.annotations.Entity;
import org.springframework.data.annotation.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private int id; //定义主键默认自增长
//人和身份证,一对一
@OneToOne(cascade=CascadeType.ALL) //OneToOne定义实体是一对一的关系;cascade定义级联范围,all就是所有增删的操作的都关联
@JoinColumn(name="pid",unique=true) //joinColumn定义关联的列,也就是外键;unique表明只有这一个外键
private IdCard card;
//人和公司,多对一
@ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)//fetch是抓取方式
@JoinColumn(name="cid",referencedColumnName="cid")// 关联的列是company.cid
private Company company;
private int age;
private Date birth;
public Person(){
}
public Person(int id, IdCard card, int age, Date birth, Company company) {
super();
this.id = id;
this.card = card;
this.age = age;
this.birth = birth;
this.company = company;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public IdCard getCard() {
return card;
}
public void setCard(IdCard card) {
this.card = card;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
映射到数据库后company表cid是主键,person表id是主键,pid是idCard.id表的外键,cid是company.cid的外键。
多对一双单向外键关联
@OneToMany(cascade={CascadeType.All},fetch=FetchType.LAZY)
@JoinColumn(name="id")
//多对一时,多方设置EAGER,一方设置LAZY
//保存时先保存多方,在实体类中可以设置成Set<>集合
共同学习,写下你的评论
评论加载中...
作者其他优质文章