Spring框架提供集成支持ORM包括Hibernate、Mybatis、JDO、JPA以及Oracle的Toplink。Spring在集成的方式上,几乎是相同的。但是,Spring的集成方式比较统一并不意味着所有的ORM解决方案都是一样的。我们应该根据具体的场景,来决定使用何种ORM解决方案。下面将通过Spring对比较流行的Hibernate和Mybatis这两种ORM方案的集成来进行阐述,最后会对其他ORM方案的集成做一定的概述,方便在以后使用ORM方案时,该如何从Spring获得支持。

一、Spring对Hibernate的集成

 鉴于Hibernate API的使用,在具体项目实践过程中,也存在类似于JDBC API使用中资源管理以及异常的处理之类的普遍问题。Spring在JDBCTemplate的成功理念下,对Hibernate的使用也以相同的方式进行了封装,使得我们不用在资源管理以及异常处理方面投入过多的精力。同时,Spring对所有的数据访问技术相关的事务管理,也通过AOP的形式剥离出来,进一步避免了过多的方面纠缠在一起的困境。

1.HibernateTemplate诞生 

  •  基于HibernateTemplate的Session资源管理

Hibernate的SessionFactory,就好象JDBC的DataSource,它是所有数据访问资源的发源地。只有获取了SessionFactory的支持,后继的数据访问才能继续,SessionFactory目的是处理事务。SessionFactory的获取有2种方式:

代码方式: 

Configuration config = new Configuration().configure("com/pojo/hibernate.cfg.xml");
SessionFactory factory = config.buildSessionFactory();
Session session = factory.openSession();

IoC注入xml: 

1).LocalSessionFactoryBean 

<!-- 方式一 -->
    <bean id="sessionFactory"
		    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>

		<!--添加映射文件
		<property name="mappingResources">
			<list>
				<value>com/hisu/bean/User.hbm.xml</value>
			</list>
		</property>
		-->
	</bean>
    <!-- 方式二 -->
    <bean id="dataSorce"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName"
			value="org.gjt.mm.mysql.Driver">
		</property>
		<property name="url" value="jdbc:mysql://localhost:3306/film"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
		<property name="maxActive" value="25" />
		<property name="maxWait" value="25" />
	</bean>
    <!-- 配置hibernate的sessionFactory -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSorce" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				<value>com/hisu/bean/User.hbm.xml</value>
			</list>
		</property>
	</bean>

 2).AnnotationSessionFactoryBean

 3).JNDI获取SessionFactory

  •  特定Hibernate的数据访问异常

SessionFactoryUtils类提供了converHibernateAccessException静态方法进行HibernateException到Spring异常的转译

public static DataAccessException convertHibernateAccessException(HibernateException ex)

2.使用HibernateDaoSupport封装Hibernate API

public class PersonDAOImpl extends HibernateDaoSupport implements PersonDAO {
    public List queryAll(int currentPage, int lineSize) throws Exception {
		List<Person> all = new ArrayList<Person>();
		String hql = "FROM Person AS p";
        Session session = this.getSession(true);
		Query q = session.createQuery(hql);
		q.setFirstResult((currentPage - 1) * lineSize);
		q.setMaxResults(lineSize);
		all = q.list();
        this.releaseSession(session);
		return all;
	}

    public void insert(Person person) throws Exception{
		this.getHibernateTemplate().save(person);
	}

}

 Spring IoC注入xml

<!-- spring对hibernate的简单封装 -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
	<property name="sessionFactory" ref="sessionFactory"/>
</bean>

<bean id="personDAOImpl" class="com.test.dao.impl.PersonDAOImpl">
	<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>

SessionFactory为了避免内存溢出,必须手动释放session; HibernateTemplate使用完会自动释放session

二、Spring对Mybatis的集成 

 1.SqlSessionTemplate的诞生

  • 基于SqlSessionTemplate的sqlSession资源管理

 Mybatis的sqlSessionFactory,它是所有数据访问资源的发源地。只有获取了SessionFactory的支持,后继的数据访问才能继续。SessionFactory的获取有2种方式:

 代码方式:

//加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml"); 
//构建sqlSession的工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
reader.close();

IoC注入xml: SqlSessionFactoryBean

<!-- spring集成mybatis集中管理session -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 引入数据源 -->
		<property name="dataSource" ref="dataSource"/>
		<!-- 加载mybatis核心配置文件-->
		<property name="configlocation" value="classpath:config/mybatis.cfg.xml"/>
		<!-- 批量别名定义,自动扫描包,自动定义别名,别名就是类名(首字母大写或小写都可以) -->
		<!-- <property name="typeAliasesPackage" value="com.huayuan.bean"></property> -->
		<!-- 扫描sql配置文件,mapper.xml -->
		<!-- <property name="mapperLocations" value="classpath:com/huayuan/mapper/*.xml"></property> -->
	</bean>
  •  特定Mybatis的数据访问异常

SqlSessionUtils类提供了异常转译和事务处理

 2.SqlSessionDaoSupport

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
	
	private SqlSessionFactory sqlSessionFactory;

	public SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}

	public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

	public User selectUserById(int id) {
		SqlSession session = this.getSqlSessionFactory().openSession();
		User user = session.selectOne("user.selectUserById", id);
		return user;
	}
    public int insertUser(User user) {
		// TODO Auto-generated method stub
		int result = 0;
		SqlSession session = this.getSqlSessionFactory().openSession();
		result = session.insert("user.insertUser", user);
		session.commit();
		return result;
	}
}

Spring IoC注入xml

<!-- 原始dao接口注入 -->
	<bean id="userDao" class="cn.itcast.ssm.dao.UserDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
	</bean>

三、Spring对其他ORM方案的集成概述 

回顾Spring对各种数据访问技术的集成,主要集中在以下三点:

1.数据访问资源管理,主要涉及两种管理对象 

  • 连接工厂(ConnectionFactory)。连接工厂代表的是创建数据访问会话资源的统一概念,通常可以通过特定的数据访问技术的支持来直接创建它们,也可以通过JNDI等服务获取已经创建并配置好的实例。对于JDBC来说,对应连接工厂概念的实体是DataSource,Hibernate是SessionFactory,Mybatis是SqlSessionFactory......
  • 连接(Connection)或者说会话资源。连接是客户端与数据媒介进行数据通信的纽带,每次进行数据访问的时候,都需要从指定的连接工厂获得某个连接以完成本次数据访问操作,操作完成后关闭当前连接资源。对于JDBC来说,连接对应的是java.sql.Connection,对于Hibernate来说,对应的是Session,对于Mybatis是SqlSession...... 

2.特定数据访问异常的转译,将这些特定的数据访问异常转译为Spring统一的数据访问异常体系,从而使客户端可以使用统一的方式透明的处理数据访问异常

3.将特定于数据访问技术的事务管理,统一纳入到Spring的事务管理抽象层,使得我们可以用统一的方式来管理事务。