写了MyBatis与Spring的集成,今天写写Hibernate与Spring的集成。以前是别人集成好了自己直接用,今天自己集成一下。与MyBatis学习笔记系列一样,本篇依然采用courseman数据库(数据库的创建请参见笔者博客:MyBatis入门示例),及ant来管理工程(对ant不熟悉的朋友请参见笔者的相关博客:ant的下载与安装,ant入门示例,)。本示例的任务是根据教师ID读取教师记录(教师类和表结构请参见笔者博客:MyBatis的association示例)。
一、版本说明
Spring:3.1.2。
Hibernate:3.6.7.Final。
本示例提供×××(点此进入×××页面),因此需要的jar包就不一一赘述。
二、Spring的配置
配置文件(beans.xml)的内容如下:
-
<?xml version="1.0" encoding="utf8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:tx="http://www.springframework.org/schema/tx"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xsi:schemaLocation="
-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
-
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
-
default-autowire="byName" default-lazy-init="false">
-
-
<!--本示例采用DBCP数据源,应预先把DBCP的jar包复制到工程的lib目录下。数据源配置如下-->
-
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
-
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
-
<property name="url"
-
value="jdbc:mysql://localhost/courseman"/>
-
<property name="username" value="courseman"/>
-
<property name="password" value="abc123"/>
-
</bean>
-
-
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
-
<!--dataSource属性指定要用到的数据源,因此在Hibernate的
-
核心配置文件中就无需再配置与数据库连接相关的属性-->
-
<property name="dataSource" ref="dataSource"/>
-
<!--指定Hibernate核心配置文件-->
-
<property name="configLocation" value="resources/hibernate.cfg.xml"/>
-
</bean>
-
-
</beans>
需要注意的是,以上sessionFactory的配置有其特殊之处。它的class是org.springframework.orm.hibernate3.LocalSessionFactoryBean,此类实现了Srping中的一个接口org.springframework.beans.factory.FactoryBean,这个接口声明了一个方法getObject()。这意味着,当我们要引用sessionFactory这个bean的时候,返回的不是类LocalSessionFactoryBean的实例,而是此实例的getObject()方法的返回值。而LocalSessionFactoryBean对此方法的实现(实际上是从AbstractSessionFactoryBean继承而来),是返回了一个SessionFactory对象。也就是说,LocalSessionFactoryBean的实例是用来生成SessionFactory对象的工厂。
这与MyBatis和Spring的集成是一样的(请参见笔者博文:MyBatis与Spring集成示例),看来天下乌鸦一般黑啊!不过这倒是减轻了我们的学习、记忆负担。所不同的是,MyBatis的SqlSessionFactoryBean(类似于LocalSessionFactoryBean)是MyBatis自己实现的,而LocalSessionFactoryBean是Spring实现的。原因是Spring 3未提供与MyBatis 3的集成,MyBatis只好自己亲自上阵了(相关信息英文请参见:http://www.mybatis.org/spring/index.html,中文请参见:http://www.mybatis.org/spring/zh/index.html)。
三、Hibernate的配置
Hibernate的核心配置文件hibernate.cfg.xml的内容如下:
-
<?xml version='1.0' encoding='utf8'?>
-
<!--
-
~ Hibernate, Relational Persistence for Idiomatic Java
-
~
-
~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
-
~ indicated by the @author tags or express copyright attribution
-
~ statements applied by the authors. All third-party contributions are
-
~ distributed under license by Red Hat Inc.
-
~
-
~ This copyrighted material is made available to anyone wishing to use, modify,
-
~ copy, or redistribute it subject to the terms and conditions of the GNU
-
~ Lesser General Public License, as published by the Free Software Foundation.
-
~
-
~ This program is distributed in the hope that it will be useful,
-
~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-
~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
-
~ for more details.
-
~
-
~ You should have received a copy of the GNU Lesser General Public License
-
~ along with this distribution; if not, write to:
-
~ Free Software Foundation, Inc.
-
~ 51 Franklin Street, Fifth Floor
-
~ Boston, MA 02110-1301 USA
-
-->
-
<!DOCTYPE hibernate-configuration PUBLIC
-
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
-
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
-
-
<hibernate-configuration>
-
-
<session-factory>
-
-
<!-- 数据库方言 -->
-
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
-
-
<!-- Enable Hibernate's automatic session context management -->
-
<property name="current_session_context_class">thread</property>
-
-
<!-- Disable the second-level cache -->
-
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
-
-
<!-- 打印输出执行的SQL语句 -->
-
<property name="show_sql">true</property>
-
-
<mapping resource="resources/mappers/Teacher.hbm.xml" />
-
-
</session-factory>
-
-
</hibernate-configuration>
Spring还提供了一种配置方式,可代替hibernate.cfg.xml。配置如下(配置文件是工程根目录下的beans2.xml):
-
<?xml version="1.0" encoding="utf8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:tx="http://www.springframework.org/schema/tx"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xsi:schemaLocation="
-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
-
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
-
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
-
default-autowire="byName" default-lazy-init="false">
-
-
<!--本示例采用DBCP数据源,应预先把DBCP的jar包复制到工程的lib目录下。数据源配置如下-->
-
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
-
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
-
<property name="url"
-
value="jdbc:mysql://localhost/courseman"/>
-
<property name="username" value="courseman"/>
-
<property name="password" value="abc123"/>
-
</bean>
-
-
<!--SessionFactory的另一种配置方式。这种方式可取代Hibernate的核心配置文件,因为如以下配置所示,
-
Hibernate的各种属性、实体映射文件等,都可以用这种方式配置-->
-
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
-
<!--dataSource属性指定要用到的连接池-->
-
<property name="dataSource" ref="dataSource"/>
-
<!--指定要用到的实体映射文件-->
-
<property name="mappingResources">
-
<list>
-
<value>resources/mappers/Teacher.hbm.xml</value>
-
</list>
-
</property>
-
<!--配置Hibernate的属性-->
-
<property name="hibernateProperties">
-
<value>
-
<!--数据库方言-->
-
hibernate.dialect=org.hibernate.dialect.MySQLDialect
-
<!-- 打印输出执行的SQL语句 -->
-
hibernate.show_sql=true
-
</value>
-
</property>
-
</bean>
-
-
</beans>
教师实体映射文件内容如下:
-
<?xml version="1.0"?>
-
<!DOCTYPE hibernate-mapping PUBLIC
-
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
-
-
<hibernate-mapping package="com.abc.domain">
-
-
<class name="Teacher" table="TEACHER">
-
<id name="id" type="java.lang.Integer" column="ID">
-
<generator class="native"/>
-
</id>
-
<property name="name"/>
-
<property name="gender"/>
-
<property name="researchArea" column="RESEARCH_AREA"/>
-
<property name="title"/>
-
</class>
-
-
</hibernate-mapping>
四、执行类
执行类(HibernateSpringDemo.java)的代码如下。
-
package com.demo;
-
-
import org.springframework.context.ApplicationContext;
-
import com.abc.domain.Teacher;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
import org.hibernate.SessionFactory;
-
import org.hibernate.Session;
-
-
-
public class HibernateSpringDemo
-
{
-
private static ApplicationContext ctx;
-
-
static
-
{
-
//在类路径下寻找resources/beans.xml文件
-
ctx = new ClassPathXmlApplicationContext("resources/beans.xml");
-
}
-
-
-
public static void main(String[] args)
-
{
-
//从Spring容器中请求SessionFactory
-
SessionFactory factory =
-
(SessionFactory)ctx.getBean("sessionFactory");
-
-
Session session = factory.openSession();
-
-
//读取id为1的教师。
-
Teacher teacher = (Teacher)session.get(Teacher.class, 1);
-
-
if(teacher != null)
-
{
-
System.out.println("姓 名: " + teacher.getName());
-
System.out.println("研究方向: " + teacher.getResearchArea());
-
}
-
-
else
-
{
-
System.out.println("未找到!");
-
}
-
-
session.close();
-
-
}
-
-
}
修改ant的build.xml文件的run target,指定此类为执行类。
-
<target name="run" depends="compile">
-
<!--指定HibernateSpringDemo为要运行的类-->
-
<java fork="true" classname="com.demo.HibernateSpringDemo"
-
classpathref="library">
-
<classpath path="${targetdir}"/>
-
</java>
-
</target>
执行结果如下:
五、可能会遇到的错误
1、缺少javassist包
对于需要的jar包,笔者并没有一次性把Spring和Hibernate提供的所有jar包全部用上,而是根据编译、运行时报出的找不到类的异常信息,找到相关的jar包,然后再复制到工程的lib目录下。然而,在编程过程中,却遇到了这个错误:java.lang.ExceptionInInitializerError,内嵌的异常是:org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]。上网查询,才得知是少了javassist包。感到奇怪的是,这次却没有报找不到类的异常信息。Hibernate发布包下有个lib目录,存放着Hibernate的jar包。它有个required(必需的)子目录,javassist包就在此目录下。既然是必需的,那就把此目录下的jar包全部用上吧,免得再出错后又得花上不少时间来排错。
2、字符集问题
hibernate.cfg.xml的编码本为utf-8,添加中文注释后报错:Could not parse configuration。把编码改为utf8或gbk后即可解决此问题。对于这个问题,Spring、MyBatis和ant,都是一个德行(请参见笔者博文“MyBatis与Spring集成示例”中的第五部分可能会遇到的错误中的“2、字符集问题”)。
转载于:https://blog.51cto.com/legend2011/963649