Spring中使用JPA

1.配置persistence.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.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <persistence-unit name="jpaPU" transaction-type="RESOURCE_LOCAL">
     <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <properties>
   
<!--
      <property name="hibernate.dialect" value=" org.hibernate.dialect.Oracle9iDialect"/>
         <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
         <property name="hibernate.connection.username" value="scott"/>
         <property name="hibernate.connection.password" value="123456"/>
         <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
           <property name = "hibernate.show_sql" value = "true"/>
           <property name = "hibernate.format_sql" value = "true"/>
       -->
    
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
         <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
         <property name="hibernate.connection.username" value="root"/>
         <property name="hibernate.connection.password" value="123456"/>
         <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/hib?useUnicode=true&amp;characterEncoding=UTF-8"/>
         <property name="hibernate.max_fetch_depth" value="3"/>
         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
           <property name = "hibernate.show_sql" value = "true"/>
           <property name = "hibernate.format_sql" value = "true"/>
      </properties>
  </persistence-unit>
</persistence>
2.beans.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: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/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<!--使用注解时需要用到它,如@Resource,@PersistenceContext 等注解-->
     <context:annotation-config/>

<!-- 配置实体管理器工厂,引入持久化单元-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="jpaPU"/>
    </bean>

<--使用Spring提供的适配器:JPA事务管理器-->
    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
   </bean>

<!--使用Spring声明式事务管理-->
   
<tx:annotation-driven transaction-manager="txManager"/>
    <bean id="ps" class="com.service.impl.PersonServiceBean"/>
</beans>
3.编写实体Bean和业务Bean

 

package com.domin;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class Person implements java.io.Serializable{
   
    @Id
    @GeneratedValue
    private Integer id;
   
    @Column(length=10,nullable=false)
    private String name;

    public Person(String name) {
        // TODO Auto-generated constructor stub
        this.name=name;
    }
    public Person() {
        // TODO Auto-generated constructor stub
    }
    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

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

    public void setName(String name) {
        this.name = name;
    }
}
业务方法接口

package com.service;

import java.util.List;

import com.domin.Person;

public interface IPersonService {

    public void save(Person person);

    public void update(Person person);

    public void delete(Integer id);

    public Person getPerson(Integer id);

    public List<Person> getPersons();

}

业务方法实现:

package com.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.domin.Person;
import com.service.IPersonService;


@Transactional
public class PersonServiceBean implements IPersonService {
    @PersistenceContext EntityManager em;//注入实体管理器
   
    public void save(Person person){
        em.persist(person);
    }
   
    public void update(Person person){
        em.merge(person);
    }
   
    public void delete(Integer personid){
        em.remove(em.getReference(Person.class, personid));
    }
   @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
    public Person getPerson(Integer personid){
        return em.find(Person.class, personid);
    }
    @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
    @SuppressWarnings("unchecked")
    public List<Person> getPersons(){
        return em.createQuery("select o from Person o").getResultList();
    }
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       IPersonService personService =(IPersonService) context.getBean("personService");
        personService.save(new Person("小叶2"));
    }

}

其实,使用@PersistenceContext EntityManager em;是为了和@Transactional配合使用。因为声明式事务管理应用AOP技术,要在业务方法执行前后对它进行拦截以进行事务处理,包括事务的打开,关闭,提交,回滚等操作。所以就要求业务方法中操作数据库的对象不是自己新建Connection连接对象,而是也能使用当前线程中的连接对象(如果已经有的话)。其实,Spring自己提供的JdbcTemplate,JpaTemplate,HibernateTemplate类获取连接对象时都要先从当前线程中查找,所以可以配合声明式事务处理使用。

Spring实现AOP的方式不外乎使用JDK自带的动态代理技术和cglib代理。

使用动态代理时,必须使用被代理对象的接口来调用方法。

使用cglib,则可以直接使用代理对象来调用方法。

也就是说,由于上面的业务Bean实现了某一个接口,那么Spring会使用动态代理的方式,则只能使用它的接口。

IPersonService personService =(IPersonService) context.getBean("personService");

这句若改为

PersonServiceBean ps=(PersonServiceBean)apc.getBean("ps");

就会报错。

java.lang.ClassCastException: $Proxy12 cannot be cast to com.service.impl.PersonServiceBean
但是,如果业务Bean不实现某个接口,则Spring会使用cglib创建它的子类,使用

PersonServiceBean ps=(PersonServiceBean)apc.getBean("ps");是正确的。

 


 

 

posted @ 2012-01-07 11:36  tazi  阅读(1698)  评论(0编辑  收藏  举报