spring+mybatis+druid数据源+sharding-jdbc分库分表

首先我们看下如何让spring与mybatis集成,我使用的是mysql数据库,建库建表语句如下:

 
  1.  
    drop database if exists demodb00;
  2.  
    CREATE database demodb00 DEFAULT CHARACTER SET utf8;
  3.  
     
  4.  
    CREATE TABLE demodb00.user (
  5.  
    id int(11) NOT NULL AUTO_INCREMENT,
  6.  
    name varchar(100) DEFAULT NULL,
  7.  
    age int(11) DEFAULT NULL,
  8.  
    PRIMARY KEY (id),
  9.  
    UNIQUE KEY id_UNIQUE (id)
  10.  
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 

编写实体类UserEntity.java

 
  1.  
    package net.aty.spring.entity;
  2.  
     
  3.  
     
  4.  
    public class UserEntity {
  5.  
     
  6.  
    private int id;
  7.  
     
  8.  
    private String name;
  9.  
     
  10.  
    private int age;
  11.  
     
  12.  
    public UserEntity() {
  13.  
     
  14.  
    }
  15.  
     
  16.  
    public UserEntity(int id, String name, int age) {
  17.  
    this.id = id;
  18.  
    this.name = name;
  19.  
    this.age = age;
  20.  
    }
  21.  
     
  22.  
    public int getAge() {
  23.  
    return age;
  24.  
    }
  25.  
     
  26.  
    public void setAge(int age) {
  27.  
    this.age = age;
  28.  
    }
  29.  
     
  30.  
    public String getName() {
  31.  
     
  32.  
    return name;
  33.  
    }
  34.  
     
  35.  
    public void setName(String name) {
  36.  
    this.name = name;
  37.  
    }
  38.  
     
  39.  
     
  40.  
    public int getId() {
  41.  
    return id;
  42.  
    }
  43.  
     
  44.  
    public void setId(int id) {
  45.  
    this.id = id;
  46.  
    }
  47.  
     
  48.  
    @Override
  49.  
    public String toString() {
  50.  
    return "UserEntity{" +
  51.  
    "id=" + id +
  52.  
    ", name='" + name + '\'' +
  53.  
    ", age=" + age +
  54.  
    '}';
  55.  
    }
  56.  
    }
 

编写mapper类UserMapper.java

 
  1.  
    package net.aty.spring.mapper;
  2.  
     
  3.  
     
  4.  
    import net.aty.spring.entity.UserEntity;
  5.  
     
  6.  
    public interface UserMapper {
  7.  
     
  8.  
    int insertOne(UserEntity user);
  9.  
     
  10.  
    UserEntity selectByPk(int id);
  11.  
    }
 

编写mapper映射文件:UserMapper.xml

 
  1.  
    <?xml version="1.0" encoding="UTF-8" ?>
  2.  
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3.  
     
  4.  
    <mapper namespace="net.aty.spring.mapper.UserMapper">
  5.  
     
  6.  
    <insert id="insertOne" parameterType="net.aty.spring.entity.UserEntity">
  7.  
    INSERT INTO user(id, name,age) VALUE(#{id},#{name},#{age})
  8.  
    </insert>
  9.  
     
  10.  
    <select id="selectByPk" resultType="net.aty.spring.entity.UserEntity" parameterType="java.lang.Integer">
  11.  
    select * from user where id=#{id}
  12.  
    </select>
  13.  
     
  14.  
    </mapper>
 

编写mybatis配置文件:mybatis.xml

 
  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  3.  
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4.  
    <configuration>
  5.  
    <!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->
  6.  
    <settings>
  7.  
    <!-- 全局映射器启用缓存 -->
  8.  
    <setting name="cacheEnabled" value="true"/>
  9.  
    <!-- 查询时,关闭关联对象即时加载以提高性能 -->
  10.  
    <setting name="lazyLoadingEnabled" value="false"/>
  11.  
    <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
  12.  
    <setting name="aggressiveLazyLoading" value="true"/>
  13.  
    <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
  14.  
    <setting name="multipleResultSetsEnabled" value="true"/>
  15.  
    <!-- 允许使用列标签代替列名 -->
  16.  
    <setting name="useColumnLabel" value="true"/>
  17.  
    <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
  18.  
    <!-- <setting name="useGeneratedKeys" value="true" /> -->
  19.  
    <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
  20.  
    <setting name="autoMappingBehavior" value="FULL"/>
  21.  
    <!-- 对于批量更新操作缓存SQL以提高性能 -->
  22.  
    <setting name="defaultExecutorType" value="REUSE"/>
  23.  
    <!-- 数据库超过25000秒仍未响应则超时 -->
  24.  
    <setting name="defaultStatementTimeout" value="25000"/>
  25.  
     
  26.  
    </settings>
  27.  
     
  28.  
    </configuration>
 

配置druid数据源,以及整合mybatis的spring-mybatis.xml

 
  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <beans xmlns="http://www.springframework.org/schema/beans"
  3.  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  
    xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.  
    http://www.springframework.org/schema/beans/spring-beans.xsd">
  6.  
     
  7.  
    <!--配置数据源-->
  8.  
    <bean id="dataSourceResource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
  9.  
    destroy-method="close">
  10.  
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  11.  
    <property name="username" value="root"/>
  12.  
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/demodb00"/>
  13.  
    <property name="password" value="root"/>
  14.  
    <property name="maxActive" value="10"/>
  15.  
    <property name="initialSize" value="1"/>
  16.  
    <property name="maxWait" value="60000"/>
  17.  
    <property name="minIdle" value="1"/>
  18.  
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
  19.  
    <property name="minEvictableIdleTimeMillis" value="300000"/>
  20.  
    <property name="validationQuery" value="SELECT 'x'"/>
  21.  
    <property name="testWhileIdle" value="true"/>
  22.  
    <property name="testOnBorrow" value="false"/>
  23.  
    <property name="testOnReturn" value="false"/>
  24.  
    <property name="poolPreparedStatements" value="true"/>
  25.  
    <property name="maxPoolPreparedStatementPerConnectionSize" value="50"/>
  26.  
    <property name="maxOpenPreparedStatements" value="100"/>
  27.  
    <property name="proxyFilters">
  28.  
    <list>
  29.  
    <ref bean="statFilter"/>
  30.  
    <ref bean="logFilter"/>
  31.  
    </list>
  32.  
    </property>
  33.  
    </bean>
  34.  
     
  35.  
    <bean id="statFilter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">
  36.  
    <property name="statementExecutableSqlLogEnable" value="false"/>
  37.  
    <property name="dataSourceLogEnabled" value="false"/>
  38.  
    </bean>
  39.  
    <bean id="logFilter" class="com.alibaba.druid.filter.stat.StatFilter">
  40.  
    <property name="slowSqlMillis" value="50"/>
  41.  
    <property name="logSlowSql" value="false"/>
  42.  
    <property name="mergeSql" value="true"/>
  43.  
    </bean>
  44.  
     
  45.  
     
  46.  
     
  47.  
    <!--整合spring与mybatis-->
  48.  
     
  49.  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  50.  
    <property name="dataSource" ref="dataSourceResource"/>
  51.  
    <property name="configLocation" value="classpath:/META-INF/mybatis.xml"></property>
  52.  
    <property name="typeAliasesPackage" value="net.aty.spring.mybatis.entity"></property>
  53.  
    <property name="mapperLocations" value="classpath*:/META-INF/mybatis/*.xml"></property>
  54.  
    </bean>
  55.  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  56.  
    <property name="basePackage" value="net.aty.spring.mapper"></property>
  57.  
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
  58.  
    </bean>
  59.  
     
  60.  
    </beans>
 

编写测试代码,可以发现能够正常读取和修改数据库记录

 
  1.  
    package net.aty.spring;
  2.  
     
  3.  
    import net.aty.spring.entity.UserEntity;
  4.  
    import net.aty.spring.mapper.UserMapper;
  5.  
    import org.springframework.context.ApplicationContext;
  6.  
    import org.springframework.context.support.ClassPathXmlApplicationContext;
  7.  
     
  8.  
    public class Main {
  9.  
    public static void main(String[] args) {
  10.  
    ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring-mybatis.xml");
  11.  
     
  12.  
    UserMapper mapper = context.getBean(UserMapper.class);
  13.  
    mapper.insertOne(new UserEntity(1, "xx", 11));
  14.  
    mapper.insertOne(new UserEntity(2, "xxzzz", 11));
  15.  
     
  16.  
    System.out.println(mapper.selectByPk(1));
  17.  
    System.out.println(mapper.selectByPk(2));
  18.  
    }
  19.  
    }
 




上面我们完成了spring与mybatis的整合,随着业务的变化,数据越来越多,我们需要分库分表。我们项目使用的当当中间件:sharding-jdbc,github地址是:https://github.com/dangdangdotcom/sharding-jdbc。假设我们分为demodb00和demodb01这2个数据库,每个库分user_0和user_1这2张表。

sharding-jdbc.xml配置如下:

 
  1.  
    <?xml version="1.0" encoding="UTF-8"?>
  2.  
    <beans xmlns="http://www.springframework.org/schema/beans"
  3.  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.  
    xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb"
  5.  
    xsi:schemaLocation="http://www.springframework.org/schema/beans
  6.  
    http://www.springframework.org/schema/beans/spring-beans.xsd
  7.  
    http://www.dangdang.com/schema/ddframe/rdb
  8.  
    http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd">
  9.  
     
  10.  
    <bean id="statFilter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">
  11.  
    <property name="statementExecutableSqlLogEnable" value="false"/>
  12.  
    <property name="dataSourceLogEnabled" value="false"/>
  13.  
    </bean>
  14.  
    <bean id="logFilter" class="com.alibaba.druid.filter.stat.StatFilter">
  15.  
    <property name="slowSqlMillis" value="50"/>
  16.  
    <property name="logSlowSql" value="false"/>
  17.  
    <property name="mergeSql" value="true"/>
  18.  
    </bean>
  19.  
     
  20.  
    <bean id="master0" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
  21.  
    destroy-method="close">
  22.  
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  23.  
    <property name="username" value="root"/>
  24.  
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/demodb00"/>
  25.  
    <property name="password" value="root"/>
  26.  
    <property name="maxActive" value="10"/>
  27.  
    <property name="initialSize" value="1"/>
  28.  
    <property name="maxWait" value="60000"/>
  29.  
    <property name="minIdle" value="1"/>
  30.  
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
  31.  
    <property name="minEvictableIdleTimeMillis" value="300000"/>
  32.  
    <property name="validationQuery" value="SELECT 'x'"/>
  33.  
    <property name="testWhileIdle" value="true"/>
  34.  
    <property name="testOnBorrow" value="false"/>
  35.  
    <property name="testOnReturn" value="false"/>
  36.  
    <property name="poolPreparedStatements" value="true"/>
  37.  
    <property name="maxPoolPreparedStatementPerConnectionSize" value="50"/>
  38.  
    <property name="maxOpenPreparedStatements" value="100"/>
  39.  
    <property name="proxyFilters">
  40.  
    <list>
  41.  
    <ref bean="statFilter"/>
  42.  
    <ref bean="logFilter"/>
  43.  
    </list>
  44.  
    </property>
  45.  
    </bean>
  46.  
     
  47.  
    <bean id="master1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
  48.  
    destroy-method="close">
  49.  
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
  50.  
    <property name="username" value="root"/>
  51.  
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/demodb01"/>
  52.  
    <property name="password" value="root"/>
  53.  
    <property name="maxActive" value="10"/>
  54.  
    <property name="initialSize" value="1"/>
  55.  
    <property name="maxWait" value="60000"/>
  56.  
    <property name="minIdle" value="1"/>
  57.  
    <property name="timeBetweenEvictionRunsMillis" value="60000"/>
  58.  
    <property name="minEvictableIdleTimeMillis" value="300000"/>
  59.  
    <property name="validationQuery" value="SELECT 'x'"/>
  60.  
    <property name="testWhileIdle" value="true"/>
  61.  
    <property name="testOnBorrow" value="false"/>
  62.  
    <property name="testOnReturn" value="false"/>
  63.  
    <property name="poolPreparedStatements" value="true"/>
  64.  
    <property name="maxPoolPreparedStatementPerConnectionSize" value="50"/>
  65.  
    <property name="maxOpenPreparedStatements" value="100"/>
  66.  
    <property name="proxyFilters">
  67.  
    <list>
  68.  
    <ref bean="statFilter"/>
  69.  
    <ref bean="logFilter"/>
  70.  
    </list>
  71.  
    </property>
  72.  
    </bean>
  73.  
     
  74.  
    <rdb:master-slave-data-source id="rbb_0" master-data-source-ref="master0" slave-data-sources-ref="master0"/>
  75.  
    <rdb:master-slave-data-source id="rbb_1" master-data-source-ref="master1" slave-data-sources-ref="master1"/>
  76.  
     
  77.  
    <rdb:strategy id="idDbSharding" sharding-columns="id"
  78.  
    algorithm-class="net.aty.spring.DbAlgorithm"/>
  79.  
     
  80.  
    <rdb:strategy id="idTbSharding" sharding-columns="id"
  81.  
    algorithm-class="net.aty.spring.TbAlgorithm"/>
  82.  
     
  83.  
    <rdb:data-source id="wholeDataSource">
  84.  
    <rdb:sharding-rule data-sources="rbb_0,rbb_1">
  85.  
    <rdb:table-rules>
  86.  
    <rdb:table-rule logic-table="user" actual-tables="user_${0..1}"
  87.  
    database-strategy="idDbSharding" table-strategy="idTbSharding"/>
  88.  
    </rdb:table-rules>
  89.  
    </rdb:sharding-rule>
  90.  
    </rdb:data-source>
  91.  
     
  92.  
    </beans>
 


这个文件中定义了2个库的数据源,以及我们的分库分表规则,我是按照id分库分表的:

 
  1.  
    import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
  2.  
    import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
  3.  
     
  4.  
    import java.util.Collection;
  5.  
     
  6.  
    public class DbAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Integer> {
  7.  
     
  8.  
    @Override
  9.  
    public String doEqualSharding(Collection<String> collection, ShardingValue<Integer> shardingValue) {
  10.  
    int id = shardingValue.getValue();
  11.  
     
  12.  
    int index = id % 2;
  13.  
     
  14.  
    for (String each : collection) {
  15.  
    if (each.endsWith(index + "")) {
  16.  
    return each;
  17.  
    }
  18.  
    }
  19.  
    throw new UnsupportedOperationException();
  20.  
    }
  21.  
     
  22.  
    @Override
  23.  
    public Collection<String> doInSharding(Collection<String> collection, ShardingValue<Integer> shardingValue) {
  24.  
    return null;
  25.  
    }
  26.  
     
  27.  
    @Override
  28.  
    public Collection<String> doBetweenSharding(Collection<String> collection, ShardingValue<Integer> shardingValue) {
  29.  
    return null;
  30.  
    }
  31.  
    }
 
 
  1.  
    import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
  2.  
    import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
  3.  
     
  4.  
    import java.util.Collection;
  5.  
     
  6.  
    public class TbAlgorithm implements SingleKeyTableShardingAlgorithm<Integer> {
  7.  
     
  8.  
     
  9.  
    @Override
  10.  
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
  11.  
    int id = shardingValue.getValue();
  12.  
     
  13.  
    int index = id % 2;
  14.  
     
  15.  
    for (String each : availableTargetNames) {
  16.  
    if (each.endsWith(index + "")) {
  17.  
    return each;
  18.  
    }
  19.  
    }
  20.  
    throw new UnsupportedOperationException();
  21.  
    }
  22.  
     
  23.  
    @Override
  24.  
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
  25.  
    return null;
  26.  
    }
  27.  
     
  28.  
    @Override
  29.  
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {
  30.  
    return null;
  31.  
    }
  32.  
    }
 

