一、类级别注解
1. Hibernate注解简介
使用注解的目的:为了简化繁琐的ORM映射文件(*.hbm)的配置
2. JPA与Hibernate的关系
JPA,全称Java Persistence API,JPA注解是JAVAEE的标准和规范
JPA和Hibernate的关系:JPA是标准接口,Hibernate是实现,但是其功能是JPA的超集
Hibernate通过hibernate-annotation、hibernate-entitymanager和hibernate-core三个组件来实现JPA
一般在实际开发中,优先考虑使用JPA注解,这样更有利于程序的移植和扩展
3. Hibernate注解分类
类级别注解
属性级别注解
映射关系注解
4.类级别注解:
@Entity--实体类注解
@Table--表注解
@Embeddable--嵌入类注解

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">update</property> <property name="hibernate.current_session_context_class">thread</property> </session-factory> </hibernate-configuration>
@Entity注解——映射实体类
@Entity(name=“tableName”)
name:可选,对应数据库中的一个表。若表名与实体类名相同,则可以省略
注意:使用@Entity时必须指定实体类的主键属性,用@Id在主键属性的get方法上注解。
@Table(name=“”,catalog=“”,schema=“”)
与@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息
name:可选,映射表的名称,默认表明与实体名称一致,只有在不一致的情况下才需要指定表名
catalog:可选,表示Catalog名称,默认为Catalog(“”)
schema:可选,表示Schema名称,默认为Schema(“”)
Catalog:将远程或本地的数据库服务器中的实例或库映射到用户主机,以方便用户执行各种操作。
Schema:数据库对象的集合,一个用户一般对应一个schema。
可以把它们理解为一个容器或者数据库对象命名空间中的一个层次,主要用来解决命名冲突问题.
catalog为目录,schema为模式.
从概念上说,一个数据库系统包含多个Catalog,每个Catalog又包含多个Schema,而每个Schema又包含多个数据库对象(表、视图、字段等),反过来讲一个数据库对象必然属于一个Schema,而该Schema又必然属于一个Catalog. 这样我们就可以得到该数据库对象的完全限定名称从而解决命名冲突的问题了
例如数据库对象表的全限定名称就可以表示为:Catalog名 称.Schema名称.表名称.
不同数据库对schema、catalog的支持不同.
@Embeddable
1.@Embeddable表示一个非Entity类可以嵌入到另一个Entity类中作为属性而存在。
2.@Embeddable不生成独立的表,可以理解@Embeddable注解类为属性集。
二、属性级别注解
1.属性级别注解
@Id
@SequenceGenerator
@GeneratedValue
@Column
@Embedded
@EmbeddedId
@Lob
@Version
@Basic
@Transient
2.添加方式
一是写在属性字段上面
二是写在属性的get访问器的上面
@Id
必须,定义了映射到数据库表的主键的属性,一个实体类可以有一个或者多个属性被映射为主键,可置于主键属性或者getXxxx()前
注意:如果有多个属性定义为主键属性,该实体类必须实现serializable接口
注意:将 String类型的属性设置成主键是一定要指定该属性的长度,可以用@Column(length=8)注解来指定,不然MySQL会默认让其长度为255,而MySQL主键的长度不允许太长。
@GeneratedValue注解
@GeneratedValue注解与@Id注解一起使用,用于定义主键的生成策略. 包含两个属性strategy(主键生成策略)、generator(主键生成器)
strategy可以取:
1.GenerationType.AUTO:根据底层数据库自动选择(默认)
2.GenerationType.INDENTITY:根据数据库的Identity字段生成.
3.GenerationType.SEQUENCE:使用Sequence(序列)来决定主键的取值.
4.GenerationType.TABLE:使用指定的表来决定主键的取值 (结合某些表来实现,必须与@TableGenerator注解一起使用).
如:@Id
@GeneratedValue(strategy=GenerationType.TABLE)
@TableGenerator(name="tab_cat_gen",allocationSize=1)
generator表示主键生成器的名称,这个属性通常与ORM框架相关。例如Hibernate可以指定uuid等主键生成方式
如:@Id
@GeneratedValue(generator="sid")
@GenericGenerator(name="sid", strategy="assigned")
@Column(length=8)
@Column
可将属性映射到列,使用该注解来覆盖默认值,@Column描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具非常有用
常用属性:
name:可选,表示数据库表中该字段的名称,默认情形属性名称一致;
nullable:可选,表示该字段是否允许为null,默认为true;
unique:可选,表示该字段是否是唯一标识,默认为false;
length:可选,表示该字段的大小,仅对String类型的字段有效,默认值255(如果是主键,不能使用默认值);
insertable:可选,表示在ORM框架执行插入操作时,该字段是否应出现在INSERT语句中,默认为true;
updateable:可选,表示在ORM框架执行更新操作时,该字段是否应出现在UPDATE语句中,默认为true,对于一经创建就不能修改的字段,该属性非常有用,如对于birthday字段。
@Embedded
注释属性,表示该属性的类是嵌入类
注意:同时嵌入类也必须标注@Embeddable
@EmbeddedId:
@EmbeddedId使用嵌入式主键类实现复合主键。
注意:嵌入式主键类必须实现Serializable接口、必须有默认的public无参数的构造方法、必须覆盖equals和hashCode方法。
@Transient:
可选,表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性,如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则ORM框架默认其注解为@Basic。
三、关联映射注解
实体之间的映射关系
一对一:一个公民对应一个身份证号码
一对多(多对一):一个公民有多个银行帐号
多对多:一个学生有多个老师,一个老师有多个学生。
1、一对一单向外键关联
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="pid", unique=true) 参数name为被控类主键,主控类的外键,unique标识该主键唯一
注意:保存时应先保存外键对象,再保存主表对象
2.一对一双向外键关联
单向外键主控类对于被控类透明。主控类知道被控类。双向外键主被控类双方都知道
一对一双向:在一对一单向基础上,在被控类中添加主控类的对象,并且添加@OneToOne注解,且该注解的属性mappedBy必须设置,设置成主控类中被控类的对象。
@OneToOne(MappedBy="xx") 其中xx是主控类中被控类的对象名字
双向关联必须设置mappedBy属性,因为双向关联只能交给一方去控制,不可能在双方都设置外键保存关联关系,否则双方都无法保存
3.一对一单向外键联合主键
1.创建主键类
2.主键类必须实现Serializable接口,重写hasCode()和equals()方法
3.主键类用@Embeddable注解,实体类属性用@EmbeddedId注解,可参考之前的内容
4.多对一单向外键关联
@ManyToOne(cascade={CasCadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name="rid", referencedColumnName="cid")
//name=定义外键在本表的字段名 referencedColumnName=关联外键对象的哪个字段
5.一对多单向外键关联
无论使用一对多还是多对一,外键字段都是存在多方的表当中.
@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
@JoinColumn(name="cid"); //指定外键名字
总结:使用多对一时,多方的抓取策略fetch一般设置为EAGER、一方设置为LAZY.
当使用单向的一对多关联时,要先保存多方的数据再保存一方的数据.外键存在多方表中.
6.一对多(多对一)双向外键关联
多方:多方持有一方的引用
@ManyToOne(cascade={CasCadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name="cid")
一方:一方持有多方的集合
@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY)
@JoinColumn(name="cid");
7.多对多单向外键关联
保存时先保存被控方,因为是学生主控方,所以对方先保存,再自己(主控方)保存。【在单向的情况下,双向就无需纠结这个问题】
8、多对多双向外键关联
@ManyToMany(mappedBy="teachers")——将主控方交给学生来处理,很多人误认为是交给老师来处理。
9.总结
a) 只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
b) mappedBy标签一定是定义在the owned side(被拥有方的),他指向theowning side(拥有方);
c) 关系的拥有方负责关系的维护,在拥有方建立外键。所以用到@JoinColumn;
d)mappedBy跟JoinColumn/JoinTable总是处于互斥的一方