Hibernate注解

使用注解的目的

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

JPA与Hibernate的关系

什么是JPA?
JPA即Java Persistence API
JPA注解是JavaEE的规范和标准

JPA与Hibernate的关系
JPA是标准接口,Hibernate是实现,但是其功能是JPA的超集,即HIbernate更强大

Hibernate如何实现与JPA的关系
通过hibernate-annotation、hibernate-entityManager、hibernate-core三个组件实现

注意:一般在实际开发中,优先考虑使用JPA注解,这样更有利于程序的移植性和扩展

Hibernate注解的分类

  • 类级别注解
  • 属性级别注解
  • 映射关系注解

常见的类级别注解

@Entity 表示一个实体类,对应数据库中的一张表
@Table 表示表
@Embeddable 表示一个嵌入类

@Entity:映射实体类

  • @Entity(name=”tableName”)
  • name:可选,对应数据库中的一张表,若表名与实体类名相同,可省略
  • 注意:使用@Entity时必须指定实体类的主键属性
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity(name="t_student")
public class Student {

    @Id//设置主键
    private int id;

    private String name;
}

@Table(name=”“,catalog=”“,schema=”“)

  • 与@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息
  • name:可选,映射表的名称,默认表名与实体名一致,只有在不一致的情况下才需要指定表名
  • catalog:可选,表示catalog名称,默认为catalog(“”)
  • schema:可选,表示schema名称,默认为schema(“”)
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="t_student")
@Entity
public class Student {

    @Id//设置主键
    private int id;

    private String name;
}

@Embeddable

  • 表示一个非Entity类可以嵌入到另一个Entity类中作为属性而存在,不对应数据库中的一张表
import javax.persistence.Embeddable;

@Embeddable
public class Address {

    private String address;

    private String phone;
}

Hibernate属性级别注解

添加方式

  • 写在属性字段上面
  • 写在属性的get访问器的上面

@Id

  • 必须,定义了映射到数据库表的主键的属性,一个实体类可以有一个或多个属性被映射为主键,可置于主键属性或get方法前
  • 若果有多个属性定义为主键属性,该实体类必须实现Serializable接口
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Table(name="t_student")
@Entity
public class Student implements Serializable{

    private static final long serialVersionUID = -5577849458641751334L;

    @Id//设置主键
    private int id;

    @Id
    @Column(length=8)//若String类型为主键,长度不能过长
    private String name;
}

@GeneratedValue(strategy=GenerationType.AUTO,generator=”“)

  • 可选,用于定义主键生成策略
  • strategy表示主键生成策略,取值有以下几种
  • GenerationType.AUTO:根据底层数据库自动选择(默认)
  • GenerationType.INDENTITY:根据数据库的Identity字段生成
  • GenerationType.SEQUENCE:使用sequence来决定主键的取值
  • GenerationType.TABLE:使用指定表来决定主键取值,结合@TableGenerator使用
    @Id//设置主键
    @TableGenerator(name="tab_cat",allocationSize=1)
    @GeneratedValue(strategy=GenerationType.TABLE)
    private int id;

Generator表示主键生成器的名称,这个属性通常和ORM框架有关
eg:Hibernate可以指定uuid等生成主键

  • 指定主键生成策略为手动指定主键的值
    @Id
    @GeneratedValue(generator="id")
    @GenericGenerator(name="id",strategy="assigned")
    @Column(length=8)
    private String id;

@Column

  • @Column可将属性映射到列,使用该注解来覆盖默认值
  • @Column描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具非常有用
  • 常用属性有如下几个
  • name:可选,表示数据库表中该字段名称,默认情形属性名称一致
  • nullable:可选,表示该字段是否允许为null,默认为true
  • unique:可选,表示该字段是否是唯一标识,默认为false
  • length:可选,表示该字段的大小,仅对String类型的字段有效,默认为255,如果是主键的话则不能使用默认值
  • insertable:可选,表示在ORM框架执行插入操作时,该字段是否应出现在INSERT语句中,默认为true
  • updateable:可选,表示在ORM框架执行更新操作时,该字段是否应出现在UPDATE语句中,默认为true,对于一经创建就不可以更改的字段,该属性非常有用,如注册日期

@Embedded

  • @Embedded是注释属性的,表示该属性的类是嵌入类
  • 同时嵌入类也必须标注@Embeddable注解

@EmbeddedId

  • @EmbeddedId使用嵌入式主键类实现复合主键
  • 注意:嵌入式主键类必须实现Serializable接口、必须有默认的public无参构造函数、必须覆盖equals()和hashCode()方法
import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class Address implements Serializable{

    private static final long serialVersionUID = 1L;

    private String address;

    private String phone;

    public Address() {
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return super.equals(obj);
    }
}


----------


另一个类中
@EmbeddedId
private Address address;

@Transient

  • 可选,表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性,如果一个属性并非数据库表的字段映射,就务必将其标注为@Transient,否则ORM框架默认其注解为@Basic

