一、类级别注解
1.1 @Entity --- 声明一个实体类,必加注解
属性:
(1)name : 可选,对应数据库中的一个表,若表名与实体类名相同,则可以省略。
属性:
(1)name : 指定表的名称
(2)catalog : 指定数据库名称
(3)schema : 指定数据库查询的用户名
示例:
@Entity
@Table(name = "t_person", catalog = "hibernateTest")
public class Person {
....
}
二、属性级别注解
2.1 与主键相关注解
2.1.1 @Id --- 映射生成主键,必须
属性:
无
2.1.2 @GeneratedValue --- 用于定义主键生成策略,可选。
属性:
(1) strategy : 表示主键生成策略,取值:
- GenerationType.AUTO : 主键生成策略由数据库自身决定(默认),若数据库支持自动增长类型,则为自动增长。
- GenerationType.INDENTITY : 根据数据库的Identity字段生成,支持DB2、MySQL、MS、SQL Server、SyBase与HyperanoicSQL数据库的Identity型主键。
- GenerationType.SEQUENCE : 使用Sequence来决定主键的取值,适合Oracle、DB2等,结合@SequenceGenerator。(Oracle没有自动增长类型,只能用Sequence)
- GenerationType.TABLE : 使用指定表来保存主键值,结合@TableGenerator使用
@Id
@TableGenerator(name="tab_generator_test",allocationSize=1)
@GeneratedValue(strategy = GenerationType.TABLE)
private Integer id;
(2) generator : 表示主键生成器的名称,这个属性通常和ORM框架相关,配合@GenericGenerator,可以使用Hibernate主键生成策略中的其他策略,如uuid
@Id
@GenericGenerator(strategy = "uuid", name = "myuuid")
@GeneratedValue(generator = "myuuid")
private String id;
2.1.3 @GenericGenerator --- 声明一个hibernate的主键生成策略,与@GeneratedValue结合使用,可选。
属性:
(1) name : 指定生成器名称,它被引用在@GeneratedValue中设置的generator属性值中。
(2) strategy : 指定具体生成器的主键生成策略。
(3) parameters : 得到strategy指定的具体生成器所用到的参数。
主键策略:
http://blog.csdn.net/ka_ka314/article/details/79016161
@Id
@GenericGenerator(strategy = "uuid", name = "myuuid")
@GeneratedValue(generator = "myuuid")
private String id;
2.1.4 @SequenceGenerator --- 注解声明了一个数据库序列,与@GeneratedValue结合使用,可选。
属性:
(1) name : 表示该表主键生成策略名称,它被引用在@GeneratedValue中设置的“gernerator”值中
(2) sequenceName : 表示生成策略用到的数据库序列名称。
(3) initialValue : 表示主键初始值,默认为0。
(4) allocationSize : 每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
2.1.5 @TableGenerator --- 注解声明了表主键生成策略机制,可选。
属性:
(1) name : 属性表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的generator属性值中。
(2) table : 属性表示表生成策略所持久化的表名
(3) catalog和schema : catalog属性和schema具体指定表所在的目录名或是数据库名。
(4) pkColumnName : 属性的值表示在持久化表中,该主键生成策略所对应键值的名称。
(5) pkColumnValue : 属性的值表示在持久化表中,该生成策略所对应的主键。
(6) valueColumnName : 属性的值表示在持久化表中,该主键当前所生成的值,它的值将会随着每次创建累加。
(7) initialValue : 表示主键初识值,默认为0。
(8) allocationSize : 表示每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50。
@Id
@TableGenerator(name="tab_generator_test",allocationSize=1)
@GeneratedValue(strategy = GenerationType.TABLE)
private Integer id;
2.2 与非主键相关注解
2.2.1 @Version--- 声明了对乐观锁定的支持
@Version
@Column(name="version_test")
public Integer getVersion() { ... }
2.2.2 @Transient --- 声明了非持久化属性,即数据库中没有响应的映射字段,是一个普通属性
属性:
无
@Transient
private String msg;
2.2.3 @Temporal --- 声明了日期类型
@Temporal(TemporalType.TIMESTAMP) //是用来定义日期类型
private Date publicationDate; //出版日期
日期类型:
- TemporalType.DATE : 日期
- TemporalType.TIME : 时间
- TemporalType.TIMESTAMP : 日期和时间
@Temporal(TemporalType.TIMESTAMP) //是用来定义日期类型
private Date publicationDate; //出版日期
2.2.4 @Column --- 映射表的列,可选,默认是类的属性名
属性:
(1) name : 属性定义了被标注字段在数据库表中所对应字段的名称
(2) unique : 属性表示该字段是否为唯一表示,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中的@UniqueConstraint。
(3) nullable : 属性表示该字段是否可以为null值,默认为true。
(4) insertable :属性表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。
(5) updatable : 属性表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。
(6) columnDefinition : 属性表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。(也就是说,如果DB中表已经建好,该属性没有必要使用。)
(7) table : 属性定义了包含当前字段的表名。
(8) length : 属性表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。
(9) precision和scale : precision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。
注:此标记可以标注在getter方法或属性上
@Column(name="c_name",length=30,nullable=true)
private String name;
2.2.5 @Type --- 声明属性类型
属性:
(1) type : 类型
@Type(type="string")
private String name;
2.2.6 @Basic --- 声明属性的存取策略,所有没有定义注解的属性,等价于在属性上添加@Basic
属性:
(1) fetch : 是否延迟加载
(2) optional : 该列是否可以为null
2.2.7 @JoinColumn --- 指定对应的外键的列
属性:
(1) name : 属性定义了被标注字段在数据库表中所对应外键的名称
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "c_customer_id") // 指定外键列
private Customer c; // 描述订单属于某一个客户
三、一对一关联注解
@OneToOne --- 表示一对一的映射
属性:
(1) fetch : 配置加载方式,取值有:
- FetchType.EAGER : 及时加载,多对一默认是FetchType.EAGER
- FetchType.LAZY : 延迟加载,一对多默认是FetchType.LAZY
(2) cascade : 设置级联方式,取值有:
- CascadeType.PERSIST : 保存
- CascadeType.REMOVE : 删除
- CascadeType.MERGE : 修改
- CascadeType.REFRESSH : 刷新
- CascadeType.ALL : 全部
(4) targetEntity : 定义关系类的类型
(5) optional : 该列是否可以为null
(6) orphanRemoval : 作用是删除孤立记录,即外键为空的类型,默认为false。该属性为true时会根据外键执行级联删除。
3.1 外键映射
示例:
User类
package com.hibernate.oneToOne;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "t_user")
public class User {
@Id
@GenericGenerator(strategy = "uuid", name = "myuuid")
@GeneratedValue(generator = "myuuid")
private String id;
private String name;
/*
* mappedBy : 外键维护方
*/
@OneToOne(targetEntity = IDCard.class,
mappedBy = "user")
private IDCard idCard;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IDCard getIdCard() {
return idCard;
}
public void setIdCard(IDCard idCard) {
this.idCard = idCard;
}
}
IDCard类:
package com.hibernate.oneToOne;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "t_idcard")
public class IDCard {
@Id
@GenericGenerator(strategy = "uuid", name = "myuuid")
@GeneratedValue(generator = "myuuid")
private String id;
private String cardNum;
@OneToOne(targetEntity = User.class)
@JoinColumn(name = "c_user_id")
@Cascade(CascadeType.SAVE_UPDATE)
private User user;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCardNum() {
return cardNum;
}
public void setCardNum(String cardNum) {
this.cardNum = cardNum;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
Test类
// 测试一对一操作外键映射方案(由idcard维护外键)
@Test
public void test6() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 1.创建一个人
User user = new User();
user.setName("张龙");
// 2.创建身份证号
IDCard idcard = new IDCard();
idcard.setCardNum("1234567890");
// 3.身份证号关联人
idcard.setUser(user);
// 4.存储身份证号
session.save(idcard);
session.getTransaction().commit();
session.close();
}
3.2 主键映射
Husband类
package com.hibernate.oneToOne;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name = "t_husband")
public class Husband {
@Id
@GenericGenerator(name = "myForeignKey", strategy = "foreign", parameters = {
@Parameter(name = "property", value = "wife") })
@GeneratedValue(generator = "myForeignKey")
private String id;
private String name;
@OneToOne(mappedBy = "husband")
@PrimaryKeyJoinColumn
private Wife wife;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Wife getWife() {
return wife;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife类
package com.hibernate.oneToOne;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "t_wife")
public class Wife {
@Id
@GenericGenerator(name = "myuuid", strategy = "uuid")
@GeneratedValue(generator = "myuuid")
private String id;
private String name;
@OneToOne
@PrimaryKeyJoinColumn
@Cascade(CascadeType.SAVE_UPDATE)
private Husband husband;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
}
Test类
// 测试一对一主键生成策略
@Test
public void test7() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 创建丈夫
Husband husband = new Husband();
husband.setName("武大郎");
// 创建妻子
Wife wife = new Wife();
wife.setName("潘金莲");
// 要做双向关联
husband.setWife(wife);
wife.setHusband(husband);
session.save(wife);
session.getTransaction().commit();
session.close();
}
四、多对一和一对多关联注解
@ManyToOne | @OneToMany --- 表示多对一 | 一对多
属性:
参考一对一
示例:
Customer类
package com.hibernate.oneToMany;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="t_customer")
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id; // 主键
private String name; // 姓名
// 描述客户可以有多个订单
/*
* targetEntity相当于<one-to-many class="">
* mappedBy相当于inverse=true
*/
@OneToMany(targetEntity=Order.class,mappedBy="c",orphanRemoval=true)
private Set<Order> orders = new HashSet<Order>();
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Order类
package com.hibernate.oneToMany;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
//订单-----多的一方
@Entity
@Table(name = "t_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private Double money;
private String receiverInfo; // 收货地址
// 订单与客户关联
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "c_customer_id") // 指定外键列
private Customer c; // 描述订单属于某一个客户
public Customer getC() {
return c;
}
public void setC(Customer c) {
this.c = c;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public String getReceiverInfo() {
return receiverInfo;
}
public void setReceiverInfo(String receiverInfo) {
this.receiverInfo = receiverInfo;
}
}
Test类:
// 测试one-to-many注解操作(保存客户时级联保存订单)
@Test
public void test3() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 1.创始一个客户
Customer c = new Customer();
c.setName("张龙");
// 2创始两个订单
Order o1 = new Order();
o1.setMoney(100d);
o1.setReceiverInfo("北京");
Order o2 = new Order();
o2.setMoney(2000d);
o2.setReceiverInfo("上海");
// 3.建立关系
// 原因:是为了维护外键
o1.setC(c);
o2.setC(c);
// 原因:是为了进行级联操作
c.getOrders().add(o1);
c.getOrders().add(o2);
// 4.保存客户,并级联保存订单
session.save(c);
session.getTransaction().commit();
session.close();
}
五、多对多关联注解
@ManyToMany
属性:
参考一对一
示例:
Teacher类
package com.hibernate.manyToMany;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name = "t_teacher")
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(targetEntity = Student.class, mappedBy = "teachers") // 代表由对方来维护外键
@Cascade(CascadeType.ALL)
private Set<Student> students = new HashSet<Student>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
Student类
package com.hibernate.manyToMany;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@ManyToMany(targetEntity = Teacher.class)
// 使用JoinTabl来描述中间表,并描述中间表中外键与Student,Teacher的映射关系
// joinColumns它是用来描述Student与中间表中的映射关系
// inverseJoinColums它是用来描述Teacher与中间表中的映射关系
// referencedColumnName映射的是类中的哪个字段
@JoinTable(name = "s_t", joinColumns = {
@JoinColumn(name = "c_student_id", referencedColumnName = "id") }, inverseJoinColumns = {
@JoinColumn(name = "c_teacher_id", referencedColumnName = "id") })
@Cascade(CascadeType.ALL)
private Set<Teacher> teachers = new HashSet<Teacher>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
Test类
// 测试多对多级联删除(前提是建立了双向的级联 All)
@Test
public void test5() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
Student s = session.get(Student.class, 1);
session.delete(s);
session.getTransaction().commit();
session.close();
}
// 测试多对多级联保存(保存学生时保存老师)
@Test
public void test4() {
Session session = HibernateUtils.openSession();
session.beginTransaction();
// 1.创建两个老师
Teacher t1 = new Teacher();
t1.setName("tom");
Teacher t2 = new Teacher();
t2.setName("fox");
// 2.创建两个学生
Student s1 = new Student();
s1.setName("张三");
Student s2 = new Student();
s2.setName("张龙");
// 3.学生关联老师
s1.getTeachers().add(t1);
s1.getTeachers().add(t2);
s2.getTeachers().add(t1);
s2.getTeachers().add(t2);
// 4.保存学生
session.save(s1);
session.save(s2);
session.getTransaction().commit();
session.close();
}