• SPRING学习(三十八)--SPRING集成MYBATIS之数据库连接池和多种数据源配置方式(三)


    上一章节学习了如果运用spring集成mybatis,数据源配置使用的spring提供的数据源配置方式,另外还有一些第三方数据源配置方式,而且可以配置数据库连接池。

    通过数据库连接池可以增加数据访问的性能,因为访问数据库时建立连接与释放连接是耗时操作,JDBC默认不带连接池技术,但MyBatis是内置连接池功能的,还有一些第三方知名的连接池技术如:DBCP、C3P0、Druid(德鲁伊)。

    1、DBCP

    DBCP 是 Apache 软件基金组织下的开源连接池实现,要使用DBCP数据源,需要应用程序应在系统中增加如下两个 jar 文件:Commons-dbcp.jar:连接池的实现、Commons-pool.jar:连接池实现的依赖库,常用属性如下:

    (1)pom.xml文件添加依赖

         <!--propertiesUtil 读取配置文件-->
        <dependency>
            <groupId>commons-configuration</groupId>
            <artifactId>commons-configuration</artifactId>
            <version>1.10</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <!-- mybatis驱动包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--mybatis-spring适配器 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--Spring java数据库访问包,在本例中主要用于提供数据源 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- apache dbcp 方式配置数据源驱动包 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- apache 数据库连接池包 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.6</version>
        </dependency>

    (2)db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/mytestdatabase?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username=qiaozhong
    password=1
    initialSize=2
    maxActive=5
    minIdle=2
    maxIdle=5
    maxWait=10

    (3)spring-mybatis.xml配置:

    <?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:mvc="http://www.springframework.org/schema/mvc"
        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
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ">
        
        <!-- 引入配置文件 -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:mybatisConfig/db.properties" />
        </bean>
    
        <!-- 数据源与数据库连接池配置 -->
           <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${driver}" />
            <property name="url" value="${url}" />
            <property name="username" value="${username}" />
            <property name="password" value="${password}" />
            <!-- 初始化连接大小 -->
            <property name="initialSize" value="${initialSize}" />
            <!-- 连接池最大数量 -->
            <property name="maxActive" value="${maxActive}" />
            <!-- 连接池最大空闲 -->
            <property name="maxIdle" value="${maxIdle}" />
            <!-- 连接池最小空闲 -->
            <property name="minIdle" value="${minIdle}" />
            <!-- 获取连接最大等待时间 -->
            <property name="maxWait" value="${maxWait}" />
        </bean>
    
        <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
            <property name="mapperLocations" value="classpath:mybatis/**.xml" />
        </bean>
    
        <!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
        <bean id="mapperScanConfig" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="mybatis.dao" />
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
        
        <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    </beans>

    上述通过DBCP方式配置了数据源和数据库连接池,如何验证我们的数据库连接池配置生效呢?

    可以通过查看数据库连接数来判断,查看命令:D:ProgramFilesMySQLMySQL Server 5.7in>mysqladmin  -uqiaozhong -p1 -h127.0.0.1 -P3306 status

    先进入到mysql安装目录D:ProgramFilesMySQLMySQL Server 5.7in

    执行:mysqladmin  -uqiaozhong -p1 -h127.0.0.1 -P3306 status

    其中-u为数据库用户名,-p为密码password,-h为数据库ip,-P为端口port

    返回值中的Threads为数据库连接数。

    验证流程:

    1>不启动程序,执行命令查看mysql连接数为1。

    2>在测试类中打个断点,对数据库测试函数进行debug,执行命令查看mysql连接数变为3。因为db.properties中配置的数据库连接池初始化连接数和最小空闲连接数均为2。

    3>连接池配置成功。

     2、C3P0

     C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。C3P0数据源在项目开发中使用得比较多。dbcp没有自动回收空闲连接的功能,而c3p0有自动回收空闲连接功能。

    (1)pom.xml文件增加依赖:

         <!--propertiesUtil 读取配置文件-->
        <dependency>
            <groupId>commons-configuration</groupId>
            <artifactId>commons-configuration</artifactId>
            <version>1.10</version>
        </dependency>
        
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <!-- mybatis驱动包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--mybatis-spring适配器 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--Spring java数据库访问包,在本例中主要用于提供数据源 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!--c3p0 连接池 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

    (2)db.properties配置:

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/mytestdatabase?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username=qiaozhong
    acquireIncrement=3
    password=1
    initialSize=1
    maxActive=5
    minIdle=1
    maxIdle=5
    maxWait=10
    idleConnectionTestPeriod=60

    (3)spring-mybatis.xml配置:

    <?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:mvc="http://www.springframework.org/schema/mvc"
        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
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ">
        
        <!-- 引入配置文件 -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:mybatisConfig/db.properties" />
        </bean>
    
        <!-- C3P0数据源与数据库连接池配置 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
            <property name="driverClass" value="${driver}" />
            <property name="jdbcUrl" value="${url}" />
            <property name="user" value="${username}" />
            <property name="password" value="${password}" />
            <!-- acquireIncrement:链接用完了自动增量的数量。 -->
            <property name="acquireIncrement" value="${acquireIncrement}" />
            <!--initialPoolSize:初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。 --> 
            <property name="initialPoolSize" value="${initialSize}" />
            <!--maxPoolSize:连接池中保留的最小连接数。 -->
            <property name="minPoolSize" value="${minIdle}" />
            <!--maxPoolSize:连接池中保留的最大连接数。 -->
            <property name="maxPoolSize" value="${maxIdle}" />
            <!--maxIdleTime:最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。-->
            <property name="maxIdleTime" value="${maxWait}" />
            <!--idleConnectionTestPeriod:检查所有连接池中的空闲连接的时间间隔,单位秒--> 
            <property name="idleConnectionTestPeriod"  value="${idleConnectionTestPeriod}" />
        </bean>
        
        <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
            <property name="mapperLocations" value="classpath:mybatis/**.xml" />
        </bean>
    
        <!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
        <bean id="mapperScanConfig" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="mybatis.dao" />
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
        
        <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    </beans>

    3、Druid(德鲁伊)

    Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。阿里巴巴是一个重度使用关系数据库的公司,我们在生产环境中大量的使用Druid,通过长期在极高负载的生产环境中实际使用、修改和完善,让Druid逐步发展成最好的数据库连接池。Druid在监控、可扩展性、稳定性和性能方面都有明显的优势。

     (1)pom.xml配置:

        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>
        <!-- mybatis驱动包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--mybatis-spring适配器 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--Spring java数据库访问包,在本例中主要用于提供数据源 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- 为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- druid(德鲁伊)数据源和连接池 -->
        <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid</artifactId>
             <version>1.0.20</version>
        </dependency>

    (2)db.properties

    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://127.0.0.1:3306/mytestdatabase?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username=qiaozhong
    password=1
    initialSize=1
    maxActive=5
    minIdle=1
    maxIdle=5
    maxWait=10
    timeBetweenEvictionRunsMillis=60000
    minEvictableIdleTimeMillis=25200000

    (3)spring-mybatis.xml配置:

    <?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:mvc="http://www.springframework.org/schema/mvc"
        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
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ">
        
        <!-- 引入配置文件 -->
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="location" value="classpath:mybatisConfig/db.properties" />
        </bean>
        
        <!-- 配置数据源与数据库连接池,使用的是alibaba的Druid(德鲁伊)数据源 -->
        <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
            <property name="driverClassName" value="${driver}" />
            <property name="url" value="${url}" />
            <property name="username" value="${username}" />
            <property name="password" value="${password}" />
            <!-- 初始化连接大小 -->
            <property name="initialSize" value="${initialSize}" />
            <!-- 连接池最大使用连接数量 -->
            <property name="maxActive" value="${maxActive}" />
            <!-- 连接池最大空闲 -->
            <property name="maxIdle" value="${maxIdle}" />
            <!-- 连接池最小空闲 -->
            <property name="minIdle" value="${minIdle}" />
            <!-- 获取连接最大等待时间 -->
            <property name="maxWait" value="${maxWait}" />
            <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
            <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
            <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
            <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />
            <!-- 监控数据库 -->
            <property name="filters" value="mergeStat" />
        </bean>
        
        <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
            <property name="mapperLocations" value="classpath:mybatis/**.xml" />
        </bean>
    
        <!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
        <bean id="mapperScanConfig" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="mybatis.dao" />
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
        
        <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    </beans>

    4、SqlSession

    Mybatis-Spring为我们提供了一个实现了SqlSession接口的SqlSessionTemplate类,它是线程安全的,可以被多个Dao同时使用。同时它还跟Spring的事务进行了关联,确保当前被使用的SqlSession是一个已经和Spring的事务进行绑定了的。而且它还可以自己管理Session的提交和关闭。当使用了Spring的事务管理机制后,SqlSession还可以跟着Spring的事务一起提交和回滚。修改applicationContext.xml文件,增加一个bean。

    SqlSessionTemplate 是 MyBatis-Spring 的核心。 这个类负责管理 MyBatis 的 SqlSession, 调用 MyBatis 的 SQL 方法, 翻译异常。 SqlSessionTemplate 是线程安全的, 可以被多个 DAO 所共享使用。
    当调用 SQL 方法时, 包含从映射器 getMapper()方法返回的方法, SqlSessionTemplate 将会保证使用的 SqlSession 是和当前 Spring 的事务相关的。此外,它管理 session 的生命 周期,包含必要的关闭,提交或回滚操作。
    SqlSessionTemplate 实现了 SqlSession 接口,这就是说,在代码中无需对 MyBatis 的 SqlSession 进行替换。 SqlSessionTemplate 通常是被用来替代默认的 MyBatis 实现的 DefaultSqlSession , 因为模板可以参与到 Spring 的事务中并且被多个注入的映射器类所使 用时也是线程安全的。相同应用程序中两个类之间的转换可能会引起数据一致性的问题。
    SqlSessionTemplate 对象可以使用 SqlSessionFactory 作为构造方法的参数来创建。

        <!-- 创建一个sqlSession对象 -->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="sqlSessionFactory" />
        </bean>
        
        <!--创建一个BTDImpl对象 -->
        <bean id="bTDImpl" class="com.zhangguo.Spring61.dao.BTDImpl">
            <property name="sqlSession" ref="sqlSession"></property>
        </bean>

    新增一个BTDImpl类,实现接口BookTypeDAO,具体如下:

    package com.zhangguo.Spring61.dao;
    
    import java.util.List;
    import org.apache.ibatis.session.SqlSession;
    import com.zhangguo.Spring61.entities.BookType;
    import com.zhangguo.Spring61.mapping.BookTypeDAO;
    
    public class BTDImpl implements BookTypeDAO {
        private SqlSession sqlSession;
    
        public void setSqlSession(SqlSession sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public List<BookType> getAllBookTypes() {
            return sqlSession.selectList("com.zhangguo.Spring61.mapping.BookTypeDAO.getAllBookTypes");
        }
    
    }

    使用Spring的依赖注入在DAO中直接使用SqlSessionTemplate来访问数据库了。

    测试代码:

    package com.zhangguo.Spring61.test;
    
    import static org.junit.Assert.assertNotNull;
    import java.util.List;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import com.zhangguo.Spring61.dao.BTDImpl;
    import com.zhangguo.Spring61.entities.BookType;
    
    public class TestMyBatisSpring02 {
        @Test
        public void test01() {
            //初始化容器
            ApplicationContext ctx=new ClassPathXmlApplicationContext("ApplicationContext.xml");
            //获得bean
            BTDImpl bTDImpl=ctx.getBean("bTDImpl",BTDImpl.class);
            //访问数据库
            List<BookType> booktypes=bTDImpl.getAllBookTypes();
            for (BookType bookType : booktypes) {
                System.out.println(bookType);
            }
            assertNotNull(booktypes);
        }
    }

    运行结果:

     

    也可以通过自动装配实现,使配置更加简单,在配置文件中可以删除“创建一个BTDImpl对象”这一段,在类BTDImpl中增加注解,代码如下:

    package com.zhangguo.Spring61.dao;
    
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.apache.ibatis.session.SqlSession;
    import org.springframework.stereotype.Repository;
    
    import com.zhangguo.Spring61.entities.BookType;
    import com.zhangguo.Spring61.mapping.BookTypeDAO;
    
    @Repository
    public class BTDImpl implements BookTypeDAO {
        @Resource
        private SqlSession sqlSession;
    
        public void setSqlSession(SqlSession sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public List<BookType> getAllBookTypes() {
            return sqlSession.selectList("com.zhangguo.Spring61.mapping.BookTypeDAO.getAllBookTypes");
        }
    
    }

     测试方法获得bean要修改成:BTDImpl bTDImpl=ctx.getBean(BTDImpl.class);,运行结果同上。

    个人理解,如有错误,欢迎指正!
  • 相关阅读:
    windowsCE常用编译参数 及编译器列表
    摘抄System Architecture for Native Device Drivers
    django+vue学习系列
    FreeTextBox的ToolbarButton整理
    FreeTextBox实现机制
    Server的Transfer和Response的Redirect
    FTB2.0和CuteEditor的一些问题
    ASP.NET跨应用程序进行登录的解决
    testFTB2.0
    Rainbow分页解决方案
  • 原文地址:https://www.cnblogs.com/gllegolas/p/11885593.html
Copyright © 2020-2023  润新知