• 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
  • 相关阅读:
    微信小程序创建第一个项目
    微信小程序工具下载与安装
    Windows下删除顽固文件夹
    微信小程序账号注册
    C++第四十九篇 -- 将一个项目Copy到另一台电脑
    C++第四十八篇 -- 字符串分离方法
    C++第四十七篇 -- VS2017带参数启动调试程序
    MarkDown插入图片
    Http升级到Https (本地测试,无须域名和认证)
    语音识别(ASR) 阿里云
  • 原文地址:https://www.cnblogs.com/handsome1013/p/7463505.html
Copyright © 2020-2023  润新知