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

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

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

[sql] view plain copy
 
  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
[java] view plain copy
 
  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
[java] view plain copy
 
  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
[html] view plain copy
 
  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
[html] view plain copy
 
  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
[html] view plain copy
 
  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>  

 

 

编写测试代码,可以发现能够正常读取和修改数据库记录
[java] view plain copy
 
  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配置如下:

[html] view plain copy
 
  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分库分表的:
[java] view plain copy
 
  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. }  
[java] view plain copy
 
  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配置:

[html] view plain copy
 
  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>  

 

 

 
1
posted @ 2017-09-01 15:36  wjj1013  阅读(2047)  评论(0编辑  收藏  举报