转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79368021

一、概述

之前,我们介绍了利用Mycat进行分库分表操作,Mycat分表操作是利用分库来进行的,单个库中的分表操作可结合MySQL的分区进行,这也是Mycat官方提倡的方式。那么,如何利用Mycat真正实现数据库的分库分表,可以私信我。今天,我们来看看sharding-jdbc,sharding-jdbc也是一款分库分表的“中间件”,不过,它并不向Mycat那样作为一个真正的中间件,它是一款以jar包的形式整合到业务中的插件,这就决定了它是轻量级的,用法也是十分简单的。

二、分库分表实战

接下来,我们就利用sharding-jdbc进行数据库的分库分表操作。

1、创建数据库

首先我们创建相应的数据库

create database sharding_0;
create database sharding_1;

这样我们就创建了两个数据库sharding_0和sharding_1;

接下来我们在两个库中创建相应的数据表,在两个库中分别进行如下SQL:

SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for t_student_00
-- ----------------------------
DROP TABLE IF EXISTS `t_student_00`;
CREATE TABLE `t_student_00` (`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;-- ----------------------------
-- Table structure for t_student_01
-- ----------------------------
DROP TABLE IF EXISTS `t_student_01`;
CREATE TABLE `t_student_01` (`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 AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_user_00
-- ----------------------------
DROP TABLE IF EXISTS `t_user_00`;
CREATE TABLE `t_user_00` (`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;-- ----------------------------
-- Table structure for t_user_01
-- ----------------------------
DROP TABLE IF EXISTS `t_user_01`;
CREATE TABLE `t_user_01` (`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 AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;-- ----------------------------
-- Table structure for t_user_02
-- ----------------------------
DROP TABLE IF EXISTS `t_user_02`;
CREATE TABLE `t_user_02` (`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 AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

这样,我们的数据库就准备好了。

2、创建项目

接下来,我们就创建一个Maven项目,项目结构如下:

3、配置pom.xml

<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.lyz</groupId>  <artifactId>sharding-jdbc-mybatis</artifactId>  <version>0.0.1-SNAPSHOT</version>  <packaging>jar</packaging>  <name>sharding-jdbc-mybatis</name>  <url>http://maven.apache.org</url>  <properties>  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  <spring.version>4.1.0.RELEASE</spring.version><mybatis.version>3.2.4</mybatis.version>  </properties>  <dependencies>  <dependency>  <groupId>junit</groupId>  <artifactId>junit</artifactId>  <version>4.10</version>  </dependency>  <dependency>  <groupId>com.dangdang</groupId>  <artifactId>sharding-jdbc-core</artifactId>  <version>1.0.0</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>  </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>  <dependency>  <groupId>log4j</groupId>  <artifactId>log4j</artifactId>  <version>1.2.16</version>  </dependency>  <dependency>  <groupId>org.slf4j</groupId>  <artifactId>slf4j-log4j12</artifactId>  <version>1.7.5</version>  </dependency>  </dependencies>
</project>  

4、创建数据库映射类

这里,我们创建两个数据库映射类:User类和Student类。

4-1、User类

package com.lyz.sharding.entity;import java.io.Serializable;/*** 用户类* @author liuyazhuang**/
public class User implements Serializable {private static final long serialVersionUID = 1L;private Integer id;private Integer userId;private String name;private Integer age;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getUserId() {return userId;}public void setUserId(Integer userId) {this.userId = userId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User [id=" + id + ", userId=" + userId + ", name=" + name + ", age=" + age + "]";}}

4-2、Student类

package com.lyz.sharding.entity;import java.io.Serializable;/*** 学生类* @author liuyazhuang**/
public class Student implements Serializable {private static final long serialVersionUID = 8920597824668331209L;private Integer id;private Integer studentId;private String name;private Integer age;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getStudentId() {return studentId;}public void setStudentId(Integer studentId) {this.studentId = studentId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student [id=" + id + ", studentId=" + studentId + ", name=" + name + ", age=" + age + "]";}}

5、创建Mapper类

5-1、UserMapper类

package com.lyz.sharding.mapper;import java.util.List;
import com.lyz.sharding.entity.User;  /*** 处理用户的数据操作接口* @author liuyazhuang**/
public interface UserMapper {  Integer insert(User u);  List<User> findAll();  List<User> findByUserIds(List<Integer> userIds);  }  

5-2、StudentMapper类

package com.lyz.sharding.mapper;import java.util.List;
import com.lyz.sharding.entity.Student;/*** 处理学生的数据操作接口* @author liuyazhuang**/
public interface StudentMapper {  Integer insert(Student s);  List<Student> findAll();  List<Student> findByStudentIds(List<Integer> studentIds);  }  

6、创建service类

6-1、UserService类

package com.lyz.sharding.service;  import java.util.List;
import com.lyz.sharding.entity.User;/*** 处理用户的Service* @author liuyazhuang**/
public interface UserService {  public boolean insert(User u);  public List<User> findAll();  public List<User> findByUserIds(List<Integer> ids);  public void transactionTestSucess();  public void transactionTestFailure() throws IllegalAccessException;  }  

6-2、StudentService类

package com.lyz.sharding.service;import com.lyz.sharding.entity.Student;/*** 处理学生的service* @author liuyazhuang**/
public interface StudentService {  boolean insert(Student student);  }  

7、创建service的实现类

7-1、UserServiceImpl类

package com.lyz.sharding.service.impl;import java.util.List;import javax.annotation.Resource;import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import com.lyz.sharding.entity.Student;
import com.lyz.sharding.entity.User;
import com.lyz.sharding.mapper.StudentMapper;
import com.lyz.sharding.mapper.UserMapper;
import com.lyz.sharding.service.UserService; @Service
@Transactional
public class UserServiceImpl implements UserService {  @Resource  public UserMapper userMapper;  @Resource  public StudentMapper studentMapper;  public boolean insert(User u) {  return userMapper.insert(u) > 0 ? true :false;  }  public List<User> findAll() {  return userMapper.findAll();  }  public List<User> findByUserIds(List<Integer> ids) {  return userMapper.findByUserIds(ids);  }  @Transactional(propagation=Propagation.REQUIRED)  public void transactionTestSucess() {  User u = new User();  u.setUserId(13);  u.setAge(25);  u.setName("war3 1.27");  userMapper.insert(u);  Student student = new Student();  student.setStudentId(21);  student.setAge(21);  student.setName("hehe");  studentMapper.insert(student);  }  @Transactional(propagation=Propagation.REQUIRED)  public void transactionTestFailure() throws IllegalAccessException {  User u = new User();  u.setUserId(13);  u.setAge(25);  u.setName("war3 1.27 good");  userMapper.insert(u);  Student student = new Student();  student.setStudentId(21);  student.setAge(21);  student.setName("hehe1");  studentMapper.insert(student);  throw new IllegalAccessException();  }  }  

7-2、StudentServiceImpl类

package com.lyz.sharding.service.impl;
import javax.annotation.Resource;import org.springframework.stereotype.Service;import com.lyz.sharding.entity.Student;
import com.lyz.sharding.mapper.StudentMapper;
import com.lyz.sharding.service.StudentService;@Service
public class StudentServiceImpl implements StudentService{  @Resource  public StudentMapper studentMapper;  public boolean insert(Student student) {  return studentMapper.insert(student) > 0 ? true : false;  }  }  

8、创建分库逻辑

8-1、User分库逻辑UserSingleKeyDatabaseShardingAlgorithm类

package com.lyz.sharding.algorithm;  import java.util.Collection;
import java.util.LinkedHashSet;  import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;  /** * user表分库的逻辑函数 * @author liuyazhuang* */
public class UserSingleKeyDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Integer>{  /** * sql 中关键字 匹配符为 =的时候,表的路由函数 */  public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {  for (String each : availableTargetNames) {  if (each.endsWith(shardingValue.getValue() % 2 + "")) {  return each;  }  }  throw new IllegalArgumentException();  }  /** * sql 中关键字 匹配符为 in 的时候,表的路由函数 */  public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(availableTargetNames.size());  for (Integer value : shardingValue.getValues()) {  for (String tableName : availableTargetNames) {  if (tableName.endsWith(value % 2 + "")) {  result.add(tableName);  }  }  }  return result;  }  /** * sql 中关键字 匹配符为 between的时候,表的路由函数 */  public Collection<String> doBetweenSharding(Collection<String> availableTargetNames,  ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(availableTargetNames.size());  Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();  for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {  for (String each : availableTargetNames) {  if (each.endsWith(i % 2 + "")) {  result.add(each);  }  }  }  return result;  }  }  

8-2、Student分库逻辑StudentSingleKeyDatabaseShardingAlgorithm

package com.lyz.sharding.algorithm;
import java.util.Collection;
import java.util.LinkedHashSet;  import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;  /** * user表分库的逻辑函数 * @author liuyazhuang * */
public class StudentSingleKeyDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Integer>{  /** * sql 中关键字 匹配符为 =的时候,表的路由函数 */  @Overridepublic String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {  for (String each : availableTargetNames) {  if (each.endsWith(shardingValue.getValue() % 2 + "")) {  return each;  }  }  throw new IllegalArgumentException();  }  /** * sql 中关键字 匹配符为 in 的时候,表的路由函数 */@Overridepublic Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(availableTargetNames.size());  for (Integer value : shardingValue.getValues()) {  for (String tableName : availableTargetNames) {  if (tableName.endsWith(value % 2 + "")) {  result.add(tableName);  }  }  }  return result;  }  /** * sql 中关键字 匹配符为 between的时候,表的路由函数 */  @Overridepublic Collection<String> doBetweenSharding(Collection<String> availableTargetNames,  ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(availableTargetNames.size());  Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();  for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {  for (String each : availableTargetNames) {  if (each.endsWith(i % 2 + "")) {  result.add(each);  }  }  }  return result;  }  }  

9、创建分表逻辑

9-1、User分表逻辑UserSingleKeyTableShardingAlgorithm

package com.lyz.sharding.algorithm;  import java.util.Collection;
import java.util.LinkedHashSet;  import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
/** * 因为t_student实际表在每个库中只有3个,所以 %3 * @author iuyazhuang* */
public class UserSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Integer>{  /** * sql 中 = 操作时,table的映射 */  public String doEqualSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {  for (String each : tableNames) {  if (each.endsWith(("0".concat(String.valueOf(shardingValue.getValue() % 3))))) {  return each;  }  }  throw new IllegalArgumentException();  }  /** * sql 中 in 操作时,table的映射 */  public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(tableNames.size());  for (Integer value : shardingValue.getValues()) {  for (String tableName : tableNames) {  if (tableName.endsWith(("0".concat(String.valueOf(value % 3))))) {  result.add(tableName);  }  }  }  return result;  }  /** * sql 中 between 操作时,table的映射 */  public Collection<String> doBetweenSharding(Collection<String> tableNames,  ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(tableNames.size());  Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();  for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {  for (String each : tableNames) {  if (each.endsWith(("0".concat(String.valueOf(i % 3))))) {  result.add(each);  }  }  }  return result;  }  }  

9-2、创建Student分表逻辑StudentSingleKeyTableShardingAlgorithm

package com.lyz.sharding.algorithm;import java.util.Collection;
import java.util.LinkedHashSet;  import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;  /** * 因为t_student实际表在每个库中只有2个,所以 %2 * @author iuyazhuang* */
public class StudentSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Integer>{  /** * sql 中 = 操作时,table的映射 */  public String doEqualSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {  for (String each : tableNames) {  if (each.endsWith("0".concat(String.valueOf(shardingValue.getValue() % 2)))) {  return each;  }  }  throw new IllegalArgumentException();  }  /** * sql 中 in 操作时,table的映射 */  public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(tableNames.size());  for (Integer value : shardingValue.getValues()) {  for (String tableName : tableNames) {  if (tableName.endsWith("0".concat(String.valueOf(value % 2)))) {  result.add(tableName);  }  }  }  return result;  }  /** * sql 中 between 操作时,table的映射 */  public Collection<String> doBetweenSharding(Collection<String> tableNames,  ShardingValue<Integer> shardingValue) {  Collection<String> result = new LinkedHashSet<String>(tableNames.size());  Range<Integer> range = (Range<Integer>) shardingValue.getValueRange();  for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {  for (String each : tableNames) {  if (each.endsWith("0".concat(String.valueOf(i % 2)))) {  result.add(each);  }  }  }  return result;  }  }  

10、创建Mapper.xml

10-1、创建UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lyz.sharding.mapper.UserMapper" >  <resultMap id="resultMap" type="com.lyz.sharding.entity.User" >  <id column="id" property="id" jdbcType="INTEGER" />  <result column="user_id" property="userId" jdbcType="INTEGER" />  <result column="name" property="name" jdbcType="VARCHAR" />  <result column="age" property="age" jdbcType="INTEGER" />  </resultMap>  <insert id="insert">  insert into t_user (user_id,name,age) values (#{userId},#{name},#{age})  </insert>  <select id="findAll" resultMap="resultMap">  select <include refid="columnsName"/> from t_user   </select>  <select id="findByUserIds" resultMap="resultMap">  select <include refid="columnsName"/> from t_user where user_id in (  <foreach collection="list" item="item" separator=",">  #{item}  </foreach>  )  </select>  <sql id="columnsName">  id,user_id,name,age  </sql>
</mapper>  

10-2、创建StudentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.lyz.sharding.mapper.StudentMapper" >  <resultMap id="resultMap" type="com.lyz.sharding.entity.Student" >  <id column="id" property="id" jdbcType="INTEGER" />  <result column="student_id" property="studentId" jdbcType="INTEGER" />  <result column="name" property="name" jdbcType="VARCHAR" />  <result column="age" property="age" jdbcType="INTEGER" />  </resultMap>  <insert id="insert">  insert into t_student (student_id,name,age) values (#{studentId},#{name},#{age})  </insert>  <select id="findAll" resultMap="resultMap">  select <include refid="columnsName"/> from t_student  </select>  <select id="findByStudentIds" resultMap="resultMap">  select <include refid="columnsName"/> from t_student where student_id in (  <foreach collection="list" item="item" separator=",">  #{item}  </foreach>  )  </select>  <sql id="columnsName">  id,student_id,name,age  </sql>
</mapper>  

11、创建jdbc_dev.properties

jdbc_driver0   = com.mysql.jdbc.Driver
jdbc_url0      = jdbc:mysql://localhost:3306/sharding_0?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc_username0 = root
jdbc_password0 = rootjdbc_driver1   = com.mysql.jdbc.Driver
jdbc_url1      = jdbc:mysql://localhost:3306/sharding_1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc_username1 = root
jdbc_password1 = rootvalidationQuery=SELECT 1

12、创建spring配置文件

12-1、spring-database.xml

<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"  xmlns:tx="http://www.springframework.org/schema/tx"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  <property name="locations">  <list>  <value>classpath:config/resource/jdbc_dev.properties</value>  </list>  </property>  </bean>  <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="driverClass" value="${jdbc_driver0}" /> -->  <!-- 初始化连接大小 -->  <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="driverClass" value="${jdbc_driver1}" /> -->  <!-- 初始化连接大小 -->  <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>  

12-2、spring-sharding.xml

<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"  xmlns:tx="http://www.springframework.org/schema/tx"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">  <context:component-scan base-package="com.lyz.sharding" /> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  <property name="basePackage" value="com.lyz.sharding.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>  <!-- 配置好dataSourceRulue,即对数据源进行管理 -->  <bean id="dataSourceRule" class="com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule">  <constructor-arg>  <map>  <entry key="sharding_0" value-ref="sharding_0"/>  <entry key="sharding_1" value-ref="sharding_1"/>  </map>  </constructor-arg>  </bean>  <!-- 对t_user表的配置,进行分库配置,逻辑表名为t_user,每个库有实际的三张表 -->  <bean id="userTableRule" class="com.dangdang.ddframe.rdb.sharding.api.rule.TableRule">  <constructor-arg value="t_user" index="0"/>  <constructor-arg index="1">  <list>  <value>t_user_00</value>  <value>t_user_01</value>  <value>t_user_02</value>  </list>  </constructor-arg>  <constructor-arg index="2" ref="dataSourceRule"/>  <constructor-arg index="3" ref="userDatabaseShardingStrategy"/>  <constructor-arg index="4" ref="userTableShardingStrategy"/>  </bean>  <!-- t_user分库策略 -->  <bean id="userDatabaseShardingStrategy" class="com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy">  <constructor-arg index="0" value="user_id"/>  <constructor-arg index="1">  <bean class="com.lyz.sharding.algorithm.UserSingleKeyDatabaseShardingAlgorithm" />  </constructor-arg>  </bean>  <!-- t_user 分表策略 -->  <bean id="userTableShardingStrategy" class="com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy">  <constructor-arg index="0" value="user_id"/>  <constructor-arg index="1">  <bean class="com.lyz.sharding.algorithm.UserSingleKeyTableShardingAlgorithm" />  </constructor-arg>  </bean>  <!-- 对t_student表的配置,进行分库配置,逻辑表名为t_student,每个库有实际的三张表 -->  <bean id="studentTableRule" class="com.dangdang.ddframe.rdb.sharding.api.rule.TableRule">  <constructor-arg value="t_student" index="0"/>  <constructor-arg index="1">  <list>  <value>t_student_00</value>  <value>t_student_01</value>  </list>  </constructor-arg>  <constructor-arg index="2" ref="dataSourceRule"/>  <constructor-arg index="3" ref="studentDatabaseShardingStrategy"/>  <constructor-arg index="4" ref="studentTableShardingStrategy"/>  </bean>  <!-- t_student分库策略 -->  <bean id="studentDatabaseShardingStrategy" class="com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy">  <constructor-arg index="0" value="student_id"/>  <constructor-arg index="1">  <bean class="com.lyz.sharding.algorithm.StudentSingleKeyDatabaseShardingAlgorithm" />  </constructor-arg>  </bean>  <!-- t_student 分表策略 -->  <bean id="studentTableShardingStrategy" class="com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy">  <constructor-arg index="0" value="student_id"/>  <constructor-arg index="1">  <bean class="com.lyz.sharding.algorithm.StudentSingleKeyTableShardingAlgorithm" />  </constructor-arg>  </bean>  <!-- 构成分库分表的规则 传入数据源集合和每个表的分库分表的具体规则 -->  <bean id="shardingRule" class="com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule">  <constructor-arg index="0" ref="dataSourceRule"/>  <constructor-arg index="1">  <list>  <ref bean="userTableRule"/>  <ref bean="studentTableRule"/>  </list>  </constructor-arg>  </bean>  <!-- 对datasource进行封装 -->  <bean id="shardingDataSource" class="com.dangdang.ddframe.rdb.sharding.api.ShardingDataSource">  <constructor-arg ref="shardingRule"/>  </bean>  <!-- 事务 -->  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  <property name="dataSource" ref="shardingDataSource" />  </bean>  <tx:annotation-driven transaction-manager="transactionManager" />  </beans>  

13、创建log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">    <!-- [控制台STDOUT] -->    <appender name="console" class="org.apache.log4j.ConsoleAppender">    <param name="encoding" value="GBK" />    <param name="target" value="System.out" />    <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%-5p %c{2} - %m%n" />    </layout>    </appender>    <!-- [公共Appender] -->    <appender name="DEFAULT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">    <param name="File" value="logs/common-default.log" />    <param name="Append" value="true" />    <param name="encoding" value="GBK" />    <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />    <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />    </layout>    </appender>    <!-- [错误日志APPENDER] -->    <appender name="ERROR-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">    <param name="File" value="logs/common-error.log" />    <param name="Append" value="true" />    <param name="encoding" value="GBK" />    <param name="threshold" value="error" />    <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />    <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />    </layout>    </appender>    <!-- [组件日志APPENDER] -->    <appender name="COMPONENT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">    <param name="File" value="logs/logistics-component.log" />    <param name="Append" value="true" />    <param name="encoding" value="GBK" />    <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" />    <layout class="org.apache.log4j.PatternLayout">    <param name="ConversionPattern" value="%d %-5p %c{2} - %m%n" />    </layout>    </appender>    <!-- [组件日志] -->    <logger name="LOGISTICS-COMPONENT">    <level value="${loggingLevel}" />    <appender-ref ref="COMPONENT-APPENDER" />    <appender-ref ref="ERROR-APPENDER" />    </logger>    <!-- Root Logger -->    <root>    <level value="${rootLevel}"></level>    <appender-ref ref="DEFAULT-APPENDER" />    <appender-ref ref="ERROR-APPENDER" />    <appender-ref ref="console" />   <appender-ref ref="COMPONENT-APPENDER" />   </root>
</log4j:configuration>    

14、创建测试类ShardingJdbcMybatisTest

package com.lyz.sharding.test;  import java.util.Arrays;
import java.util.List;import javax.annotation.Resource;import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import com.lyz.sharding.entity.Student;
import com.lyz.sharding.entity.User;
import com.lyz.sharding.service.StudentService;
import com.lyz.sharding.service.UserService;/*** 测试分库分表规则* @author liuyazhuang**/
@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() {  User u = new User();  u.setUserId(11);  u.setAge(25);  u.setName("github");  Assert.assertEquals(userService.insert(u), true);  }  @Test  public void testStudentInsert() {  Student student = new Student();  student.setStudentId(21);  student.setAge(21);  student.setName("hehe");  Assert.assertEquals(studentService.insert(student), true);  }  @Test  public void testFindAll(){  List<User> users = userService.findAll();  if(null != users && !users.isEmpty()){  for(User u :users){  System.out.println(u);  }  }  }  @Test  public void testSQLIN(){  List<User> users = userService.findByUserIds(Arrays.asList(1));  if(null != users && !users.isEmpty()){  for(User u :users){  System.out.println(u);  }  }  }  @Test  public void testTransactionTestSucess(){  userService.transactionTestSucess();  }  @Test(expected = IllegalAccessException.class)  public void testTransactionTestFailure() throws IllegalAccessException{  userService.transactionTestFailure();  }
}  

三、测试

我们进行ShardingJdbcMybatisTest类,查看数据表数据,即可看到我们的程序利用sharding-jdbc实现了分库分表操作。

四、温馨提示

大家可以到链接http://download.csdn.net/download/l1028386804/10258290下载完整的sharding-jdbc分库分表实例源代码

sharding-jdbc之——分库分表实例相关推荐

  1. Sharding Sphere ~ Sharding-jdbc分库分表、读写分离

    Sharding Sphere 是什么? 1.一套开源的分布式数据库中间件解决方案 2.有三个产品:Sharding-JDBC 和 Sharding-Proxy 3.定位为关系型数据库中间件,合理在分 ...

  2. sharding jdbc根据年月分表

    1.配置Maven依赖 <!--shardingsphere分表策略--> <dependency><groupId>io.shardingsphere</g ...

  3. sharding-jdbc4.1.1 分库分表后 mysql查询优化(count)

    sharding jdbc分库分表之后查询优化 背景 需求 研发历程 1.单线程(sharding jdbc 内置查询机制) 2.多线程(sharding jdbc 内置查询机制) 3.sql调整 结 ...

  4. 数据库读写分离与分库分表

    3.1 读写分离(主要是为了数据库读能力的水平扩展) 3.1.1 读写分离概念 单台mysql实例情况下不能支持短时间内大量的对数据库的读操作,所以会将数据库配置成集群,一个master(主库).多个 ...

  5. 【数据库与事务系列】分库分表中间件

    前面讲了利用mybatis插件进行多数据源切换和分表的方案,但是对业务侵入性较强,当然给予mybatis-plus的对业务侵入性还好,但是支持的策略有限.场景有限. 所以业界诞生了很多分库分表中间件来 ...

  6. 亿级流量网站架构核心技术之“数据库分库分表策略”

    本文节选自<亿级流量网站架构核心技术--跟开涛学搭建高可用高并发系统>一书 张开涛 著 电子工业出版社出版 小编会从留言中选择获赞最多的前五名用户免费送出此书哦!规则见文末. 数据库分库分 ...

  7. 一文读懂分库分表的技术演进(最佳实践)

    每个优秀的程序员和架构师都应该掌握分库分表,这是我的观点. 移动互联网时代,海量的用户每天产生海量的数据,比如: 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张, ...

  8. 海量数据的分库分表技术演进,最佳实践

    每个优秀的程序员和架构师都应该掌握分库分表,移动互联网时代,海量的用户每天产生海量的数量 用户表 订单表 交易流水表 以支付宝用户为例,8亿:微信用户更是10亿.订单表更夸张,比如美团外卖,每天都是几 ...

  9. mycat分库分表demo

    关于Mycat,它是一个阿里的开源项目,用来解决分库分表的海量数据存储和查询优化,关于它的简介,可以直接参考介绍:Mycat简介. 下面对自己的demo做个记录: 我之前从192.168.68.3克隆 ...

最新文章

  1. windows优化大师8周年纪念版_《数码宝贝》20周年纪念:当年的八神太一与亚古兽你还记得吗?...
  2. 配置oracle驱动_Myeclipse中添加Oracle
  3. img打 webpack_webpack打包html里面img后src为“[object Module]”问题
  4. AutoLayout bug集合
  5. 获取android手机的屏幕分辨率 android开发
  6. 327 区间和的个数
  7. 你认为已经过时的C语言,是如何影响500万程序员的?...
  8. 计算机联系函范文,致客户联络函
  9. java.io.FileNotFoundException:/mnt/sdcard/......(Permission denied)
  10. Oracle中查看所有的表,用户表,列名,主键,外键
  11. vfp 打开服务器文件,vfp获取远程服务器时间
  12. Nxlog 配置总结
  13. 算法4(一、递归学习)
  14. MIUI12_Global未知来源安装等待时间patcher
  15. python除数为0报错_Python3报错-Python入门到精通
  16. svn提示commit:remains in tree-conflict的解决方法
  17. 质量与规范,敬我们那些年欠下的技术债
  18. OpenStack-Placement、nova组件部署
  19. 解决M1处理器安装PS闪退问题Photoshop 2021 fo mac(支持最新M1芯片处理器款mac)
  20. 无线充电各种原理方案的比较

热门文章

  1. 用C++完成五子连珠游戏
  2. 五子棋的实现“慕课网五子连珠的笔记”
  3. 网络布线和综合布线系统
  4. git创建html文件路径,git使用详解
  5. oracle指定用户SID,oracle怎么捕获用户登录信息,如SID,IP地址等
  6. WPS中如何快速消除硬回车(转)
  7. springboot在restcontroller下返回文本类型
  8. eclipse开普勒_开普勒之路–里程碑3到来
  9. Scrapy 在shell下抓取图片
  10. tortoise-orm关于pydantic序列化模型外键字段无法生成的问题