Skip to content
liuqingyao edited this page Mar 22, 2017 · 8 revisions

使用教程

1.引入jar包(代码较少,也可copy源码)

  • maven依赖尚未测试,推荐自己下载源码打包,或放到自己的私服中
  • 有什么好的扩展可以上传分享,在原公司,有同事进行了扩展实现了连接建立的时间监控

2.配置数据源multi-datasource.xml(代码片段)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <util:properties id="dataSourceProps" location="classpath:/conf/database.properties"/>


    <bean id="dbWrite" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="#{dataSourceProps['database.driverClassName']}"/>
        <property name="url" value="#{dataSourceProps['database.dbWrite.url']}"/>
        <property name="username" value="#{dataSourceProps['database.dbWrite.username']}"/>
        <property name="password" ref="dbWritePassword"/>
        <property name="initialSize" value="#{dataSourceProps['jdbc.pool.initialSize']}"/>
        <property name="maxTotal" value="#{dataSourceProps['jdbc.pool.maxTotal']}"/>
        <property name="maxIdle" value="#{dataSourceProps['jdbc.pool.maxIdle']}"/>
        <property name="minIdle" value="#{dataSourceProps['jdbc.pool.minIdle']}"/>
        <property name="maxWaitMillis" value="#{dataSourceProps['jdbc.pool.maxWait']}"/>

        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="validationQuery" value="select current_date()"/>
        <property name="validationQueryTimeout" value="1"/>
        <property name="timeBetweenEvictionRunsMillis" value="3000000"/>
        <property name="numTestsPerEvictionRun" value="18"/>
        <property name="minEvictableIdleTimeMillis" value="-1"/>
        <property name="softMinEvictableIdleTimeMillis" value="1800000"/>
        <property name="removeAbandonedOnBorrow" value="false"/>
        <property name="removeAbandonedOnMaintenance" value="true"/>
        <property name="removeAbandonedTimeout" value="180"/>
    </bean>

    <bean id="dbRead" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="#{dataSourceProps['database.driverClassName']}"/>
        <property name="url" value="#{dataSourceProps['database.dbReadSlow.url']}"/>
        <property name="username" value="#{dataSourceProps['database.dbReadSlow.username']}"/>
        <property name="password" ref="dbReadPassword"/>
        <property name="initialSize" value="#{dataSourceProps['jdbc.pool.initialSize']}"/>
        <property name="maxTotal" value="#{dataSourceProps['jdbc.pool.maxTotal']}"/>
        <property name="maxIdle" value="#{dataSourceProps['jdbc.pool.maxIdle']}"/>
        <property name="minIdle" value="#{dataSourceProps['jdbc.pool.minIdle']}"/>
        <property name="maxWaitMillis" value="#{dataSourceProps['jdbc.pool.maxWait']}"/>

        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="validationQuery" value="select current_date()"/>
        <property name="validationQueryTimeout" value="1"/>
        <property name="timeBetweenEvictionRunsMillis" value="3000000"/>
        <property name="numTestsPerEvictionRun" value="18"/>
        <property name="minEvictableIdleTimeMillis" value="-1"/>
        <property name="softMinEvictableIdleTimeMillis" value="1800000"/>
        <property name="removeAbandonedOnBorrow" value="false"/>
        <property name="removeAbandonedOnMaintenance" value="true"/>
        <property name="removeAbandonedTimeout" value="180"/>
    </bean>

    <bean id="dbReadSlow" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="#{dataSourceProps['database.driverClassName']}"/>
        <property name="url" value="#{dataSourceProps['database.dbReadSlow.url']}"/>
        <property name="username" value="#{dataSourceProps['database.dbReadSlow.username']}"/>
        <property name="password" ref="dbReadSlowPassword"/>
        <property name="initialSize" value="#{dataSourceProps['jdbc.pool.initialSize']}"/>
        <property name="maxTotal" value="#{dataSourceProps['jdbc.pool.maxTotal']}"/>
        <property name="maxIdle" value="#{dataSourceProps['jdbc.pool.maxIdle']}"/>
        <property name="minIdle" value="#{dataSourceProps['jdbc.pool.minIdle']}"/>
        <property name="maxWaitMillis" value="#{dataSourceProps['jdbc.pool.maxWait']}"/>

        <property name="testWhileIdle" value="true"/>
        <property name="testOnBorrow" value="false"/>
        <property name="testOnReturn" value="false"/>
        <property name="validationQuery" value="select current_date()"/>
        <property name="validationQueryTimeout" value="1"/>
        <property name="timeBetweenEvictionRunsMillis" value="3000000"/>
        <property name="numTestsPerEvictionRun" value="18"/>
        <property name="minEvictableIdleTimeMillis" value="-1"/>
        <property name="softMinEvictableIdleTimeMillis" value="1800000"/>
        <property name="removeAbandonedOnBorrow" value="false"/>
        <property name="removeAbandonedOnMaintenance" value="true"/>
        <property name="removeAbandonedTimeout" value="180"/>
    </bean>

    <!-- 动态数据源,继承于AbstractRoutingDataSource -->
    <bean id="multipleDataSource" class="com.company.component.datasource.multi_datasource.MultipleDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String"> <!-- 数据源配置 -->
                <entry key="dbWrite" value-ref="dbWrite"/>
                <entry key="dbRead" value-ref="dbRead"/>
                <entry key="dbReadSlow" value-ref="dbReadSlow"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dbReadSlow"/>
    </bean> </font>
    <!--  sqlSessionFactory for mybatis -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="multipleDataSource"/>
        <!-- 配置mybatis配置文件的位置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 配置扫描Mapper XML的位置,如果没有的可以删除,Mapper XML的暂时不支持 -->
        <property name="mapperLocations">
            <list>
                <value>classpath:mybatis_mapper/*Mapper.xml</value>
            </list>
        </property>
    </bean>

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>

    <!-- 配置扫描Mapper接口的包路径 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 如果是多个包名可用",; \t\n"中任意符号分隔开,详见:MapperScannerConfigurer[269行] -->
        <property name="basePackage" value="com.company.biz.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
    <bean id="mybatisTransactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="multipleDataSource"/>

    <tx:advice id="mybatisAdvice" transaction-manager="mybatisTransactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="remove*" propagation="REQUIRED"/>
            <tx:method name="accept*" propagation="REQUIRED"/>
            <tx:method name="reject*" propagation="REQUIRED"/>
            <tx:method name="execute*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="recover*" propagation="REQUIRED"/>
            <tx:method name="sync*" propagation="REQUIRED"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <bean id="multiDataSourceAspect"
          class="com.company.component.datasource.multi_datasource.aspect.MultipleDataSourceAspect"/>

    <aop:config>
        <aop:aspect ref="multiDataSourceAspect">
            <aop:around method="doAround"
                        pointcut="execution(public * com.company..dao.*.*(..))"/>
        </aop:aspect>
    </aop:config>
</beans>

3.在Spring主配置文件中引入multi-datasource.xml

<import resource="classpath:multi-datasource.xml"/>

4.DAO层代码配注解


import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

@Component
@DataSource("dbRead")
public interface AwardLinkDao {
    static final String TABLE = " award_link ";
    static final String SELECT_FIELDS = "id,user_id,share_link,ctime,valid";
    static final String INSERT_FIELDS = "user_id,share_link,ctime,valid";
    static final String INSERT_VALUES = "#{user_id},#{share_link},#{ctime},#{valid}";

    @DataSource("dbWrite")
    @Options(useGeneratedKeys = true)
    @Insert("insert into " + TABLE + " (" + INSERT_FIELDS + ") values (" + INSERT_VALUES + ")")
    public void insertAwardLink(AwardLink awardLink);

    @DataSource("dbRead")
    @Select("select " + SELECT_FIELDS + " from " + TABLE + " where user_id=#{bmUserId} and valid=1")
    public AwardLink getAwardLinkByUserId(@Param("userId") long UserId);

    @Select("select id from " + TABLE + " limit 1")
    public Long getFirstId();
}

注解生效优先级:方法级>类级>包级