Hibernate关联映射注解

  • 一对一单向外键
  • 一对一双向外键
  • 一对一双向外键联合主键
  • 多对一单向外键
  • 一对多单向外键
  • 一对多双向外键
  • 多对多单向外键
  • 多对多双向外键

一对一单向外键

    @OneToOne(cascade = CascadeType.ALL)//级联操作
    @JoinColumn(name = "pid", unique = true)//唯一
  • 保存时应该先保存外键对象,再保存主表对象
  • 学生一对一身份证
package oneToOne;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

@Entity
public class Students {

    @Id
    @GeneratedValue// 自增长
    private int sid;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "pid", unique = true)
    private IdCard idCard;
}


----------


package oneToOne;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.hibernate.annotations.GenericGenerator;

@Entity
public class IdCard {

    @Id
    @GeneratedValue(generator = "pid")
    @GenericGenerator(name = "pid", strategy = "assigned")
    @Column(length = 8)
    private String pid;

    private String sname;
}

一对一双向外键

  • 主控方的配置同一对一单向外键关联
  • 被控方:@OneToOne(mappedBy = “idCard”)
  • 双向关联,必须设置mappedBy属性。因为双向关联只能交给一方去控制,不可能在双方都设置外键保存关联关系,否则双方都无法保存
  • 学生类同上面一样
package oneToOne;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class IdCard {

    @Id
    @GeneratedValue(generator = "pid")
    @GenericGenerator(name = "pid", strategy = "assigned")
    @Column(length = 8)
    private String pid;

    private String sname;

    @OneToOne(mappedBy = "idCard")
    private Students stu;
}

一对一双向外键联合主键

  1. 创建主键类,加@Embeddable
  2. 主键类必须实现Serializable接口,重写hashCode()和equals()方法
  3. 联合主键上使用@EmbeddedId

多对一单向外键

  • 多方持有一方的引用,比如:多个学生对应一个班级(多对一)
@ManyToOne(cascade = { CascadeType.ALL }, //级联操作
            fetch =FetchType.EAGER)//抓取策略:积极
@JoinColumn(name = "cid",//外键属性名
             referencedColumnName = "CID")//数据库表中字段名
package oneToMany;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Students {

    @Id
    @GeneratedValue// 自增长
    private int sid;

    @ManyToOne(cascade = { CascadeType.ALL }, 
                fetch =  FetchType.EAGER)
    @JoinColumn(name = "cid", referencedColumnName = "CID")
    private ClassRoom classRoom;
}


----------


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 javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import org.hibernate.annotations.GenericGenerator;

@Entity
public class ClassRoom {

    @Id
    @GeneratedValue(generator = "cid")
    @GenericGenerator(name = "cid", strategy = "assigned")
    @Column(length = 8)
    private String cid;
}

一对多单向外键

  • 一方持有多方的集合,一个班级有多个学生(一对多)
@OneToMany(cascade = { CascadeType.ALL }, 
        fetch = FetchType.LAZY)//懒加载
@JoinColumn(name = "cid")//外键属性名
students和上面的一样
package oneToMany;

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 javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class ClassRoom {

    @Id
    @GeneratedValue(generator = "cid")
    @GenericGenerator(name = "cid", strategy = "assigned")
    @Column(length = 8)
    private String cid;

    @OneToMany(cascade = { CascadeType.ALL }, 
                fetch = FetchType.LAZY)
    @JoinColumn(name = "cid")
    private Set<Students> stus;

}

总结:多对一的时候,多方设置EAGER,一方设置LAZY

多对多单向外键

  • 学生和教师构成多对多的关联关系
  • 其中一个多方持有另一个多方的集合对象(学生持有教师的集合)
@ManyToMany
@JoinTable(name = "teachers_students", 
        joinColumns = { @JoinColumn(name = "sid") },
        inverseJoinColumns = { @JoinColumn(name = "tid") })
package manyToMany;

import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import org.hibernate.annotations.GenericGenerator;

@Entity
public class Teachers {

    @Id
    @GeneratedValue(generator = "tid")
    @GenericGenerator(name = "tid", strategy = "assigned")
    @Column(length = 8)
    private String tid;
}


----------
package manyToMany;

import java.util.Set;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

public class Students {

    @Id
    @GeneratedValue// 自增长
    private int sid;

    @ManyToMany
    @JoinTable(name = "teachers_students", 
    joinColumns = { @JoinColumn(name = "sid") }, 
    inverseJoinColumns = { @JoinColumn(name = "tid") })
    private Set<Teachers> teachers;
}

多对多双向外键

  • 双方持有对方的集合对象,其中一方设置
    @ManyToMany(mappedBy = "teachers")
package manyToMany;

import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import org.hibernate.annotations.GenericGenerator;

@Entity
public class Teachers {

    @Id
    @GeneratedValue(generator = "tid")
    @GenericGenerator(name = "tid", strategy = "assigned")
    @Column(length = 8)
    private String tid;

    @ManyToMany(mappedBy = "teachers")
    private Set<Students> students;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值