天天看点

Hibernate与Spring集成示例

一、版本说明

      Spring:3.1.2。

      Hibernate:3.6.7.Final。

二、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对象的工厂。

三、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): 

  <!--SessionFactory的另一种配置方式。这种方式可取代Hibernate的核心配置文件,因为如以下配置所示,  

  Hibernate的各种属性、实体映射文件等,都可以用这种方式配置--> 

     <!--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> 

</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>   

执行结果如下:

<a href="http://blog.51cto.com/attachment/201208/184120808.png" target="_blank"></a>

五、可能会遇到的错误

      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、字符集问题

本文转自 NashMaster2011 51CTO博客,原文链接:http://blog.51cto.com/legend2011/963649,如需转载请自行联系原作者