接下来我们只需要修改上面的spring-mybatis.xml,就可以使用分库分表了,不需要改动已有的代码。可以看到只需要修改数据源,就可以完成sharding-jdbc与mybatis、spring的集成,非常方便。

 

修改了这个数据源后,直接运行上面的测试代码,可以看到分库分表生效了。id=1的记录插入了rbb_1这个数据源,user_1这张表;id=2的记录插入了rbb_0这个数据源,user_0这张表。


至此就完成了spring与mybatis以及sharding-jdbc分库分表的集成,最后给出项目使用的pom配置:

 
  1.  
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.  
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3.  
    <modelVersion>4.0.0</modelVersion>
  4.  
    <groupId>net.aty.mybatis</groupId>
  5.  
    <artifactId>mybatis-demo</artifactId>
  6.  
    <packaging>jar</packaging>
  7.  
    <version>1.0-SNAPSHOT</version>
  8.  
    <name>mybatis-demo</name>
  9.  
    <url>http://maven.apache.org</url>
  10.  
     
  11.  
    <properties>
  12.  
    <spring.version>4.3.3.RELEASE</spring.version>
  13.  
    </properties>
  14.  
    <dependencies>
  15.  
    <dependency>
  16.  
    <groupId>org.slf4j</groupId>
  17.  
    <artifactId>slf4j-log4j12</artifactId>
  18.  
    <version>1.7.21</version>
  19.  
    </dependency>
  20.  
     
  21.  
    <dependency>
  22.  
    <groupId>log4j</groupId>
  23.  
    <artifactId>log4j</artifactId>
  24.  
    <version>1.2.17</version>
  25.  
    </dependency>
  26.  
    <dependency>
  27.  
    <groupId>org.mybatis</groupId>
  28.  
    <artifactId>mybatis</artifactId>
  29.  
    <version>3.4.1</version>
  30.  
    </dependency>
  31.  
    <dependency>
  32.  
    <groupId>mysql</groupId>
  33.  
    <artifactId>mysql-connector-java</artifactId>
  34.  
    <version>5.1.26</version>
  35.  
    </dependency>
  36.  
     
  37.  
    <dependency>
  38.  
    <groupId>com.alibaba</groupId>
  39.  
    <artifactId>druid</artifactId>
  40.  
    <version>1.0.26</version>
  41.  
    </dependency>
  42.  
     
  43.  
     
  44.  
    <dependency>
  45.  
    <groupId>org.mybatis</groupId>
  46.  
    <artifactId>mybatis-spring</artifactId>
  47.  
    <version>1.3.0</version>
  48.  
    </dependency>
  49.  
     
  50.  
     
  51.  
    <dependency>
  52.  
    <groupId>com.dangdang</groupId>
  53.  
    <artifactId>sharding-jdbc-core</artifactId>
  54.  
    <version>1.3.3</version>
  55.  
    </dependency>
  56.  
    <dependency>
  57.  
    <groupId>com.dangdang</groupId>
  58.  
    <artifactId>sharding-jdbc-config-spring</artifactId>
  59.  
    <version>1.3.3</version>
  60.  
    </dependency>
  61.  
     
  62.  
     
  63.  
    <dependency>
  64.  
    <groupId>org.springframework</groupId>
  65.  
    <artifactId>spring-jdbc</artifactId>
  66.  
    <version>${spring.version}</version>
  67.  
    </dependency>
  68.  
    <dependency>
  69.  
    <groupId>org.springframework</groupId>
  70.  
    <artifactId>spring-context</artifactId>
  71.  
    <version>${spring.version}</version>
  72.  
    </dependency>
  73.  
     
  74.  
    </dependencies>
  75.  
     
  76.  
    <build>
  77.  
    <plugins>
  78.  
    <plugin>
  79.  
    <groupId>org.apache.maven.plugins</groupId>
  80.  
    <artifactId>maven-compiler-plugin</artifactId>
  81.  
    <version>2.5.1</version>
  82.  
    <configuration>
  83.  
    <encoding>UTF-8</encoding>
  84.  
    <source>1.8</source>
  85.  
    <target>1.8</target>
  86.  
    </configuration>
  87.  
    </plugin>
  88.  
    </plugins>
  89.  
    </build>
  90.  
     
  91.  
    </project>
 

猜你喜欢

转载自blog.csdn.net/wjq008/article/details/81315528
今日推荐