ETJava Beta | Java    注册   登录
  • Spring整合Mybatis时配置C3P0连接池报Could not load driverClass错误

    发表于 2024-09-20 19:32:37     阅读(265)     博客类别:Spring

    问题描述

    在使用Spring整合Mybatis时 配置C3P0连接池时报Could not load driverClass ${jdbc.driver} 错误 但可以正常查询到数据 如果将表达式修改为具体值则不会报错 

     

    原因分析

     

    在整合mybatis时配置了MapperScannerConfigurer 而MapperScannerConfigure需要注入SqlSessionFactory工厂 而SqlSessionFactory工厂需要注入数据源 从而引发了一系列的关联 然而问题则出现在MapperScannerConfigurer与数据源的执行顺序上
    MapperScannerConfigurer会先于数据源执行 因此在MapperScannerConfigurer执行之后就把表达式${jdbc.driver}当作字符串执行
    又因为c3p0有默认的重连机制 确保数据库恢复后能够可以继续连接 因此当driver刚开始注入失败时会继续尝试重新连接 默认30次

     

    解决方案

     

    解决方案有两个

     

    方案1

     

    注入mybatis的MapperScannerConfigurer时 给sqlSessionFactoryBeanName属性注入值
    注意 值为String类型(使用value赋值) 同时要确保IOC容器中已经存在了名称为sqlSessionFactroy的bean

    示例

    <context:property-placeholder location="classpath:database.properties"/>
    
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          <property name="driverClass" value="${jdbc.driver}"/>
          <property name="jdbcUrl" value="${jdbc.url}"/>
          <property name="user" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
      </bean>
    
    
      <bean id="sqlSessionFactroy" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
          <property name="configLocation" value="classpath:mybatis-config.xml"/>
      </bean>
    
    
    
    
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactroy"/>
         <property name="basePackage" value="com.kuang.dao"/>
      </bean>

     

    方案2

     

      让spring的ioc自动注入 我们不在手动关联sqlSessionFactoryBean的注入
          即 在注入myatis的MapperScannerConfigurer时 不指定sqlSessionFactoryBeanName

      注意: 在配置SqlSessionFactoryBean会话工厂bean时 id属性名必须为sqlSessionFactory 否则Spring无法自动关联

     

    示例

     

    <?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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
        
      <context:property-placeholder location="classpath:database.properties"/>
    
      <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
          <property name="driverClass" value="${jdbc.driver}"/>
          <property name="jdbcUrl" value="${jdbc.url}"/>
          <property name="user" value="${jdbc.username}"/>
          <property name="password" value="${jdbc.password}"/>
      </bean>
    
    
      <bean id="sqlSessionFactroy" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="dataSource"/>
          <property name="configLocation" value="classpath:mybatis-config.xml"/>
      </bean>
    
    
    
    
      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--Spring自动注入sqlSessionFactoryBean 这里不在手动关联 --> 
        <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactroy"/>-->
        <property name="basePackage" value="com.kuang.dao"/>
    </bean>
    
    
    </beans>

     

    方案3(未测试)

    通过c3p0的配置文件自行配置 
    即 自定义c3p0-config.xml或c3p0-config.properties文件
    然后通过配置文件关联相关的数据库连接信息
    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!--<default-config>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_demo
            </property>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="user">root</property>
            <property name="password">root</property>
    
    
            <property name="checkoutTimeout">30000</property>
            <property name="idleConnectionTestPeriod">30</property>
            <property name="initialPoolSize">10</property>
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">100</property>
            <property name="minPoolSize">10</property>
            <property name="maxStatements">200</property>
        </default-config>-->
    </c3p0-config>