Spring实战——使用对象-关系映射持久化数据

一、在Spring中集成hibernate

1、hibernate简介:

      hibernate是目前很流行的开源持久化框架。不仅提供了基本的对象关系映射,还提供了ORM工具所应具有的所有复杂功能,比如缓存、延迟加载、预先抓取以及分布式缓存。

2、声明hibernate的Session工厂

在Spring中,需要通过Spring的某一个Hibernate Session工厂bean来获取Hibernate SessionFactory。从3.1版本开始,Spring提供了三个Session工厂的Bean:

org.springframework.orm.hibernate3.LocalSessionFactoryBean

org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean

org.springframework.orm.hibernate4.LocalSessionFactoryBean

对于以上三个Session工厂,选择方式如下:

①如果使用hibernate版本在3.2或更高版本(知道hibernate4.0,但不包含4.0),并且使用XML定义映射的话,就使用org.springframework.orm.hibernate3包中的LocalSessionFactoryBean。

②如果使用hibernate版本在3.2或更高版本(知道hibernate4.0,但不包含4.0),并且使用注解定义映射的话,就使用org.springframework.orm.hibernate3.annotation包中的AnnotationSessionFactoryBean。

③如果使用hibernate4,就使用org.springframework.orm.hibernate4.LocalSessionFactoryBean,这个Session工厂既可以匹配XML映射,也可以匹配注解映射。

3、在Spring中集成Hibernate的配置

先在web.xml中添加配置:

    <filter>
        <filter-name>openSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
        <init-param>
            <param-name>singleSession</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>openSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
	

然后在Spring-dao.xml中配置SessionFactory(这里实体类使用注解映射):

	<!-- 数据源连接池配置三种方式(推荐使用):DBCP、C3P0、BoneCP -->
	<!-- DBCP配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean>
	
	<!-- 配置sessionFactory -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="packagesToScan" value="com.mfc.entity"></property>
		<property name="hibernateProperties">
			<props>
                <prop key="hibernate.show_sql">true</prop>     <!--在控制台显示执行的数据库操作语句-->
                <prop key="hibernate.format_sql">true</prop>     <!--在控制台显示执行的数据哭操作语句(格式)-->
                <prop key="hibernate.connection.autocommit">true</prop>
			</props>
		</property>
	</bean>

使用Java配置SessionFactory:

	@Bean
	public LocalSessionFactoryBean sessionFactory(DataSource dataSource){
		LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
		sessionFactory.setDataSource(dataSource);
		sessionFactory.setPackagesToScan(new String[]{"com.mfc.entity"});
		Properties properties = new Properties();
		properties.setProperty("hibernate.show_sql", "true");
		properties.setProperty("hibernate.format_sql", "true");
		properties.setProperty("hibernate.connection.autocommit", "true");
		return sessionFactory;
	}

4、在dao层中使用SessionFactory:

以前经常使用HibernateTemplate,HibernateTemplate能够保证每个事务使用同一个Session,但是这种方式的弊端在于Repository实现会直接与Spring耦合。

先在的最佳实现是使用上下文Session,通过这种方式,会直接将Hibernate的SessionFactory装配到Repository中,并使用它来获取Session,程序如下:

package com.mfc.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.mfc.entity.Tuser;

@Repository(value = "tuserDao")
public class TuserDaoImpl implements TuserDao {
	
	@Autowired
	private SessionFactory sessionFactory;
	
	private Session getSession(){
		return sessionFactory.getCurrentSession();
	}
	
	@Override
	public void add(Tuser tuser) {
		getSession().save(tuser);
	}

	@Override
	public void delete(Tuser tuser) {
		getSession().delete(tuser);
	}

	@Override
	public void update(Tuser tuser) {
		getSession().update(tuser);
	}

	@Override
	public List<Tuser> find(Tuser tuser) {
		return getSession().createCriteria(Tuser.class).list();
	}

	@Override
	public Tuser findByPrimary(String userId) {
		return (Tuser) getSession().get(Tuser.class, userId);
	}
}

二、Spring与Java持久化API

1、实体管理器工厂介绍

   基于JPA的应用程序需要使用EntityManagerFactory的实现类来获取EntityManager实例。JPA定义了两种类型的实体管理器。

①应用程序管理类型:这种适用于不运行在Java EE容器中的独立应用程序,不做介绍

②容器管理类型:由JavaEE创建和管理,下面主要看这个。org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean

2、使用容器管理类型的JPA

①在Spring容器中注入LocalContainerEntityManagerFactoryBean

	<!-- DBCP配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean>
	
	<bean id="em" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
		<property name="packagesToScan" value="com.mfc.entity"></property>
	</bean>
	<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="database" value="ORACLE"></property>
		<property name="showSql" value="true"></property>
		<property name="generateDdl" value="false"></property>
	</bean>
	
	

②使用Java配置代替上面的配置:

	@Bean
	public BasicDataSource dataSource(){
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("");
		dataSource.setUrl("");
		dataSource.setUsername("");
		dataSource.setPassword("");
		return dataSource;
	}
	
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){
		LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
		em.setDataSource(dataSource);
		em.setJpaVendorAdapter(jpaVendorAdapter);
		em.setPackagesToScan(new String[]{"com.mfc.entity"});
		return em;
	}
	
	@Bean
	public JpaVendorAdapter jpaVendorAdapter(){
		HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
		jpaVendorAdapter.setDatabase("ORACLE");
		jpaVendorAdapter.setShowSql(true);
		jpaVendorAdapter.setGenerateDdl(false);
		return jpaVendorAdapter;
	}

