Hibernate3注解 收藏
一、@Entity(name="EntityName")
必须,name为可选,对应数据库中一的个表java
二、@Table(name="",catalog="",schema="")
可选,一般和@Entity配合使用,只能标注在实体的class定义处,表示实体对应的数据库表的信息
name:可选,表示表的名称.默认地,表名和实体名称一致,只有在不一致的状况下才须要指定表名
catalog:可选,表示Catalog名称,默认为Catalog("").
schema:可选,表示Schema名称,默认为Schema("").spring
三、@id
必须
@id定义了映射到数据库表的主键的属性,一个实体只能有一个属性被映射为主键.置于getXxxx()前.数据库
四、@GeneratedValue(strategy=GenerationType,generator="")
可选
strategy:表示主键生成策略,有AUTO,INDENTITY,SEQUENCE 和 TABLE 4种,分别表示让ORM框架自动选择,
根据数据库的Identity字段生成,根据数据库表的Sequence字段生成,以有根据一个额外的表生成主键,默认为AUTO
generator:表示主键生成器的名称,这个属性一般和ORM框架相关,例如,Hibernate能够指定uuid等主键生成方式.
示例:
@Id
@GeneratedValues(strategy=StrategyType.SEQUENCE)
public int getPk() {
return pk;
}api
五、@Basic(fetch=FetchType,optional=true)
可选
@Basic表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的getXxxx()方法,默认即为@Basic
fetch: 表示该属性的读取策略,有EAGER和LAZY两种,分别表示主支抓取和延迟加载,默认为EAGER.
optional:表示该属性是否容许为null,默认为true
示例:
@Basic(optional=false)
public String getAddress() {
return address;
}session
六、@Column
可选
@Column描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具很是有做用.
name:表示数据库表中该字段的名称,默认情形属性名称一致
nullable:表示该字段是否容许为null,默认为true
unique:表示该字段是不是惟一标识,默认为false
length:表示该字段的大小,仅对String类型的字段有效
insertable:表示在ORM框架执行插入操做时,该字段是否应出现INSETRT语句中,默认为true
updateable:表示在ORM框架执行更新操做时,该字段是否应该出如今UPDATE语句中,默认为true.对于一经建立就不能够更改的字段,该属性很是有用,如对于birthday字段.
columnDefinition:表示该字段在数据库中的实际类型.一般ORM框架能够根据属性类型自动判断数据库中字段的类型,可是对于Date类型仍没法肯定数据库中字段类型到底是DATE,TIME仍是TIMESTAMP.此外,String的默认映射类型为VARCHAR,若是要将String类型映射到特定数据库的BLOB或TEXT字段类型,该属性很是有用.
示例:
@Column(name="BIRTH",nullable="false",columnDefinition="DATE")
public String getBithday() {
return birthday;
}app
七、@Transient
可选
@Transient表示该属性并不是一个到数据库表的字段的映射,ORM框架将忽略该属性.
若是一个属性并不是数据库表的字段映射,就务必将其标示为@Transient,不然,ORM框架默认其注解为@Basic
示例:
//根据birth计算出age属性
@Transient
public int getAge() {
return getYear(new Date()) - getYear(birth);
}框架
八、@ManyToOne(fetch=FetchType,cascade=CascadeType)
可选
@ManyToOne表示一个多对一的映射,该注解标注的属性一般是数据库表的外键
optional:是否容许该字段为null,该属性应该根据数据库表的外键约束来肯定,默认为true
fetch:表示抓取策略,默认为FetchType.EAGER
cascade:表示默认的级联操做策略,能够指定为ALL,PERSIST,MERGE,REFRESH和REMOVE中的若干组合,默认为无级联操做
targetEntity:表示该属性关联的实体类型.该属性一般没必要指定,ORM框架根据属性类型自动判断targetEntity.
示例:
//订单Order和用户User是一个ManyToOne的关系
//在Order类中定义
@ManyToOne()
@JoinColumn(name="USER")
public User getUser() {
return user;
}dom
九、@JoinColumn
可选
@JoinColumn和@Column相似,介量描述的不是一个简单字段,而一一个关联字段,例如.描述一个@ManyToOne的字段.
name:该字段的名称.因为@JoinColumn描述的是一个关联字段,如ManyToOne,则默认的名称由其关联的实体决定.
例如,实体Order有一个user属性来关联实体User,则Order的user属性为一个外键,
其默认的名称为实体User的名称+下划线+实体User的主键名称
示例:
见@ManyToOneide
十、@OneToMany(fetch=FetchType,cascade=CascadeType)
可选
@OneToMany描述一个一对多的关联,该属性应该为集体类型,在数据库中并无实际字段.
fetch:表示抓取策略,默认为FetchType.LAZY,由于关联的多个对象一般没必要从数据库预先读取到内存
cascade:表示级联操做策略,对于OneToMany类型的关联很是重要,一般该实体更新或删除时,其关联的实体也应当被更新或删除
例如:实体User和Order是OneToMany的关系,则实体User被删除时,其关联的实体Order也应该被所有删除
示例:
@OneTyMany(cascade=ALL)
public List getOrders() {
return orders;
}工具
十一、@OneToOne(fetch=FetchType,cascade=CascadeType)
可选
@OneToOne描述一个一对一的关联
fetch:表示抓取策略,默认为FetchType.LAZY
cascade:表示级联操做策略
示例:
@OneToOne(fetch=FetchType.LAZY)
public Blog getBlog() {
return blog;
}
十二、@ManyToMany
可选
@ManyToMany 描述一个多对多的关联.多对多关联上是两个一对多关联,可是在ManyToMany描述中,中间表是由ORM框架自动处理
targetEntity:表示多对多关联的另外一个实体类的全名,例如:package.Book.class
mappedBy:表示多对多关联的另外一个实体类的对应集合属性名称
示例:
User实体表示用户,Book实体表示书籍,为了描述用户收藏的书籍,能够在User和Book之间创建ManyToMany关联
@Entity
public class User {
private List books;
@ManyToMany(targetEntity=package.Book.class)
public List getBooks() {
return books;
}
public void setBooks(List books) {
this.books=books;
}
}
@Entity
public class Book {
private List users;
@ManyToMany(targetEntity=package.Users.class, mappedBy="books")
public List getUsers() {
return users;
}
public void setUsers(List users) {
this.users=users;
}
}
两个实体间相互关联的属性必须标记为@ManyToMany,并相互指定targetEntity属性,
须要注意的是,有且只有一个实体的@ManyToMany注解须要指定mappedBy属性,指向targetEntity的集合属性名称
利用ORM工具自动生成的表除了User和Book表外,还自动生成了一个User_Book表,用于实现多对多关联
1三、@MappedSuperclass
可选
@MappedSuperclass能够将超类的JPA注解传递给子类,使子类可以继承超类的JPA注解
示例:
@MappedSuperclass
public class Employee() {
....
}
@Entity
public class Engineer extends Employee {
.....
}
@Entity
public class Manager extends Employee {
.....
}
1四、@Embedded
可选
@Embedded将几个字段组合成一个类,并做为整个Entity的一个属性.
例如User包括id,name,city,street,zip属性.
咱们但愿city,street,zip属性映射为Address对象.这样,User对象将具备id,name和address这三个属性.
Address对象必须定义为@Embededable
示例:
@Embeddable
public class Address {city,street,zip}
@Entity
public class User {
@Embedded
public Address getAddress() {
..........
}
}
如今,让咱们来动手使用Hibernate Annotation。
安装 Hibernate Annotation
要使用 Hibernate Annotation,您至少须要具有 Hibernate 3.2和Java 5。能够从 Hibernate 站点 下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项以外,您还须要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。若是您正在使用 Maven,只须要向 POM 文件添加相应的依赖项便可,以下所示:
...
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
...
下一步就是获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工做与使用 Hibernate Annotations有所不一样。您须要使用 AnnotationConfiguration 类来创建会话工厂:
sessionFactory = new
AnnotationConfiguration().buildSessionFactory();
尽管一般使用 <mapping> 元素来声明持久性类,您仍是须要在 Hibernate 配置文件(一般是 hibernate.cfg.xml)中声明持久性类:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="com.onjava.modelplanes.domain.PlaneType"/>
<mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
</session-factory>
</hibernate-configuration>
近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。若是您正在使用 Spring 框架,可使用 AnnotationSessionFactoryBean 类轻松创建一个基于注释的 Hibernate 会话工厂,以下所示:
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
...
</props>
</property>
<property name="annotatedClasses">
<list>
<value>com.onjava.modelplanes.domain.PlaneType</value>
<value>com.onjava.modelplanes.domain.ModelPlane</value>
...
</list>
</property>
</bean>
第一个持久性类
既然已经知道了如何得到注释所支持的 Hibernate 会话,下面让咱们来了解一下带注释的持久性类的状况:
像在其余任何 Hibernate应用程序中同样,带注释的持久性类也是普通 POJO。差很少能够说是。您须要向 Java 持久性 API (javax.persistence.*)添加依赖项,若是您正在使用任何特定于 Hibernate的扩展,那极可能就是 Hibernate Annotation 程序包(org.hibernate.annotations.*),但除此以外,它们只是具有了持久性注释的普通 POJO 。下面是一个简单的例子:
@Entity
public class ModelPlane {
private Long id;
private String name;
@Id
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
正像咱们所提到的,这很是简单。@Entity 注释声明该类为持久类。@Id 注释能够代表哪一种属性是该类中的独特标识符。事实上,您既能够保持字段(注释成员变量),也能够保持属性(注释getter方法)的持久性。后文中将使用基于属性的注释。基于注释的持久性的优势之一在于大量使用了默认值(最大的优势就是 “惯例优先原则(convention over configuration)”)。例如,您无需说明每一个属性的持久性——任何属性都被假定为持久的,除非您使用 @Transient 注释来讲明其余状况。这简化了代码,相对使用老的 XML 映射文件而言也大幅地减小了输入工做量。
生成主键
Hibernate 可以出色地自动生成主键。Hibernate/EBJ 3 注释也能够为主键的自动生成提供丰富的支持,容许实现各类策略。下面的示例说明了一种经常使用的方法,其中 Hibernate 将会根据底层数据库来肯定一种恰当的键生成策略:
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
定制表和字段映射
默认状况下,Hibernate 会将持久类以匹配的名称映射到表和字段中。例如,前一个类能够与映射到以以下代码建立的表中:
CREATE TABLE MODELPLANE
(
ID long,
NAME varchar
)
若是您是本身生成并维护数据库,那么这种方法颇有效,经过省略代码能够大大简化代码维护。然而,这并不能知足全部人的需求。有些应用程序须要访问外部数据库,而另外一些可能须要听从公司的数据库命名惯例。若是有必要,您可使用 @Table 和 @Column 注释来定制您本身的持久性映射,以下所示:
@Entity
@Table(name="T_MODEL_PLANE")
public class ModelPlane {
private Long id;
private String name;
@Id
@Column(name="PLANE_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name="PLANE_NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
该内容将映射到下表中:
CREATE TABLE T_MODEL_PLANE
(
PLANE_ID long,
PLANE_NAME varchar
)
也可使用其余图和列的属性来定制映射。这使您能够指定诸如列长度、非空约束等详细内容。Hibernate支持大量针对这些注释的属性。下例中就包含了几种属性:
...
@Column(name="PLANE_ID", length=80, nullable=true)
public String getName() {
return name;
}
...
映射关系
Java 持久性映射过程当中最重要和最复杂的一环就是肯定如何映射表间的关系。像其余产品同样, Hibernate 在该领域中提供了高度的灵活性,但倒是以复杂度的增长为代价。咱们将经过研究几个常见案例来了解如何使用注释来处理这一问题。
其中一种最经常使用的关系就是多对一的关系。假定在以上示例中每一个 ModelPlane 经过多对一的关系(也就是说,每一个飞机模型只与一种飞机类型创建联系,尽管指定的飞机类型能够与七种飞机模型创建联系)来与 PlaneType 创建联系。可以下进行映射:
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
public PlaneType getPlaneType() {
return planeType;
}
CascadeType 值代表 Hibernate 应如何处理级联操做。
另外一种经常使用的关系与上述关系相反:一对多再对一关系,也称为集合。在老式的 Hibernate 版本中进行映射或使用注释时,集合使人头疼,这里咱们将简要加以探讨,以使您了解如何处理集合,例如,在以上示例中每一个 PlaneType 对象均可能会包含一个 ModelPlanes 集合。可映射以下:
@OneToMany(mappedBy="planeType",
cascade=CascadeType.ALL,
fetch=FetchType.EAGER)
@OrderBy("name")
public List<ModelPlane> getModelPlanes() {
return modelPlanes;
}
命名查询
Hibernate 最优秀的功能之一就在于它可以在您的映射文件中声明命名查询。随后便可经过代码中的名称调用此类查询,这使您能够专一于查询,而避免了 SQL 或者 HQL 代码分散于整个应用程序中的状况。
也可使用注释来实现命名查询,可使用 @NamedQueries 和 @NamedQuery 注释,以下所示:
@NamedQueries(
{
@NamedQuery(
name="planeType.findById",
query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
),
@NamedQuery(
name="planeType.findAll",
query="select p from PlaneType p"
),
@NamedQuery(
name="planeType.delete",
query="delete from PlaneType where id=:id"
)
}
)
一旦完成了定义,您就能够像调用其余任何其余命名查询同样来调用它们。
结束语
Hibernate 3 注释提供了强大而精致的 API,简化了 Java 数据库中的持久性代码,本文中只进行了简单的讨论。您能够选择听从标准并使用 Java 持久性 API,也能够利用特定于 Hibernate的扩展,这些功能以损失可移植性为代价提供了更为强大的功能和更高的灵活性。不管如何,经过消除对 XML 映射文件的需求,Hibernate 注释将简化应用程序的维护,同时也可使您对EJB 3 有初步认识。来试试吧!
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dingqinghu/archive/2011/03/25/6275798.aspx
注解映射必须知足两大条件:Hibernate3.2以上版本和JSEE 5。
@Entity 类注释,全部要持久化的类都要有
@Entity
public class Org implements java.io.Serializable {
}
@Id 主键
@Id
@GeneratedValue
private String orgId;
private String orgName;
@Column(name="...") 该属性对应表中的字段是什么,没有name表示同样
@Table 对象与表映射
@UniqueConstraint 惟一约束
@Version 方法和字段级,乐观锁用法,返回数字和timestamp,数字为首选
@Transient 暂态属性,表示不须要处理
@Basic 最基本的注释。有两个属性:fetch是否延迟加载,optional是否容许null
@Enumerated 枚举类型
@Temporal 日期转换。默认转换Timestamp
@Lob 一般与@Basic同时使用,提升访问速度。
@Embeddable 类级,表可嵌入的
@Embedded 方法字段级,表被嵌入的对象和@Embeddable一块儿使用
@AttributeOverrides 属性重写
@AttributeOverride 属性重写的内容和@AttributeOverrides一块儿嵌套使用
@SecondaryTables 多个表格映射
@SecondaryTable 定义辅助表格映射和@SecondaryTables一块儿嵌套使用
@GeneratedValue 标识符生成策略,默认Auto
表与表关系映射
@OneToOne:一对一映射。它包含五个属性:
targetEntity:关联的目标类
Cascade:持久化时的级联操做,默认没有
fetch:获取对象的方式,默认EAGER
Optional:目标对象是否容许为null,默认容许
mappedBy:定义双向关联中的从属类。
单向:
@JoinColumn:定义外键(主表会多一字段,作外键)
@OneToMany:一对多映射;@ManyToOne:多对一映射
单向一对多:
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="book_oid")/**book:表;oid:book表的主键;无name会按此规则自动生成*/
单向多对一:
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="author_oid")
关联表格一对多:
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(joinColumn={@JoinColumn(name="BOOK_OBJECT_OID")},inverseJoinColumns={@JoinColumn(name="AUTHER_OBJECT_OID")})
双向一对多或多对一:
不须要多一张表,只是使用mappedBy:使用在One一方,值为One方类名表示Many的从属类。
@Entity
Java代码
@Entity
public class Org implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String orgId;
private String orgName;
@OneToMany(mappedBy = "org")
private List<Department> departments;
// Constructors
...
// Property accessors
...
}
@Entity public class Org implements java.io.Serializable { // Fields @Id @GeneratedValue private String orgId; private String orgName; @OneToMany(mappedBy = "org") private List<Department> departments; // Constructors ... // Property accessors ... }
@Entity
public class Department implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String id;
private String name;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="org_orgId")
private Org org;
@OneToMany(mappedBy = "department")
private List<Employee> employees;
// Constructors
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public Org getOrg() {
return org;
}
public void setOrg(Org org) {
this.org = org;
}
/** default constructor */
.
.
.
}
Java代码
@Entity
public class Employee implements java.io.Serializable {
// Fields
@Id
@GeneratedValue
private String employeeId;
private String employeeName;
private String passWord;
private Integer age;
private Integer sex;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="department_id")
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
/** default constructor */
...
// Property accessors
...
}
@Entity public class Employee implements java.io.Serializable { // Fields @Id @GeneratedValue private String employeeId; private String employeeName; private String passWord; private Integer age; private Integer sex; @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="department_id") private Department department; public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } /** default constructor */ ... // Property accessors ... }
双向多对多:@ManyToMany.单向多对多这里不在赘述(没有太多实际意义)
这个比较简单,看下代码就明白了:
@Entity
public class Book implements java.io.Serializable {
@Id
private int id;
private String name;
private float money;
@ManyToMany(cascade = CascadeType.ALL)
private List<Author> authors;
public List<Author> getAuthors() {
return authors;
}
public void setAuthors(List<Author> authors) {
this.authors = authors;
}
...
}
@Entity
public class Author implements java.io.Serializable {
@Id
private int id;
private String name;
private int age;
@ManyToMany(mappedBy="authors")
private List<Book> books;
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
...
}
基于注解的hibernate主键设置:@Id.
那么它的生成规则是什么呢?是由@GeneratedValue来规定的。
咱们先来看看它是如何定义的:
Java代码
@Target({METHOD,FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue{
GenerationType strategy() default AUTO;
String generator() default "";
}
@Target({METHOD,FIELD}) @Retention(RUNTIME) public @interface GeneratedValue{ GenerationType strategy() default AUTO; String generator() default ""; }
Java代码
public enum GenerationType{
TABLE,
SEQUENCE,
IDENTITY,
AUTO
}
public enum GenerationType{ TABLE, SEQUENCE, IDENTITY, AUTO }
如今咱们看到了,它提供了4种生成策略:
TABLE:使用一个特定的数据库表格来保存标识符序列。
SEQUENCE:生成序列化标识符。
IDENTITY:标识符有数据库自动生成(主要是自动增加型)
AUTO:标识符生成工做由hibernate自动处理。实际项目开发不建议使用。
注意:当主键为int,而数据库中又不是自动增加型时,使用@GeneratedValue是没法正常工做的。
咱们也可使用下面的方式来本身指定咱们的主键值:
Java代码
@GeneratedValue(generator = "c-assigned")
@GenericGenerator(name = "c-assigned", strategy = "assigned")
private String employeeId;
@GeneratedValue(generator = "c-assigned") @GenericGenerator(name = "c-assigned", strategy = "assigned") private String employeeId;
或者直接不要定义@GeneratedValue,只定义@Id效果也是同样的。