sharding-jdbc集成spring+mybatis分表分库

maven:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fulihui.com</groupId>
    <artifactId>sharding-jdbc-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.1.3.RELEASE</spring.version>
        <mybatis.version>3.2.4</mybatis.version>
        <sharding-jdbc.version>1.3.1</sharding-jdbc.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.dangdang</groupId>
            <artifactId>sharding-jdbc-core</artifactId>
            <version>${sharding-jdbc.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.dangdang</groupId>
            <artifactId>sharding-jdbc-transaction</artifactId>
            <version>${sharding-jdbc.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.dangdang</groupId>
            <artifactId>sharding-jdbc-config-spring</artifactId>
            <version>${sharding-jdbc.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.28</version>
        </dependency>
    </dependencies>
</project>

建表语句:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_student_0
-- ----------------------------
DROP TABLE IF EXISTS `t_student_0`;
CREATE TABLE `t_student_0` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `t_student_1`;
CREATE TABLE `t_student_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `t_user_2`;
CREATE TABLE `t_user_2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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"
   xmlns:tx="http://www.springframework.org/schema/tx" xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.dangdang.com/schema/ddframe/rdb
        http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd">


   <context:component-scan base-package="com.fulihui.sharding.jdbc" />

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.fulihui.sharding.jdbc.dal.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
    
    <!-- 配置sqlSessionFactory -->
     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="shardingDataSource"/>
        <property name="mapperLocations" value="classpath*:config/mapper/*-mapper.xml"/>
    </bean>

    <!-- 路由表、路由库规则配置,可以指定algorithm-class专门自己实现具体的路由规则,也可以使用表达式-->
    <rdb:strategy id="userDatabaseShardingStrategy" sharding-columns="user_id" algorithm-class="com.fulihui.sharding.jdbc.algorithm.UserDatabaseShardingAlgorithm"/>
    <rdb:strategy id="userTableShardingStrategy" sharding-columns="user_id" algorithm-class="com.fulihui.sharding.jdbc.algorithm.UserTableShardingAlgorithm"/>

    <!-- 使用表达式方式 -->
    <rdb:strategy id="studentDatabaseShardingStrategy" sharding-columns="student_id" algorithm-expression="sharding_${student_id.longValue() % 2}"/>
    <rdb:strategy id="studentTableShardingStrategy" sharding-columns="student_id" algorithm-expression="t_student_${student_id.longValue() % 2}"/>

    <rdb:data-source id="shardingDataSource">
        <rdb:sharding-rule data-sources="sharding_0,sharding_1">
            <rdb:table-rules>
                <rdb:table-rule logic-table="t_user" actual-tables="sharding_${0..1}.t_user_${0..2}" database-strategy="userDatabaseShardingStrategy" table-strategy="userTableShardingStrategy"/>
                <rdb:table-rule logic-table="t_student" actual-tables="sharding_${0..1}.t_student_${0..1}" database-strategy="studentDatabaseShardingStrategy" table-strategy="studentTableShardingStrategy"/>
            </rdb:table-rules>
            <rdb:default-database-strategy sharding-columns="none" algorithm-class="com.dangdang.ddframe.rdb.sharding.api.strategy.database.NoneDatabaseShardingAlgorithm"/>
            <rdb:default-table-strategy sharding-columns="none" algorithm-class="com.dangdang.ddframe.rdb.sharding.api.strategy.table.NoneTableShardingAlgorithm"/>
        </rdb:sharding-rule>
        <rdb:props>
            <prop key="metrics.enable">false</prop>
        </rdb:props>
    </rdb:data-source>

    <!-- 事务 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="shardingDataSource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />

</beans>
<?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:config/resource/jdbc_dev.properties" ignore-unresolvable="true"/>

   <bean name="sharding_0" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
      <property name="url" value="${jdbc_url0}" />
      <property name="username" value="${jdbc_username0}" />
      <property name="password" value="${jdbc_password0}" />
      <!-- 初始化连接大小 -->
      <property name="initialSize" value="0" />
      <!-- 连接池最大使用连接数量 -->
      <property name="maxActive" value="20" />
      <!-- 连接池最小空闲 -->
      <property name="minIdle" value="0" />
      <!-- 获取连接最大等待时间 -->
      <property name="maxWait" value="60000" />
      <property name="validationQuery" value="${validationQuery}" />
      <property name="testOnBorrow" value="false" />
      <property name="testOnReturn" value="false" />
      <property name="testWhileIdle" value="true" />
      <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
      <property name="timeBetweenEvictionRunsMillis" value="60000" />
      <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
      <property name="minEvictableIdleTimeMillis" value="25200000" />
      <!-- 打开removeAbandoned功能 -->
      <property name="removeAbandoned" value="true" />
      <!-- 1800秒,也就是30分钟 -->
      <property name="removeAbandonedTimeout" value="1800" />
      <!-- 关闭abanded连接时输出错误日志 -->
      <property name="logAbandoned" value="true" />
      <property name="filters" value="stat" />
   </bean>

   <bean name="sharding_1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
      <property name="url" value="${jdbc_url1}" />
      <property name="username" value="${jdbc_username1}" />
      <property name="password" value="${jdbc_password1}" />
      <!-- 初始化连接大小 -->
      <property name="initialSize" value="0" />
      <!-- 连接池最大使用连接数量 -->
      <property name="maxActive" value="20" />
      <!-- 连接池最小空闲 -->
      <property name="minIdle" value="0" />
      <!-- 获取连接最大等待时间 -->
      <property name="maxWait" value="60000" />
      <property name="validationQuery" value="${validationQuery}" />
      <property name="testOnBorrow" value="false" />
      <property name="testOnReturn" value="false" />
      <property name="testWhileIdle" value="true" />
      <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
      <property name="timeBetweenEvictionRunsMillis" value="60000" />
      <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
      <property name="minEvictableIdleTimeMillis" value="25200000" />
      <!-- 打开removeAbandoned功能 -->
      <property name="removeAbandoned" value="true" />
      <!-- 1800秒,也就是30分钟 -->
      <property name="removeAbandonedTimeout" value="1800" />
      <!-- 关闭abanded连接时输出错误日志 -->
      <property name="logAbandoned" value="true" />
      <property name="filters" value="stat" />
   </bean>

</beans>

增、删、改、查接口代码就不贴了。

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
        locations = { "classpath*:config/spring/spring-database.xml",
        "classpath*:config/spring/spring-sharding.xml" })
public class ShardingJdbcMybatisTest {

    @Resource
    public UserService userService;
    
    @Resource
    public StudentService studentService;

    @Test
    public void testUserInsert() {
        UserDO u = new UserDO();
        u.setUserId(9);
        u.setAge(25);
        u.setName("levon");
        Assert.assertEquals(userService.insert(u), true);
    }
    
    @Test
    public void testStudentInsert() {
        StudentDO StudentDO = new StudentDO();
        StudentDO.setStudentId(9);
        StudentDO.setAge(21);
        StudentDO.setName("hehe");
        Assert.assertEquals(studentService.insert(StudentDO), true);
    }

    @Test
    public void testFindAll(){
        List<UserDO> UserDOs = userService.findAll();
        if(null != UserDOs && !UserDOs.isEmpty()){
            for(UserDO u :UserDOs){
                System.out.println(u);
            }
        }
    }
    
    @Test
    public void testSQLIN(){
        List<UserDO> UserDOs = userService.findByUserIds(Arrays.asList(12,14,17));
        if(null != UserDOs && !UserDOs.isEmpty()){
            for(UserDO u :UserDOs){
                System.out.println(u);
            }
        }
    }
    
    @Test
    public void testTransactionTestSucess(){
        userService.transactionTestSucess();
    }
    
    @Test(expected = IllegalAccessException.class)
    public void testTransactionTestFailure() throws IllegalAccessException{
        userService.transactionTestFailure();
    }
    
    
}
原文地址:https://www.cnblogs.com/qiumingcheng/p/6725965.html