1.SpringMVC整合MyBatis及多数据源配置
1.1pom.xml文件引入mybatis配置
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- myBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis-version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring-version}</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
1.2 /resources目录添加mybatis-config.xml配置文件以及mybatis目录
这个工程我配置了两个数据源,所以mybatis目录下的Mapper文件根据不同数据源分别放在不同目录下,这样编译扫描Mapper文件。
mybatis-config.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--
| plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
| properties?, settings?,
| typeAliases?, typeHandlers?,
| objectFactory?,objectWrapperFactory?,
| plugins?,
| environments?, databaseIdProvider?, mappers?
|-->
<configuration>
<!--
| 全局配置设置
|
| 可配置选项 默认值, 描述
|
| aggressiveLazyLoading true, 当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。
| multipleResultSetsEnabled true, 允许和不允许单条语句返回多个数据集(取决于驱动需求)
| useColumnLabel true, 使用列标签代替列名称。不同的驱动器有不同的作法。参考一下驱动器文档,或者用这两个不同的选项进行测试一下。
| useGeneratedKeys false, 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。
| autoMappingBehavior PARTIAL, 指定MyBatis 是否并且如何来自动映射数据表字段与对象的属性。PARTIAL将只自动映射简单的,没有嵌套的结果。FULL 将自动映射所有复杂的结果。
| defaultExecutorType SIMPLE, 配置和设定执行器,SIMPLE 执行器执行其它语句。REUSE 执行器可能重复使用prepared statements 语句,BATCH执行器可以重复执行语句和批量更新。
| defaultStatementTimeout null, 设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时
| -->
<settings>
<!-- 这个配置使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="defaultExecutorType" value="REUSE"/>
<setting name="defaultStatementTimeout" value="25000"/>
</settings>
</configuration>
Mapper.xml文件和Dao类要一一对应
Mapper.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.dao.second.ChannelDao">
<!--例子http://www.2cto.com/database/201409/338155.html-->
<resultMap type="com.test.domain.ProductChannel" id="ChannelResult">
<result column="channel" property="channel"/>
<result column="name" property="name"/>
</resultMap>
<select id="getChannelList" resultMap="ChannelResult">
select channel,name from tb_channel where deleted = 0 and length(name) > 0 and p_id = 91
ORDER BY id
</select>
</mapper>
namespace要指定对应的Dao类。Dao类内容如下:
package com.test.dao.second;
import com.test.domain.ProductChannel;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* Created by on 2017/12/27.
*/
@Mapper
public interface ChannelDao {
List<ProductChannel> getChannelList();
}
1.3 spring-context.xml配置数据源
SpringMVC工程当中数据源的配置是写在spring-context.xml文件当中的。
<!-- Mapper文件扫描路径配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxxx.xxx.dao.first"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory1"/>
</bean>
<!-- 数据库1配置 -->
<bean id="sqlSessionFactory1" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="adminDataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:/mybatis/first/*Mapper.xml"/>
</bean>
<bean id="sqlSessionTemplate1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1"/>
<constructor-arg index="1" value="BATCH"/>
</bean>
<bean id="transactionManager1" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="adminDataSource"></property>
</bean>
<bean id="adminDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${admin-jdbc.driverClassName}" />
<property name="jdbcUrl" value="${admin-jdbc.url}" />
<property name="user" value="${admin-jdbc.user}" />
<property name="password" value="${admin-jdbc.pass}" />
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="${c3p0.minPoolSize}" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}" />
<property name="initialPoolSize" value="${c3p0.initialPoolSize}" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}" />
<property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}" />
</bean>
<tx:advice id="adminTxAdvice" transaction-manager="transactionManager1">
<tx:attributes>
<!-- 以下方法必须在事物中执行,一般增、删、改操作需要配置事务 -->
<!-- REQUIRED 如果当前有事务环境就加入当前正在执行的事务环境,如果当前没有事务,就新建一个事务。 -->
<tx:method name="create*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="import*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="finish*" propagation="REQUIRED"/>
<tx:method name="freeze*" propagation="REQUIRED"/>
<tx:method name="edit*" propagation="REQUIRED"/>
<tx:method name="up*" propagation="REQUIRED"/>
<tx:method name="down*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="REQUIRED"/>
<tx:method name="unselect*" propagation="REQUIRED"/>
<!-- 以下方法以非事务方式执行,一般用于查询操作 -->
<!-- 如果当前存在事务,就把当前事务挂起,等该方法以非事务的状态运行完,再继续原来的事务。 -->
<!-- read-only="true" 表示只读 -->
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
其中${admin-jdbc.url}这些参数是从jdbc.properties配置文件中读取的,具体的配置在我的文章《SpringMVC和SpringBoot开发环境、生产环境的多环境配置》中有详细介绍。
SpringMVC的多数据源配置很简单,只要按照上面的方式再创建一组bean就行了,如下所示:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxxx.xxx.dao.second"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory2"/>
</bean>
<!-- 数据库2配置 -->
<bean id="sqlSessionFactory2" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="secondDataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:/mybatis/second/*Mapper.xml"/>
</bean>
<bean id="sqlSessionTemplate2" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory2"/>
<constructor-arg index="1" value="BATCH"/>
</bean>
<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="secondDataSource"></property>
</bean>
<bean id="secondDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="${second-jdbc.driverClassName}" />
<property name="jdbcUrl" value="${second-jdbc.url}" />
<property name="user" value="${second-jdbc.user}" />
<property name="password" value="${second-jdbc.pass}" />
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize" value="${c3p0.minPoolSize}" />
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}" />
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}" />
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}" />
<property name="initialPoolSize" value="${c3p0.initialPoolSize}" />
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}" />
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}" />
<property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}" />
</bean>
<tx:advice id="secondTxAdvice" transaction-manager="transactionManager2">
<tx:attributes>
<!-- 以下方法必须在事物中执行,一般增、删、改操作需要配置事务 -->
<!-- REQUIRED 如果当前有事务环境就加入当前正在执行的事务环境,如果当前没有事务,就新建一个事务。 -->
<tx:method name="create*" propagation="REQUIRED"/>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="import*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="finish*" propagation="REQUIRED"/>
<tx:method name="freeze*" propagation="REQUIRED"/>
<tx:method name="edit*" propagation="REQUIRED"/>
<tx:method name="up*" propagation="REQUIRED"/>
<tx:method name="down*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="REQUIRED"/>
<tx:method name="unselect*" propagation="REQUIRED"/>
<!-- 以下方法以非事务方式执行,一般用于查询操作 -->
<!-- 如果当前存在事务,就把当前事务挂起,等该方法以非事务的状态运行完,再继续原来的事务。 -->
<!-- read-only="true" 表示只读 -->
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
2.SpringBoot整合Mybatis及多数据源配置
SpringBoot对各种常用软件的整合做了很多很好的封装,SpringBoot整合MyBatis网上有很多教程,这里只介绍一下多数据源的SpringBoot配置。
2.1 application.properties配置不同数据源的连接配置
Mapper文件和Dao类同样根据数据源进行分组
2.2 创建数据源配置类
不同数据源创建不同的配置类,如下
配置类内容如下:
package com.xxxx.xxx.datasource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* Created by on 17/7/17.
*/
@Configuration
@MapperScan(basePackages = "com.xxxx.xxx.dao.source", sqlSessionTemplateRef = "fromSqlSessionTemplate")
@PropertySource("classpath:application.properties")
public class SourceDataSourceConfig {
@Bean(name = "fromDataSource")
@ConfigurationProperties(prefix = "jdbcFrom")
@Primary
public DataSource fromDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "fromSqlSessionFactory")
@Primary
public SqlSessionFactory fromSqlSessionFactory(@Qualifier("fromDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/source/*Mapper.xml"));
return bean.getObject();
}
@Bean(name = "fromTransactionManager")
@Primary
public DataSourceTransactionManager fromTransactionManager(@Qualifier("fromDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "fromSqlSessionTemplate")
@Primary
public SqlSessionTemplate fromSqlSessionTemplate(@Qualifier("fromSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
第二个数据源的配置类同上,只是bean的名称要取不一样的。
SpringMVC和SpringBoot整合mybatis以及多数据源配置就讲解到这里,更多精彩文章敬请期待。