Spring整合Hibernate记录之数据库参数配置

 

环境:spring3 + hibernate3

对于数据库一些参数不需要经常修改,我们一般是写在配置文件,但是有时候又需要修改,spring提供了一个<content:property-placeholder>元素 

只需要在spring配置文件添加<context:property-placeholder location="classpath:jdbc.properties"/> 即可

或者

<bean id="propertyPlaceholderConfigurer" class="org.springframework,beans.factory.config.PropertyPlaceholderConfigurer">                     <property name="locations">

                      <list>

                                <value>jdbc.properties<value/>

                               <如果有多个>

                                 <value>jdbc.properties<value/>

                      </list>

扫描二维码关注公众号,回复: 2786175 查看本文章

</property>

</bean>

 

除了这种方式还可以使用另外一种方式:

    <context:property-placeholder ignore-unresolvable="true" location="classpath:spring-orm-jdbc.properties" />

如果有多个可以用逗号分隔

<context:property-placeholderlocation="classpath:spring-orm-jdbc.properties,classpath:spring-orm-jdbc.properties" />

如果名字相同的,会取最后一个。

 

配置文件如下:

这样就可以在spring的bean配置的时候使用这些参数

下一步是先配置数据源,使用的是阿里巴巴的druid.pool,下面是配置内容:

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        init-method="init" destroy-method="close">
        <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
        <property name="driverClassName" value="${jdbc.driver}" />
        <!-- 基本属性 url、user、password -->
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="${jdbc.pool.init}" />
        <property name="minIdle" value="${jdbc.pool.minIdle}" />
        <property name="maxActive" value="${jdbc.pool.maxActive}" />

        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="60000" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="testWhileIdle" value="true" />

        <!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="false" />

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="true" />
        <property name="maxPoolPreparedStatementPerConnectionSize"
            value="20" />

        <!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->
        <property name="defaultAutoCommit" value="true" />

        <!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
        <property name="validationQuery" value="${jdbc.testSql}" />
        <property name="filters" value="stat" />
    </bean>

因为整合spring和hibernate,sessionFactory的配置如下:

    <!-- 配置SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <!-- 依赖数据源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- Hibernate框架相关配置 -->
        <property name="hibernateProperties">
            <props>
                <!-- 指定连接的数据库类型方言 -->
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <!--显示SQL语句 输出到控制台-->  
                <prop key="hibernate.show_sql">true</prop>
                <!--以格式良好的方式显示SQL语句-->  
                <prop key="hibernate.formate_sql">true</prop>
            </props>
        </property>
        <!-- 自动扫描mapping -->
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath*:/mappings/</value>
            </list>
        </property>
    </bean>

在加载hibernate映射文件的时候踩了个坑,主要是mappingDirectoryLocations的配置问题,在网上查询得知:

mappingDirectoryLocations 是目录,

mappingLocations               是具体某个文件

mappingJarLocations          是jar包

但是我一开始是这样配置的:

        <!-- 自动扫描mapping -->
        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath*:/mappings/**/*.hbm.xml</value>
            </list>
        </property>

结果测试的时候报下面错误:

Caused by: java.lang.IllegalArgumentException: Mapping directory location [file [D:\workspace\spring-orm\target\classes\mappings\hibernate\user.hbm.xml]] does not denote a directory

接下来是配置事务,

    <!-- 配置spring事务 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean> 

实现事务有2种形式:

方式1:基于aop 

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="update*"     propagation="REQUIRED" />
            <tx:method name="delete*"     propagation="REQUIRED" />
            <tx:method name="add*"         propagation="REQUIRED" />
            <tx:method name="load*"     read-only="true" />
            <tx:method name="execute"     propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut expression="execution(* com.spring.orm.hibernate.*.*(..))" id="txPointcut"/>
        <aop:advisor  advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>

方式2:基于注解

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="false" />

proxy-target-class 如果是true,需要导入cglib-nodep-2.1_3.jar包,因为我的版本是spring3 否则会报下面错误:

org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.

一开始是proxy-target-class=true, 但是有警告

 WARN [org.springframework.aop.framework.Cglib2AopProxy] - Unable to proxy method [public final void org.springframework.orm.hibernate3.support.HibernateDaoSupport.setSessionFactory(org.hibernate.SessionFactory)] because it is final: All calls to this method via a proxy will be routed directly to the proxy.

CGLIB使用的是继承的方式,不能代理final的类或方法,后来改成了false 使用jdk的继承代理

配置完毕后,高高兴兴开始测试,用的是JUnit测试,结果一开始跑的时候,没反应,报错了,连配置文件都加载不进来,

ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context-jdbc.xml");

后来查询需要用到spring-test模块

然后加入了模块之后,

还需要添加@RunWith(SpringJUnit4ClassRunner.class) 注解

网上的说法是:
@RunWith:用于指定junit运行环境,是junit提供给其他框架测试环境接口扩展,为了便于使用spring的依赖注入,spring提供了org.springframework.test.context.junit4.SpringJUnit4ClassRunner作为Junit测试环境

@ContextConfiguration注解加载配置文件,因为我就一个,所以直接加载,如果有多个的话 写在applicationContext.xml里面,然后加载applicationContext.xml 即可

   @Autowired //自动注入
   private  SessionFactory sessionFactory;

自动注入SessionFactory

途中遇到过2个问题:

错误1:

java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

缺少了commons-logging包

错误2:

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element
The prefix "tx" for element "tx:annotation-driven" is not bound.

缺少了头文件

xmlns:tx="http://www.springframework.org/schema/tx"

http://www.springframework.org/schema/tx  

添加之后发现White spaces are required between publicId and systemId. 查询得知是顺序出错,

<?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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-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/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd 
    http://www.springframework.org/schema/tx                  
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

这是现在完整的头

修改完毕之后,终于跑起来了。特此记录

猜你喜欢

转载自blog.csdn.net/u013365247/article/details/81669510