1 Hibernate注解
1.1 简介
在Hibernate 新版本中,出现了一种基于Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。 即利用hibernate 注解后,可不用定义持久化类对应的*.hbm.xml 文件,直接以注解方式写入在持久化类中来实现。 Hibernate annotation 使用了ejb JPA 的注解,所以,下面安装配置hibernate annotation 环境时,需要导入ejb的包
1.2 准备工作
要使用 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)
向 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>
建立会话工厂:
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 会话工厂,如下所示:
<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>
1.3 使用
hibernate Annotation 标签的使用: 带注释的持久性类也是普通 POJO ,它们只是具备了持久性注释的普通 POJO 事实上,您既可以保持字段的持久性(注释写在成员变量之上),也可以保持属性(注释写在getter方法之上)的持久性。
常用的hibernate annotation 标签如下:
@Entity : 注释声明该类为持久类。将一个Javabean 类声明为一个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的, 要用下面的Transient 来注解.@Table(name="promotion_info") : 持久性映射的表(表名="promotion_info).@Table 是类一级的注解,定义在@Entity 下,为实体bean 映射表,目录和schema的名字,默认为实体bean的类名,不带包名.@Id : 注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。@GeneratedValue : 定义自动增长的主键的生成策略.@Transient : 将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错.@Temporal(TemporalType.TIMESTAMP) : 声明时间格式@Enumerated : 声明枚举@Version : 声明添加对乐观锁定的支持@OneToOne : 可以建立实体bean之间的一对一的关联@OneToMany : 可以建立实体bean之间的一对多的关联@ManyToOne : 可以建立实体bean之间的多对一的关联@ManyToMany : 可以建立实体bean之间的多对多的关联@Formula : 一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)@OrderBy : Many端某个字段排序(List)
1.3.1 主键递增示例
Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。 其生成规则由@GeneratedValue 设定的.这里的@id 和@GeneratedValue 都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue 的源代码可以明显看出.JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE :使用一个特定的数据库表格来保存主键。SEQUENCE :根据底层数据库的序列来生成主键,条件是数据库支持序列。IDENTITY :主键由数据库自动生成(主要是自动增长型)AUTO :主键由程序控制。 在指定主键时,如果不指定主键生成策略,默认为AUTO。
@Entity
@Table(name="T_MODEL_PLANE")
public class ModelPlane implements Serializable {
@Id
@Column(name="PLANE_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
对于oracle想使用各自的Sequence,设置如下:
@GeneratedValue(strategy = GenerationType.AUTO,generator="PROMOTION_SEQ")
@SequenceGenerator(name="PROMOTION_SEQ",sequenceName="PROMOTION_SEQ")
1.3.2 级联关系
package com.b510.examples;
import java.util.HashSet;
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.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Table(name = "category", catalog = "users")
public class Category implements java.io.Serializable {
private static final long serialVersionUID = 3240281547213597385L;
private Integer id;
private String name;
private String description;
private Set<Product> products = new HashSet<Product>(0);
public Category() {
}
public Category(String name, String description, Set<Product> products) {
this.name = name;
this.description = description;
this.products = products;
}
@Id
@GeneratedValue(generator = "generator")
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Product> getProducts() {
return this.products;
}
public void setProducts(Set<Product> products) {
this.products = products;
}
}
Product.java
package com.b510.examples;
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.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name = "product", catalog = "users")
public class Product implements java.io.Serializable {
private static final long serialVersionUID = -1546206493725028472L;
private Integer id;
private Category category;
private String name;
private String price;
private String descripton;
public Product() {
}
public Product(Category category, String name, String price,
String descripton) {
this.category = category;
this.name = name;
this.price = price;
this.descripton = descripton;
}
@GenericGenerator(name = "generator", strategy = "increment")
@Id
@GeneratedValue(generator = "generator")
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@JoinColumn(name = "category_id")
public Category getCategory() {
return this.category;
}
public void setCategory(Category category) {
this.category = category;
}
@Column(name = "name", length = 500)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "price", length = 10)
public String getPrice() {
return this.price;
}
public void setPrice(String price) {
this.price = price;
}
@Column(name = "descripton", length = 500)
public String getDescripton() {
return this.descripton;
}
public void setDescripton(String descripton) {
this.descripton = descripton;
}
}
|