参考:Spring Recipes
1. 涉及内容:
* 在Spring中配置JPA EntityManagerFactory
* 配置注解声明式事务
* 用JPA的上下文注入持久化对象
2. 实现步骤:
0).依赖包:hibernate-annotations-3.4.0.GA
hibernate-entitymanager-3.4.0.GA
spring-framework-2.5.6
1).编写Course实体类并添加JPA注解,代码如下:
package com.local.domain; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="t_course") public class Course { @Id @GeneratedValue private Long id; private String title; private Date beginDate; private Date endDate; private int fee; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getBeginDate() { return beginDate; } public void setBeginDate(Date beginDate) { this.beginDate = beginDate; } public Date getEndDate() { return endDate; } public void setEndDate(Date endDate) { this.endDate = endDate; } public int getFee() { return fee; } public void setFee(int fee) { this.fee = fee; } }
2)编写CourseDao接口和JpaCourseDao实现,代码如下:
package com.local.dao; import com.local.domain.Course; public interface CourseDao { public void save(Course course); public void delete(Long id); public Course get(Long id); }
package com.local.dao.impl; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.hibernate.HibernateException; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.local.dao.CourseDao; import com.local.domain.Course; @Repository("courseDao") public class JpaCourseDao implements CourseDao{ @PersistenceContext private EntityManager manager; public JpaCourseDao(){ } @Override @Transactional public void delete(Long id) { Course course=manager.find(Course.class, id); manager.remove(course); } @Override public Course get(Long id) { return manager.find(Course.class, id); } @Override @Transactional public void save(Course course) { manager.merge(course); } }
3)在classpath根部的META-INF目录下创建persistence.xml文件,代码如下:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="course"> <persistence-unit> </persistence>
4)配置spring配置文件
(1)打开注解支持
(2)开启组件扫描
(3)配置数据源:
编辑jdbc.properties文件,配置连接属性
(4)配置实体管理工厂
(5)配置事务管理器,并打开注解事务
(6)注册PersistenceExceptionTranslationPostProcessor,
实现JPA原生API抛出的异常到spring的DataAccessException层次结构的转换
applicationContext.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd "> <context:annotation-config/> <context:component-scan base-package="com.local"/> <tx:annotation-driven/> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> <property name="initialSize" value="${initialSize}" /> <property name="maxActive" value="${maxActive}" /> <property name="maxIdle" value="${maxIdle}" /> <property name="minIdle" value="${minIdle}" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="course"/> <property name="dataSource" ref="dataSource"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"></property> <property name="showSql" value="true"/> <property name="generateDdl" value="true"/> </bean> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"></property> </bean> <!-- 将加有Repository注解的使用JPA或者Hibernate原生API的方法所抛出的异常转化为Spring的DataAccessException中的异常 --> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"></bean> </beans>
jdbc.properties属性文件内容如下:
driverClassName=org.gjt.mm.mysql.Driver url=jdbc\:mysql\://localhost\:3306/db_jpa?useUnicode\=true&characterEncoding\=UTF-8 username=root password=root initialSize=1 maxActive=500 maxIdle=2 minIdle=1
5)编写Junit测试:
package com.local.dao.impl; import java.util.Date; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.local.dao.CourseDao; import com.local.domain.Course; public class CourseDaoImplTest { private static ApplicationContext ctx; private static CourseDao courseDao; @BeforeClass public static void init(){ ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); courseDao=(CourseDao)ctx.getBean("courseDao"); } @Test public void testSave(){ Course course=new Course(); course.setTitle("course2"); course.setBeginDate(new Date()); course.setEndDate(new Date()); course.setFee(100); courseDao.save(course); } @Test public void testGet(){ Course course=courseDao.get(new Long(3)); System.out.println("title: "+course.getTitle()); System.out.println("beginDate: "+course.getBeginDate()); System.out.println("endDate: "+course.getEndDate()); System.out.println("fee: "+course.getFee()); } }
3. 其他说明:
*1. @PersistenceContext注解:
给加该注解的属性注入实体管理器
*2. @PersistenceUnit注解:
注入实体管理器工厂
*3. 在Spring配置文件中加入了JPA的连接,在persistence.xml中不需配置了,否则会出现
java.lang.UnsupportedOperationException: Not supported by BasicDataSource之类的异常