`
fehly
  • 浏览: 245142 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate Annotations

阅读更多

 

在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
  传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
    在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件--- 一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。

 

目前,JPAJava Persistence API)的使用范围越来越广,作为Java EE 5.0平台标准的ORM规范,得到了诸如:HibernateTopLinkOpenJpaORM框架的支持,同时还是EJB 3.0的重要组成部分。JPA的宗旨是为POJO提供持久化标准规范。它能够脱离容器独立运行,方便开发和测试。本文将通过一个小实例来说明如何在Hibernate中使用JPA,来达到简化编程的目的。

Hibernate Annotations核心注解

@Entity 声明当前是一个持久化类

@Table 设置当前持久化类所映射的数据库表,如果当前类中没有使用@Table注解,Hibernate会自动使用默认的持久化类的类名(不带包名)作为所映射的表名

@Id  设置当前持久化类的标示符属性

@GeneratedValue 设置当前标示符的生产策略。@GeneratedValue的name属性设置生成策略的名称是TABLE、INENTITY、SEQUENCE或者AUTO之一。

@Column  将持久化类的数学与数据库表中的字段进行映射,name属性值为映射的字段名,length属性值为字段的长度,unique属性表示该列上设置唯一的约束,nullable属性设置该列的值是否可以为空,precision实现设置该字段的精度,scale属性设置该字段的小数位数

@Transient 标注的属性进行持久化映射

@Temporal java中没有定义时间精度的api,因此处理时间类型数据时,需要设置存储在数据库中所预期的精度,使用@Temporal注释可以调整时间的精度为:DATE、TIME和TIMESTAMP三种

@ManyToOne  设置该当前持久化类类与其他持久化类之间的多对一关联,其中CascadeType值表示Hibernate将进行级联操作

@OneToMany  设置该当前持久化类与其他持久化类之间的一对多关联

@OneToOne   设置该当前持久化类与其他持久化类之间的一对一关联

@ManyToMany 设置该当前持久化类与其他持久化类之间的多对多关联

@NameQueries 在持久化类中设置命名查询,参考@NameQuery的使用

@NameQuery   在持久化类中设置命名查询,@NamedQuery 和@NamedQueries注释加在在类和包上。如下面的例子:
@NamedQueries({@NamedQuery(name="queryById",query="select p from Product p where id=:id")})

@Version 设置乐观锁定

@Cache 设置二级缓存

@Filters  设置使用过滤器

@FilterDef  声明过滤器

 

 

 

 

 

 

demo

比如有2个表 一个CATEGORY

-- Create table
create table CATEGORY
(
  ID          NUMBER(8) not null,
  NAME        NVARCHAR2(200),
  DESCRIPTION VARCHAR2(1000)
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table CATEGORY
  add constraint CATEGORY_PK primary key (ID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );

 

   一个PRODUCT

-- Create table
create table PRODUCT
(
  ID          NUMBER(8) not null,
  NAME        VARCHAR2(200),
  PRICE       NUMBER(6,2),
  DESCRIPTION VARCHAR2(1000),
  CREATE_TIME DATE,
  CATEGORY_ID NUMBER(8)
)
tablespace USERS
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table PRODUCT
  add constraint PRODUCT_PK primary key (ID)
  using index 
  tablespace USERS
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );
alter table PRODUCT
  add constraint PRODUCT_FK foreign key (CATEGORY_ID)
  references CATEGORY (ID);

 

 可用MyEclipse 生成对应的持久化类,区别 平时的Hibernate 创建的都是*.hbm.xml而现在是

add  Hibernate mapping annotations to POJO

Category.java

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;

@Entity
@Table(name = "CATEGORY", schema = "SCOTT")
public class Category implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private Long id;
	private String name;
	private String description;
	private Set<Product> products = new HashSet<Product>(0);

	public Category() {
	}

	// Property accessors
	@GenericGenerator(name = "generator", strategy = "increment")
	@Id
	@GeneratedValue(generator = "generator")
	@Column(name = "ID", unique = true, nullable = false, precision = 8, scale = 0)
	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column(name = "NAME", length = 400)
	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "DESCRIPTION", length = 1000)
	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "category")
	public Set<Product> getProducts() {
		return this.products;
	}

	public void setProducts(Set<Product> products) {
		this.products = products;
	}

}

 

product.java

import java.util.Date;
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 javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "PRODUCT", schema = "SCOTT")
public class Product implements java.io.Serializable {
	private static final long serialVersionUID = 1L;
	private Long id;
	private Category category;
	private String name;
	private Double price;
	private String description;
	private Date createTime;

	public Product() {
	}

	@GenericGenerator(name = "generator", strategy = "increment")
	@Id
	@GeneratedValue(generator = "generator")
	@Column(name = "ID", unique = true, nullable = false, precision = 8, scale = 0)
	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "CATEGORY_ID")
	public Category getCategory() {
		return this.category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	@Column(name = "NAME", length = 200)
	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "PRICE", precision = 6)
	public Double getPrice() {
		return this.price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	@Column(name = "DESCRIPTION", length = 1000)
	public String getDescription() {
		return this.description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Temporal(TemporalType.DATE)
	@Column(name = "CREATE_TIME", length = 7)
	public Date getCreateTime() {
		return this.createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

}

 

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateAnnotationsTest {
	public void testAnnotations() {
		SessionFactory sessionFactory = new AnnotationConfiguration().configure()
				.buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();

		Category category = new Category();
		category.setName("demo");
		category.setDescription("这是一个例子");

		Product product = new Product();
		product.setName("妮维雅");
		product.setPrice(new Double(46.0));
		product.setDescription("护肤品");

		product.setCategory(category);
		category.getProducts().add(product);

		Transaction tx = session.beginTransaction();
		session.save(category);
		session.save(product);
		tx.commit();
		sessionFactory.close();
	}

	public static void main(String[] args) {
		HibernateAnnotationsTest test = new HibernateAnnotationsTest();
		test.testAnnotations();
	}
}

 

注意: 回报这种错误 java.lang.NoSuchMethodError: org.hibernate.event.PreInsertEvent.getSource()Lorg/hibernate/engine/SessionImplementor;

解决方法 替换hibernate-annotation.jar 和hibernate-validator.jar  换成新点的 或者你把hibernate-validator.jar  移除也行

hibernate-annotation.jar 换成3.4.0的就好了,3.5.1-Final还会报一个缺少MetadataProvider的类具体没太注意解决的方法,validator我换的是4.0.2的其他的没测试应该也没什么问题...

 

@GeneratedValue注解生成策略

TABLE 借助数据库表,生成存标识符属性值,表中保存当前的标识符属性的最大值

IDENTITY  使用数据库表中的自动增长字段生成标识符属性值

SEQUENCE  使用数据库的序列生成标识符属性值

AUTO  可以是上面三种任意一种类型,取决于底层数据库的类型

 

Hibernate EntityManager

java Persistence API(JPA)
java persistence api 是ejb3.0规范之一,定义了对数据库数据进行持久化操作的接口,Hibernate使用 Hibernate annotations和Hibernate EntityManager实现了JPA

会使用到 Hibernate-EntityManager.jar和jboss-archive-browing.jar

 

和Annotation不同的是没有用到hibernate.cfg.xml 而是使用persistence.xml文件的实现填写信息而xml文件必须在META-INF文件夹下其余的基本相同

persistence.xml

<?xml version='1.0' encoding='UTF-8'?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.23.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/ns/persistence http://java.sun.com/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<persistence-unit name="entityManagerTest">
		<provider>org.hibernate.ejb.HibernatePersistence
		</provider>
		<properties>
			<property name="hibernate.archive.autodetection" value="class, hbm" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
			<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" />
			<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:dbrbh" />
			<property name="hibernate.connection.username" value="scott" />
			<property name="hibernate.connection.password" value="tiger" />			
		</properties>
	</persistence-unit>
</persistence>

 

 

 //EntityManagerFactory==SessionFactory
		EntityManagerFactory emf = Persistence.createEntityManagerFactory("entityManagerTest");
		//EntityManager == session
		EntityManager entityManager = emf.createEntityManager();
		//EntityTransaction == Transaction
		EntityTransaction tx = entityManager.getTransaction();
 //entityManager persist()=Session.save()
		entityManager.persist(category);

 

分享到:
评论
2 楼 fehly 2012-10-29  
47816778 写道
你这样不会出现number 的精度问题吗

这个就是个例子而已,精度问题用BigDecimal吧
1 楼 47816778 2012-10-29  
你这样不会出现number 的精度问题吗

相关推荐

Global site tag (gtag.js) - Google Analytics