天天看點

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,如需轉載請自行聯系原作者