③上面代码中的jpaVendorAdapter属性用于指明哪一个厂商的JPA实现,Spring提供了多个JPA厂商适配器:

EclipseLinkJpaVendorAdapter、HibernateJpaVendorAdapter、OpenJpaVendorAdapter、TopLinkJpaVendorAdapter(已废弃)

④上面配置中,注入HibernateJpaVendorAdapter时最终啊哟的是database属性,对应不同数据库,database属性的值不同。

Hibernate的JPA适配器支持多种数据库,可以通过database的属性配置使用哪个数据库
数据库平台属性database的值
IBM DB2DB2
Apache DerbyDERBY
H2H2
HypersonicHSQL
InformixINFORMIX
MySqlMYSQL
oracleORACLE
PostgresQLPOSTGRESQL
Microsoft SQL ServerSQL SERVER
SybaseSYBASE

3、从JNDI获取实体管理器工厂

xml配置:

	<jee:jndi-lookup jndi-name="OracleConnection" id="emf"></jee:jndi-lookup>
	
	<bean id="em" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="emf"></property>
	</bean>

Java配置:

    @Bean
	public JndiObjectFactoryBean dataSource(){
		JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
		factoryBean.setJndiName("OracleConnection");
		factoryBean.setProxyInterface(DataSource.class);
		return factoryBean;
	}
    
    @Bean
    public JndiObjectFactoryBean entityManagerFactory(){
    	JndiObjectFactoryBean em = new JndiObjectFactoryBean();
    	em.setJndiName("OracleConnection");
    	return em;
    }

4、使用JPA编写Dao:

package com.mfc.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

import org.springframework.stereotype.Repository;

import com.mfc.entity.Tuser;

@Repository(value = "jpaTuserDao")
@Transactional
public class JPATuserDaoImpl implements TuserDao {
	
	@PersistenceContext
	private EntityManager em;

	@Override
	public void add(Tuser tuser) {
		em.persist(tuser);

	}

	@Override
	public void delete(Tuser tuser) {
		em.remove(em.merge(tuser));
	}

	@Override
	public void update(Tuser tuser) {
		em.persist(em.merge(tuser));
	}

	@Override
	public List<Tuser> find(Tuser tuser) {
		String queryString = "select * from tuser";
	    Query query = em.createNativeQuery(queryString,Tuser.class);
	    List<?> result = query.getResultList();
	    List<Tuser> users = new ArrayList<Tuser>();
	    if (result !=null) {
           Iterator<?> iterator =result.iterator();
           while (iterator.hasNext()) {
              Tuser user = (Tuser)iterator.next();
              users.add(user);
           }
        }
	    return users;
	}

	@Override
	public Tuser findByPrimary(String userId) {
		return em.find(Tuser.class, userId);
	}

}

三、借助SpringData实现自动化的JPA Repository

参考:https://blog.csdn.net/itguangit/article/details/78748077

           https://blog.csdn.net/wu920604/article/details/52595999

以下值记录了Maven依赖和Spring注入配置,其他具体操作和介绍可以看上面参考的两篇博客。

1、这里注意Spring和Spring Data JPA的版本,我使用的Maven依赖:

  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <spring.version>4.3.10.RELEASE</spring.version>
  </properties>
  <dependencies>

	 <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
	<dependency>
	    <groupId>commons-dbcp</groupId>
	    <artifactId>commons-dbcp</artifactId>
	    <version>1.4</version>
	</dependency>
	
    <!-- https://mvnrepository.com/artifact/com.oracle/ojdbc14 -->
	<dependency>
	    <groupId>com.oracle</groupId>
	    <artifactId>ojdbc14</artifactId>
	    <version>10.2.0.1.0</version>
	</dependency>  
	
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
          <!-- springframework 4 dependencies begin -->
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
       <!--  https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-aspects</artifactId>
		    <version>${spring.version}</version>
		</dependency>
		
		<!-- spring data jpa 数据库持久层 -->
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-jpa</artifactId>
             <version>1.10.4.RELEASE</version>
         </dependency>
        
        <!-- springframework 4 dependencies end -->
        
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
		<dependency>
		    <groupId>org.hibernate</groupId>
		    <artifactId>hibernate-validator</artifactId>
		    <version>4.3.1.Final</version>
		</dependency>
		
		<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.3.11.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.11.Final</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.0-api -->
		<dependency>
		    <groupId>org.hibernate.javax.persistence</groupId>
		    <artifactId>hibernate-jpa-2.0-api</artifactId>
		    <version>1.0.1.Final</version>
		</dependency>
        
  </dependencies>
  <build>
    <finalName>SpringInAction7</finalName>
  </build>
</project>

2、Spring-dao.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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xsi:schemaLocation="http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
	<!-- DBCP配置数据源 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
		<property name="username" value="scott"></property>
		<property name="password" value="scott"></property>
	</bean>
	
	<!-- 使用JPA实现持久化配置 -->
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
		<property name="packagesToScan" value="com.mfc.entity"></property>
	</bean>
	<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="database" value="ORACLE"></property>
		<property name="showSql" value="true"></property>
		<property name="generateDdl" value="false"></property>
	</bean> 
	
	<!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
	
	<!-- 测试:使用Spring Data构建自动化的JPA Repository ,com.mfc.SpringDataJPA是Repository接口的包名-->
	<jpa:repositories base-package="com.mfc.SpringDataJPA"></jpa:repositories>
</beans>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值