====== sharding-jdbc示例项目 ======
===== 简介 =====
开源分库分表中间件
===== 官方介绍 =====
Sharding-JDBC是一个开源的适用于微服务的分布式数据访问基础类库,它始终以云原生的基础开发套件为目标。
Sharding-JDBC定位为轻量级java框架,使用客户端直连数据库,以jar包形式提供服务,未使用中间层,无需额外部署,无其他依赖,DBA也无需改变原有的运维方式,可理解为增强版的JDBC驱动,旧代码迁移成本几乎为零。
Sharding-JDBC完整的实现了分库分表,读写分离和分布式主键功能,并初步实现了柔性事务。
===== 官方链接 =====
官网:[[http://shardingjdbc.io/|shardingjdbc.io]]
文档:[[http://shardingjdbc.io/docs/00-overview|shardingjdbc文档]]
github:[[https://github.com/dangdangdotcom/sharding-jdbc|sharding-jdbc]]
===== 示例项目 =====
==== pom.xml ====
4.0.0com.gxxshardingwar0.0.1-SNAPSHOTsharding Maven Webapphttp://maven.apache.org4.0.5.RELEASE1.6.91.6.12.3.203.2.71.2.21.3.22.42.01.21.1.22.4.02.4.02.4.02.4.04.111.2.165.1.91.43.3.2scm:svn:svn://121.43.104.34/gxx/trunk/shardingscm:svn:svn://121.43.104.34/gxx/trunk/shardingorg.springframeworkspring-core${spring.version}org.springframeworkspring-beans${spring.version}org.springframeworkspring-context${spring.version}org.springframeworkspring-context-support${spring.version}org.springframeworkspring-aop${spring.version}org.springframeworkspring-jdbc${spring.version}org.springframeworkspring-web${spring.version}org.springframeworkspring-webmvc${spring.version}org.aspectjaspectjrt${aspectjrt.version}org.aspectjaspectjweaver${aspectjweaver.version}org.freemarkerfreemarker${freemarker.version}org.mybatismybatis${mybatis.version}org.mybatismybatis-spring${mybatis-spring.version}org.mybatis.generatormybatis-generator-core${mybatis-generator-core.version}javax.servletservlet-api${servlet-api.version}providedjavax.servlet.jspjsp-api${jsp-api.version}providedjavax.servletjstl${jstl.version}taglibsstandard${standard.version}com.fasterxml.jackson.corejackson-databind${jackson-databind.version}com.fasterxml.jackson.corejackson-annotations${jackson-annotations.version}com.fasterxml.jackson.modulejackson-module-jaxb-annotations${jackson-module-jaxb-annotations.version}com.fasterxml.jackson.corejackson-core${jackson-core.version}log4jlog4j${log4j.version}junitjunittest${junit.version}mysqlmysql-connector-java${mysql-connector-java.version}commons-dbcpcommons-dbcp${commons-dbcp.version}com.dangdangsharding-jdbc-core1.4.2com.dangdangsharding-jdbc-config-spring1.4.0org.apache.commonscommons-lang3${commons-lang3.version}nexusTeam Nexus Repositoryhttp://121.43.104.34:8081/nexus/content/groups/publicofficalMaven Official Repositoryhttp://repo1.maven.org/maven2falsespring-milestoneSpring Maven MILESTONE Repositoryhttp://maven.springframework.org/milestonejbossJboss Repositoryhttp://repository.jboss.org/nexus/content/groups/public-jboss/falsejava.netJava.net Repositoryhttp://download.java.net/maven/2/falsespring-releaseSpring Maven Release Repositoryhttp://repo.springsource.org/libs-releasefalseshardingorg.apache.maven.pluginsmaven-compiler-plugin2.0.21.61.6utf8org.apache.maven.pluginsmaven-scm-plugin1.3org.apache.maven.pluginsmaven-release-plugin2.4svn://121.43.104.34/gxx/tags/shardingsvn://121.43.104.34/gxx/branches/shardingorg.apache.maven.pluginsmaven-archetype-plugin2.2nexus-releasesNexus Release Repositoryhttp://121.43.104.34:8081/nexus/content/repositories/releases/nexus-snapshotsNexus Snapshot Repositoryhttp://121.43.104.34:8081/nexus/content/repositories/snapshots/
==== application-context.xml ====
==== application-sharding-jdbc.xml ====
algorithm-class="com.gxx.sharding.base.UserSingleKeyDatabaseShardingAlgorithm"/>
algorithm-class="com.gxx.sharding.base.UserSingleKeyTableShardingAlgorithm"/>
actual-tables="user_0,user_1"
database-strategy="databaseShardingStrategy"
table-strategy="tableShardingStrategy"/>
==== mybatis.xml ====
==== web.xml ====
Archetype Created Web ApplicationcontextConfigLocation
classpath*:/application-*.xml,
log4jConfigLocation/WEB-INF/classes/log4j.xmlencodingFilterorg.springframework.web.filter.CharacterEncodingFilterencodingUTF-8forceEncodingtrueencodingFilter/*org.springframework.web.context.ContextLoaderListenerorg.springframework.web.util.IntrospectorCleanupListenerdispatcherorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath*:/spring-mvc.xml1dispatcher*.htmindex.jspJSPConfiguration*.jspUTF-8
==== UserSingleKeyDatabaseShardingAlgorithm.java ====
package com.gxx.sharding.base;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.apache.log4j.Logger;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.SingleKeyDatabaseShardingAlgorithm;
import com.google.common.collect.Range;
/**
* 用户单字段分库算法
* @author Gxx
*/
public class UserSingleKeyDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm {
/**
* 日志处理器
*/
private Logger logger = Logger.getLogger(UserSingleKeyDatabaseShardingAlgorithm.class);
/**
* sql equal 规则
* sharding_00.user_0
* sharding_00.user_1
* sharding_01.user_0
* sharding_01.user_1
*/
@Override
public String doEqualSharding(Collection availableDatabaseNames, ShardingValue shardingValue) {
logger.info("用户单字段分库算法:sql equal 规则");
logger.info("sharding value:" + shardingValue.getValue());
for (String each : availableDatabaseNames) {
if (each.endsWith(shardingValue.getValue() % 4 / 2 + "")) {
logger.info("扫描到库:" + each);
return each;
}
}
logger.info("没有扫描到任何库");
throw new IllegalArgumentException();
}
/**
* sql in 规则
*/
@Override
public Collection doInSharding(Collection availableDatabaseNames, ShardingValue shardingValue) {
logger.info("用户单字段分库算法:sql in 规则");
logger.info("sharding values:" + shardingValue.getValues());
Collection result = new LinkedHashSet(availableDatabaseNames.size());
for (Long value : shardingValue.getValues()) {
logger.info("sharding value:" + value);
for (String each : availableDatabaseNames) {
if (each.endsWith(value % 4 / 2 + "")) {
logger.info("扫描到库:" + each);
result.add(each);
}
}
}
logger.info("扫描最终结果:" + result);
return result;
}
/**
* sql between and 规则
*/
@Override
public Collection doBetweenSharding(Collection availableDatabaseNames,
ShardingValue shardingValue) {
logger.info("用户单字段分库算法:sql between and 规则");
logger.info("sharding value range:" + shardingValue.getValueRange());
Collection result = new LinkedHashSet(availableDatabaseNames.size());
Range range = (Range) shardingValue.getValueRange();
for (Long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
logger.info("sharding value:" + i);
for (String each : availableDatabaseNames) {
if (each.endsWith(i % 4 / 2 + "")) {
logger.info("扫描到库:" + each);
result.add(each);
}
}
}
logger.info("扫描最终结果:" + result);
return result;
}
}
==== UserSingleKeyTableShardingAlgorithm.java ====
package com.gxx.sharding.base;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.apache.log4j.Logger;
import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
/**
* 用户单字段分表算法
* @author Gxx
*/
public class UserSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm {
/**
* 日志处理器
*/
private Logger logger = Logger.getLogger(UserSingleKeyTableShardingAlgorithm.class);
/**
* sql == 规则
* sharding_00.user_0
* sharding_00.user_1
* sharding_01.user_0
* sharding_01.user_1
*/
public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {
logger.info("用户单字段分表算法:sql equal 规则");
logger.info("sharding value:" + shardingValue.getValue());
for (String each : tableNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
logger.info("扫描到表:" + each);
return each;
}
}
logger.info("没有扫描到任何表");
throw new IllegalArgumentException();
}
/**
* sql in 规则
*/
public Collection doInSharding(Collection tableNames, ShardingValue shardingValue) {
logger.info("用户单字段分表算法:sql in 规则");
logger.info("sharding values:" + shardingValue.getValues());
Collection result = new LinkedHashSet(tableNames.size());
for (long value : shardingValue.getValues()) {
logger.info("sharding value:" + value);
for (String each : tableNames) {
if (each.endsWith(value % 2 + "")) {
logger.info("扫描到表:" + each);
result.add(each);
}
}
}
logger.info("扫描最终结果:" + result);
return result;
}
/**
* sql between 规则
*/
public Collection doBetweenSharding(Collection tableNames, ShardingValue shardingValue) {
logger.info("用户单字段分表算法:sql in 规则");
logger.info("sharding value range:" + shardingValue.getValueRange());
Collection result = new LinkedHashSet(tableNames.size());
Range range = (Range) shardingValue.getValueRange();
for (long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
logger.info("sharding value:" + i);
for (String each : tableNames) {
if (each.endsWith(i % 2 + "")) {
logger.info("扫描到表:" + each);
result.add(each);
}
}
}
logger.info("扫描最终结果:" + result);
return result;
}
}
==== UserMapper.java ====
package com.gxx.sharding.base.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import com.gxx.sharding.base.vo.User;
@Repository
public interface UserMapper {
int deleteByPrimaryKey(Long userId);
int insert(User user);
int insertSelective(User user);
User selectByPrimaryKey(Long userId);
int updateByPrimaryKeySelective(User user);
int updateByPrimaryKey(User user);
/**
* 根据id集合查询用户
* @param userIdList
* @return
*/
List queryUsersInUserId(@Param("userIdList") List userIdList);
/**
* 根据id区间查询用户
* @param beginUserId
* @param endUserId
* @return
*/
@Select("SELECT * FROM user WHERE user_id BETWEEN #{beginUserId} AND #{endUserId} ORDER BY USER_ID")
List queryUsersBetweenUserId(@Param("beginUserId") Long beginUserId, @Param("endUserId") Long endUserId);
/**
* 计数
* @return
*/
@Select("SELECT COUNT(user_id) FROM user")
long countUser();
/**
* 求和
* @return
*/
@Select("SELECT SUM(user_id) FROM user")
long sumUser();
/**
* 取小
* @return
*/
@Select("SELECT MIN(user_id) FROM user")
long minUser();
/**
* 取大
* @return
*/
@Select("SELECT MAX(user_id) FROM user")
long maxUser();
/**
* 平均
* @return
*/
@Select("SELECT AVG(user_id) FROM user")
double avgUser();
/**
* 根据limit区间查询用户
* @param beginUserId
* @param num
* @return
*/
@Select("SELECT * FROM user ORDER BY user_id LIMIT #{beginUserId}, #{num}")
List queryUsersLimitUserId(@Param("beginUserId") Long beginUserId, @Param("num") Long num);
}
==== UserMapper.xml ====
user_id, name, password, create_date, create_time
delete from user
where user_id = #{userId,jdbcType=BIGINT}
insert into user (user_id, name, password,
create_date, create_time)
values (#{userId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
#{createDate,jdbcType=VARCHAR}, #{createTime,jdbcType=VARCHAR})
insert into user
user_id,
name,
password,
create_date,
create_time,
#{userId,jdbcType=BIGINT},
#{name,jdbcType=VARCHAR},
#{password,jdbcType=VARCHAR},
#{createDate,jdbcType=VARCHAR},
#{createTime,jdbcType=VARCHAR},
update user
name = #{name,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
create_date = #{createDate,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=VARCHAR},
where user_id = #{userId,jdbcType=BIGINT}
update user
set name = #{name,jdbcType=VARCHAR},
password = #{password,jdbcType=VARCHAR},
create_date = #{createDate,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=VARCHAR}
where user_id = #{userId,jdbcType=BIGINT}
==== User.java ====
package com.gxx.sharding.base.vo;
public class User {
private Long userId;
private String name;
private String password;
private String createDate;
private String createTime;
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getCreateDate() {
return createDate;
}
public void setCreateDate(String createDate) {
this.createDate = createDate == null ? null : createDate.trim();
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime == null ? null : createTime.trim();
}
@Override
public String toString() {
return "User [userId=" + userId + ", name=" + name + ", password=" + password + ", createDate=" + createDate
+ ", createTime=" + createTime + "]";
}
}
==== UserController.java ====
package com.gxx.sharding.web.user;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.gxx.sharding.base.utils.DateUtils;
import com.gxx.sharding.base.vo.User;
import com.gxx.sharding.dto.UserDto;
import com.gxx.sharding.service.UserService;
/**
* UserController
* @author gxx
*/
@Controller
@RequestMapping("/user/")
public class UserController {
/**
* 日志处理器
*/
private final Logger logger = Logger.getLogger(UserController.class);
@Autowired
private UserService userService;
@RequestMapping(value = "/preRegistFtl", method = RequestMethod.GET)
public String preRegistFtl() {
return "user/preRegistFtl";
}
@RequestMapping(value = "/preRegistJsp", method = RequestMethod.GET)
public String preRegistJsp() {
return "user/preRegistJsp";
}
@RequestMapping(value = "/preQueryFtl", method = RequestMethod.GET)
public String preQueryFtl() {
return "user/preQueryFtl";
}
/**
* 注册
* @param request
* @param userDto
* @return
*/
@RequestMapping(value = "/registJsp",produces="application/json")
public @ResponseBody UserDto registJsp(HttpServletRequest request, UserDto userDto) {
logger.info("用户注册:姓名[" + userDto.getName() + "],密码[" + userDto.getPassword() + "]");
/**
* 1.判用户名是否存在
*/
User user = null;//userService.getUserByName(userDto.getName());
if(user != null){
userDto.setSuccess(Boolean.FALSE.booleanValue());
userDto.setMessage("用户名[" + userDto.getName() + "]已存在!");
return userDto;
}
/**
* 2.创建用户对象 并 新增用户
*/
user = new User();
user.setUserId(userDto.getId().longValue());
user.setName(userDto.getName());
user.setPassword(userDto.getPassword());
user.setCreateDate("20150618");
user.setCreateTime("000000");
userService.doSaveUser(user);
/**
* 3.返回结果
*/
userDto.setSuccess(Boolean.TRUE.booleanValue());
userDto.setMessage("注册成功!");
return userDto;
}
/**
* 注册
* @param request
* @param userDto
* @return
*/
@RequestMapping(value = "/registFtl")
public String registFtl(HttpServletRequest request, UserDto userDto) {
logger.info("用户注册:姓名[" + userDto.getName() + "],密码[" + userDto.getPassword() + "]");
/**
* 1.判用户名是否存在
*/
User user = null;//userService.getUserByName(userDto.getName());
if(user != null){
userDto.setSuccess(Boolean.FALSE.booleanValue());
userDto.setMessage("用户名[" + userDto.getName() + "]已存在!");
return "user/result";
}
/**
* 2.创建用户对象 并 新增用户
*/
user = new User();
user.setUserId(userDto.getId().longValue());
user.setName(userDto.getName());
user.setPassword(userDto.getPassword());
user.setCreateDate("20150618");
user.setCreateTime("000000");
userService.doSaveUser(user);
/**
* 3.返回结果
*/
userDto.setSuccess(Boolean.TRUE.booleanValue());
userDto.setMessage("注册成功!");
return "user/result";
}
/**
* 查询
* @param request
* @param userDto
* @return
*/
@RequestMapping(value = "/queryFtl")
public String queryFtl(HttpServletRequest request, UserDto userDto) {
logger.info("用户查询:id值[" + userDto.getIdValue() + "],查询类型[" + userDto.getType() + "]");
String message = "查询成功!";
/**
* 1.根据查询类型区分
*/
if("equal".equals(userDto.getType())) {
User user = userService.getUserByUserId(Long.parseLong(userDto.getIdValue()));
logger.info("根据id[" + userDto.getIdValue() + "]查询用户:" + user);
message += user;
} else if("update".equals(userDto.getType())) {
User user = userService.getUserByUserId(Long.parseLong(userDto.getIdValue()));
user.setCreateDate(DateUtils.getCurrentDate());
user.setCreateTime(DateUtils.getCurrentTime());
userService.doUpdateUser(user);
logger.info("根据id[" + userDto.getIdValue() + "]修改用户:" + user);
message += user;
} else if("delete".equals(userDto.getType())) {
User user = userService.getUserByUserId(Long.parseLong(userDto.getIdValue()));
userService.doDeleteUser(user);
logger.info("根据id[" + userDto.getIdValue() + "]删除用户:" + user);
message += user;
} else if("in".equals(userDto.getType())) {
String[] idArray = userDto.getIdValue().split(",");
List userIdList = new ArrayList();
for(String idString : idArray) {
userIdList.add(Long.parseLong(idString));
}
List userList = userService.queryUsersInUserId(userIdList);
logger.info("根据id集合[" + userDto.getIdValue() + "]查询用户:" + userList.size());
for(int i=0;i 0) {
message += ",";
}
message += userList.get(i);
}
} else if("between".equals(userDto.getType())) {
String[] idArray = userDto.getIdValue().split(",");
Long beginUserId = Long.parseLong(idArray[0]);
Long endUserId = Long.parseLong(idArray[1]);
List userList = userService.queryUsersBetweenUserId(beginUserId, endUserId);
logger.info("根据id区间[" + userDto.getIdValue() + "]查询用户:" + userList.size());
for(int i=0;i 0) {
message += ",";
}
message += userList.get(i);
}
} else if("all".equals(userDto.getType())) {
List userList = userService.queryUsersInUserId(null);
logger.info("查询所有用户:" + userList.size());
for(int i=0;i 0) {
message += ",";
}
message += userList.get(i);
}
} else if("count".equals(userDto.getType())) {
long result = userService.countUser();
logger.info("查询count:" + result);
message += "count=[" + result + "]";
} else if("sum".equals(userDto.getType())) {
long result = userService.sumUser();
logger.info("查询sum:" + result);
message += "sum=[" + result + "]";
} else if("min".equals(userDto.getType())) {
long result = userService.minUser();
logger.info("查询min:" + result);
message += "min=[" + result + "]";
} else if("max".equals(userDto.getType())) {
long result = userService.maxUser();
logger.info("查询max:" + result);
message += "max=[" + result + "]";
} else if("avg".equals(userDto.getType())) {
double result = userService.avgUser();
logger.info("查询avg:" + result);
message += "avg=[" + result + "]";
} else if("limit".equals(userDto.getType())) {
String[] idArray = userDto.getIdValue().split(",");
Long beginUserId = Long.parseLong(idArray[0]);
Long count = Long.parseLong(idArray[1]);
List userList = userService.queryUsersLimitUserId(beginUserId, count);
logger.info("根据limit区间[" + userDto.getIdValue() + "]查询用户:" + userList.size());
for(int i=0;i 0) {
message += ",";
}
message += userList.get(i);
}
} else {
/**
* 2.查询类型不存在
*/
userDto.setSuccess(Boolean.FALSE.booleanValue());
userDto.setMessage("查询类型不存在!");
return "user/result";
}
/**
* 3.返回结果
*/
userDto.setSuccess(Boolean.TRUE.booleanValue());
userDto.setMessage(message);
return "user/result";
}
}
==== preRegistFtl.ftl ====
注册页面
==== preQueryFtl.ftl ====
查询页面
==== result.ftl ====
This is my result: ${userDto.success?string('true','false')}
This is my message: ${userDto.message}
===== 打包下载 =====
{{:分享:技术:sharding-jdbc:sharding-gxx.zip|}}
===== 库+表 =====
2个库,4张表
sharding_00.user_0;
sharding_01.user_0;
sharding_00.user_1;
sharding_01.user_1;
===== 初始化sql =====
create database sharding_00;
create database sharding_01;
use sharding_00;
CREATE TABLE `user_0` (
`user_id` bigint(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密码',
`create_date` varchar(8) NOT NULL COMMENT '创建日期',
`create_time` varchar(6) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户表_0';
CREATE TABLE `user_1` (
`user_id` bigint(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密码',
`create_date` varchar(8) NOT NULL COMMENT '创建日期',
`create_time` varchar(6) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户表_1';
use sharding_01;
CREATE TABLE `user_0` (
`user_id` bigint(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密码',
`create_date` varchar(8) NOT NULL COMMENT '创建日期',
`create_time` varchar(6) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户表_0';
CREATE TABLE `user_1` (
`user_id` bigint(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(50) NOT NULL COMMENT '姓名',
`password` varchar(32) NOT NULL COMMENT '密码',
`create_date` varchar(8) NOT NULL COMMENT '创建日期',
`create_time` varchar(6) NOT NULL COMMENT '创建时间',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='用户表_1';
===== 分片键 =====
user表的分片键:user_id
注意:分片键user_id,sql里必须是小写的,写成USER_ID,会造成:sharding-jdbc找不到分片键,那会所有的分库+分表都会执行一遍!
===== 分片算法 =====
分库算法:user_id % 4 / 2 -> sharding_00,sharding_01
分表算法:user_id % 2 -> user_0, user_1
比如:
^ user_id ^ 算库 ^ 库 ^ 算表 ^ 表 ^
| 1 | 1%4/2=0 | sharding_00 | 1%2=1 | user_1 |
| 2 | 2%4/2=1 | sharding_01 | 2%2=0 | user_0 |
| 3 | 3%4/2=1 | sharding_01 | 3%2=1 | user_1 |
| 4 | 4%4/2=0 | sharding_00 | 4%2=0 | user_0 |
| 5 | 5%4/2=0 | sharding_00 | 5%2=1 | user_1 |
===== 测试场景 =====
注意:insert场景访问该地址:http://localhost:8080/sharding/user/preRegistFtl.htm
其他场景访问该地址,类型选择下拉框:http://localhost:8080/sharding/user/preQueryFtl.htm
==== insert场景 ====
#代码中逻辑sql
insert into user (user_id, name, password, create_date, create_time) values (15, '关向辉', '123456', '20150618', '000000');
->
#sharding-jdbc解析sql
INSERT INTO sharding_01.user_1 (user_id, name, password, create_date, create_time) VALUES (15, '关向辉', '123456', '20150618', '000000');
==== select场景 ====
#代码中逻辑sql
select user_id, name, password, create_date, create_time from user where user_id = 12;
->
#sharding-jdbc解析sql
SELECT user_id, name, password, create_date, create_time FROM sharding_00.user_0 WHERE user_id = 12;
==== update场景 ====
#代码中逻辑sql
update user set name = 'gxx9', password = 'qweqwe', create_date = '20170912', create_time = '161409' WHERE user_id = 9;
->
#sharding-jdbc解析sql
UPDATE sharding_00.user_1 SET name = 'gxx9', password = 'qweqwe', create_date = '20170912', create_time = '161409' WHERE user_id = 9;
==== delete场景 ====
#代码中逻辑sql
delete from user where user_id = 8;
->
#sharding-jdbc解析sql
DELETE FROM sharding_00.user_0 WHERE user_id = 8;
==== in场景 ====
#代码中逻辑sql
SELECT * FROM user WHERE user_id IN ( 3 , 6 ) ORDER BY USER_ID;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_01.user_1 WHERE user_id IN (3, 6) ORDER BY USER_ID;
SELECT * FROM sharding_01.user_0 WHERE user_id IN (3, 6) ORDER BY USER_ID;
==== in场景 ====
#代码中逻辑sql
SELECT * FROM user WHERE user_id IN ( 3 , 4 ) ORDER BY USER_ID;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_00.user_1 WHERE user_id IN (3, 4) ORDER BY USER_ID;
SELECT * FROM sharding_00.user_0 WHERE user_id IN (3, 4) ORDER BY USER_ID;
SELECT * FROM sharding_01.user_0 WHERE user_id IN (3, 4) ORDER BY USER_ID;
SELECT * FROM sharding_01.user_1 WHERE user_id IN (3, 4) ORDER BY USER_ID;
==== between场景 ====
#代码中逻辑sql
SELECT * FROM user WHERE user_id BETWEEN 2 AND 3 ORDER BY USER_ID;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_01.user_0 WHERE user_id BETWEEN 2 AND 3 ORDER BY USER_ID;
SELECT * FROM sharding_01.user_1 WHERE user_id BETWEEN 2 AND 3 ORDER BY USER_ID;
==== between场景 ====
#代码中逻辑sql
SELECT * FROM user WHERE user_id BETWEEN 3 AND 4 ORDER BY USER_ID;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_00.user_0 WHERE user_id BETWEEN 3 AND 4 ORDER BY USER_ID;
SELECT * FROM sharding_00.user_1 WHERE user_id BETWEEN 3 AND 4 ORDER BY USER_ID;
SELECT * FROM sharding_01.user_1 WHERE user_id BETWEEN 3 AND 4 ORDER BY USER_ID;
SELECT * FROM sharding_01.user_0 WHERE user_id BETWEEN 3 AND 4 ORDER BY USER_ID;
==== 无分片键场景 ====
#代码中逻辑sql
SELECT * FROM user ORDER BY USER_ID;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_00.user_0 ORDER BY USER_ID;
SELECT * FROM sharding_00.user_1 ORDER BY USER_ID;
SELECT * FROM sharding_01.user_0 ORDER BY USER_ID;
SELECT * FROM sharding_01.user_1 ORDER BY USER_ID;
==== count场景 ====
#代码中逻辑sql
SELECT COUNT(user_id) FROM user;
->
#sharding-jdbc解析sql
SELECT COUNT(user_id) FROM sharding_00.user_0;
SELECT COUNT(user_id) FROM sharding_00.user_1;
SELECT COUNT(user_id) FROM sharding_01.user_1;
SELECT COUNT(user_id) FROM sharding_01.user_0;
==== sum场景 ====
#代码中逻辑sql
SELECT SUM(user_id) FROM user;
->
#sharding-jdbc解析sql
SELECT SUM(user_id) FROM sharding_00.user_0;
SELECT SUM(user_id) FROM sharding_00.user_1;
SELECT SUM(user_id) FROM sharding_01.user_0;
SELECT SUM(user_id) FROM sharding_01.user_1;
==== min场景 ====
#代码中逻辑sql
SELECT MIN(user_id) FROM user;
->
#sharding-jdbc解析sql
SELECT MIN(user_id) FROM sharding_00.user_0;
SELECT MIN(user_id) FROM sharding_00.user_1;
SELECT MIN(user_id) FROM sharding_01.user_0;
SELECT MIN(user_id) FROM sharding_01.user_1;
==== max场景 ====
#代码中逻辑sql
SELECT MAX(user_id) FROM user;
->
#sharding-jdbc解析sql
SELECT MAX(user_id) FROM sharding_00.user_0;
SELECT MAX(user_id) FROM sharding_00.user_0;
SELECT MAX(user_id) FROM sharding_01.user_1;
SELECT MAX(user_id) FROM sharding_01.user_1;
==== avg场景 ====
#代码中逻辑sql
SELECT AVG(user_id) FROM user;
->
#sharding-jdbc解析sql
SELECT AVG(user_id), COUNT(user_id) AS sharding_gen_1, SUM(user_id) AS sharding_gen_2 FROM sharding_00.user_0;
SELECT AVG(user_id), COUNT(user_id) AS sharding_gen_1, SUM(user_id) AS sharding_gen_2 FROM sharding_00.user_1;
SELECT AVG(user_id), COUNT(user_id) AS sharding_gen_1, SUM(user_id) AS sharding_gen_2 FROM sharding_01.user_0;
SELECT AVG(user_id), COUNT(user_id) AS sharding_gen_1, SUM(user_id) AS sharding_gen_2 FROM sharding_01.user_1;
==== limit场景 ====
#代码中逻辑sql
SELECT * FROM user ORDER BY user_id LIMIT 4, 2;
->
#sharding-jdbc解析sql
SELECT * FROM sharding_00.user_0 ORDER BY user_id LIMIT 0, 6;
SELECT * FROM sharding_00.user_0 ORDER BY user_id LIMIT 0, 6;
SELECT * FROM sharding_01.user_1 ORDER BY user_id LIMIT 0, 6;
SELECT * FROM sharding_01.user_1 ORDER BY user_id LIMIT 0, 6;