恰好看到当当开源了其Sharding-JDBC组件,摘抄一段介绍:
https://github.com/dangdangdotcom/sharding-jdbc
Sharding-JDBC
直接封装JDBC API
,可以理解为增强版的JDBC
驱动,旧代码迁移成本几乎为零:
java
的ORM
框架,如:JPA
, Hibernate
, Mybatis
, Spring JDBC Template
或直接使用JDBC
。DBCP
, C3P0
, BoneCP
, Druid
等。JDBC
规范的数据库。虽然目前仅支持MySQL
,但已有支持Oracle
,SQLServer
,DB2
等数据库的计划。 Sharding-JDBC
定位为轻量级java
框架,使用客户端直连数据库,以jar
包形式提供服务,未使用中间层,无需额外部署,无其他依赖,DBA
也无需改变原有的运维方式。SQL
解析使用Druid
解析器,是目前性能最高的SQL
解析器。
Sharding-JDBC
功能灵活且全面:
=
,BETWEEN
,IN
等多维度分片,也可支持多分片键共用。SQL
解析功能完善,支持聚合,分组,排序,Limit
,OR
等查询,并且支持Binding Table
以及笛卡尔积的表查询。 Sharding-JDBC
配置多样:
inline
方式
com.dangdang
sharding-jdbc-core
1.3.2
com.dangdang
sharding-jdbc-config-spring
1.3.2
com.dangdang
sharding-jdbc-config-common
1.3.2
创建三个库,一主(dbtal_0_master)两从(
dbtal_0_slave_0、dbtal_0_slave_1)
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_user_0
-- ----------------------------
DROP TABLE IF EXISTS `t_user_0`;
CREATE TABLE `t_user_0` (
`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=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for t_user_1
-- ----------------------------
DROP TABLE IF EXISTS `t_user_1`;
CREATE TABLE `t_user_1` (
`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;
-- ----------------------------
-- Table structure for t_user_2
-- ----------------------------
DROP TABLE IF EXISTS `t_user_2`;
CREATE TABLE `t_user_2` (
`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=30 DEFAULT CHARSET=utf8;
User.java
/**
* @filename User.java
* @version www.mindai.com
* @date 2016年10月26日
*/
package com.mjkf.demo.domain.model;
import javax.persistence.Id;
import javax.persistence.Table;
import com.mjkf.framework.core.base.model.BaseModel;
/**
* @author farrell
* @date 2016年10月26日
*/
@Table(name="t_user")
public class User extends BaseModel {
/**
* serialVersionUID
* @since Ver 1.1
*/
private static final long serialVersionUID = -4044598743926228429L;
@Id
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;
}
@Override
public String toString() {
return "User [id=" + id + ", userId=" + userId + ", name=" + name + ", age=" + age + "]";
}
}
UserMapper.java
/**
* @filename UserMapper.java
* @version www.mindai.com
* @date 2016年10月26日
*/
package com.mjkf.demo.mapper;
import com.mjkf.demo.domain.model.User;
import com.mjkf.framework.core.base.mapper.IBaseMapper;
/**
* @author farrell
* @date 2016年10月26日
*/
public interface UserMapper extends IBaseMapper{
}
/**
* @filename IUserService.java
* @version www.mindai.com
* @date 2016年10月26日
*/
package com.mjkf.demo.service;
import com.mjkf.demo.domain.model.User;
import com.mjkf.framework.core.base.service.IService;
import com.mjkf.framework.mybatis.mapper.entity.Example;
/**
* @author farrell
* @date 2016年10月26日
*/
public interface IUserService extends IService{
void updateByExample(User user,Example example);
}
UserServiceImpl.java
package com.mjkf.demo.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mjkf.demo.domain.model.User;
import com.mjkf.demo.mapper.UserMapper;
import com.mjkf.demo.service.IUserService;
import com.mjkf.framework.core.base.service.BaseService;
import com.mjkf.framework.mybatis.mapper.entity.Example;
@Service
public class UserServiceImpl extends BaseService implements IUserService{
@Autowired
UserMapper userMapper;
@Override
public void updateByExample(User record,Example example) {
userMapper.updateByExampleSelective(record, example);
}
}
MySingleKeyTableShardingAlgorithm.java
/**
* @filename SingleKeyTableShardingAlgorithm.java
* @version www.mindai.com
* @date 2016年10月25日
*/
package com.mjkf.demo.sharding;
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;
/**
* @author farrell
* @date 2016年10月25日
*/
public class MySingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm{
/**
* sql 中 = 操作时,table的映射
*/
@Override
public String doEqualSharding(final Collection tableNames, final ShardingValue shardingValue) {
for (String each : tableNames) {
if (each.endsWith(shardingValue.getValue() % 3 + "")) {
return each;
}
}
throw new UnsupportedOperationException();
}
/**
* sql 中 in 操作时,table的映射
*/
@Override
public Collection doInSharding(final Collection tableNames, final ShardingValue shardingValue) {
Collection result = new LinkedHashSet<>(tableNames.size());
for (Integer value : shardingValue.getValues()) {
for (String tableName : tableNames) {
if (tableName.endsWith(value % 3 + "")) {
result.add(tableName);
}
}
}
return result;
}
/**
* sql 中 between 操作时,table的映射
*/
@Override
public Collection doBetweenSharding(final Collection tableNames, final ShardingValue shardingValue) {
Collection result = new LinkedHashSet<>(tableNames.size());
Range range = shardingValue.getValueRange();
for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
for (String each : tableNames) {
if (each.endsWith(i % 3 + "")) {
result.add(each);
}
}
}
return result;
}
}
UserMapper.xml
applicationContext.xml
Spring公共配置
classpath:jdbc.properties
classpath:mapper/*Mapper.xml
MainTest.java
/**
* @filename MainTest.java
* @version www.mindai.com
* @date 2016年10月25日
*/
package test.mjkf;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.mjkf.demo.domain.model.User;
import com.mjkf.demo.service.IUserService;
import com.mjkf.framework.mybatis.mapper.entity.Example;
import com.mjkf.framework.mybatis.mapper.entity.Example.Criteria;
/**
* @author farrell
* @date 2016年10月25日
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:spring/applicationContext.xml" })
public class MainTest {
@Autowired
IUserService userService;
@Test
public void test(){
System.out.println("sharding-demo start................");
User entity = new User();
entity.setUserId(1);
List list = userService.find(entity);
System.out.println(list.size());
for (User user : list) {
System.out.println(user.getUserId()+"------->"+user.getName());
}
System.out.println("======================分割线===========================");
List users = userService.findAll();
for (User user : users) {
System.out.println(user.getUserId()+"------->"+user.getName());
}
System.out.println("执行插入语句");
User user = new User();
user.setUserId(1002);
user.setName("李四");
user.setAge(18);
userService.save(user);
System.out.println("======================分割线===========================");
System.out.println("执行更新语句");
User user1 = new User();
user1.setId(24);
user1.setUserId(1001);
user1.setName("李四update");
user1.setAge(18);
userService.update(user1);
System.out.println("======================分割线===========================");
// System.out.println("执行删除语句");
// User user2 = new User();
// user2.setUserId(1001);
// userService.delete(user2);
// System.out.println("======================分割线===========================");
Example example = new Example(User.class);
Criteria criteria = example.createCriteria();
criteria.andEqualTo("userId", 1001);
User user2 = new User();
user2.setName("李四update2");
user2.setUserId(1001);
user2.setAge(19);
userService.updateByExample(user2,example);
}
}
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Creating a new SqlSession
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c05239a] was not registered for synchronization because synchronization is not active
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@58e6b9bc] will not be managed by Spring
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.select] ==> Preparing: SELECT ID,USER_ID,NAME,AGE FROM t_user WHERE USER_ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.select] ==> Parameters: 1(Integer)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParserFactory] Logic SQL: SELECT ID,USER_ID,NAME,AGE FROM t_user WHERE USER_ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL result: SQLParsedResult(routeContext=RouteContext(tables=[Table(name=t_user, alias=Optional.absent())], sqlStatementType=null, sqlBuilder=null), conditionContexts=[ConditionContext(conditions={Condition.Column(columnName=USER_ID, tableName=t_user)=Condition(column=Condition.Column(columnName=USER_ID, tableName=t_user), operator==, values=[1], valueIndices=[0])})], mergeContext=MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null))
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL: SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user)] WHERE USER_ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] final route result:[SQLExecutionUnit(dataSource=datasource_01, sql=SELECT ID, USER_ID, NAME, AGE FROM t_user_1 WHERE USER_ID = ?, sqlBuilder=SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user_1)] WHERE USER_ID = ?)]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] merge context:MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null)
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.select] <== Total: 0
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c05239a]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
0
======================分割线===========================
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Creating a new SqlSession
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@438c1676] was not registered for synchronization because synchronization is not active
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@2216bf9f] will not be managed by Spring
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.selectAll] ==> Preparing: SELECT ID,USER_ID,NAME,AGE FROM t_user
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.selectAll] ==> Parameters:
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParserFactory] Logic SQL: SELECT ID,USER_ID,NAME,AGE FROM t_user
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL result: SQLParsedResult(routeContext=RouteContext(tables=[Table(name=t_user, alias=Optional.absent())], sqlStatementType=null, sqlBuilder=null), conditionContexts=[ConditionContext(conditions={})], mergeContext=MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null))
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL: SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user)]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] final route result:[SQLExecutionUnit(dataSource=datasource_01, sql=SELECT ID, USER_ID, NAME, AGE FROM t_user_0, sqlBuilder=SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user_0)]), SQLExecutionUnit(dataSource=datasource_01, sql=SELECT ID, USER_ID, NAME, AGE FROM t_user_2, sqlBuilder=SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user_2)]), SQLExecutionUnit(dataSource=datasource_01, sql=SELECT ID, USER_ID, NAME, AGE FROM t_user_1, sqlBuilder=SELECT ID, USER_ID, NAME, AGE FROM [Token(t_user_1)])]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] merge context:MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.merger.ShardingResultSets$WrapperResultSet] 747195039 join pipeline
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.merger.ShardingResultSets$WrapperResultSet] 1770136464 join pipeline
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.merger.ResultSetFactory] Sharding-JDBC: Sharding result sets type is 'MULTIPLE'
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.merger.pipeline.reducer.IteratorReducerResultSet] 1721468812 join pipeline
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.selectAll] <== Total: 10
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@438c1676]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
1002------->李四
1002------->李四
1002------->李四
1002------->李四
1001------->李四update2
1001------->李四update2
1001------->李四update2
1001------->李四update2
1001------->李四update2
1001------->李四update2
执行插入语句
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Creating a new SqlSession
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1e7ae447] was not registered for synchronization because synchronization is not active
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@716acd11] will not be managed by Spring
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.insert] ==> Preparing: INSERT INTO t_user ( ID,USER_ID,NAME,AGE ) VALUES( ?,?,?,? )
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.insert] ==> Parameters: null, 1002(Integer), 李四(String), 18(Integer)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParserFactory] Logic SQL: INSERT INTO t_user ( ID,USER_ID,NAME,AGE ) VALUES( ?,?,?,? )
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL result: SQLParsedResult(routeContext=RouteContext(tables=[Table(name=t_user, alias=Optional.absent())], sqlStatementType=null, sqlBuilder=null), conditionContexts=[ConditionContext(conditions={Condition.Column(columnName=USER_ID, tableName=t_user)=Condition(column=Condition.Column(columnName=USER_ID, tableName=t_user), operator==, values=[1002], valueIndices=[1])})], mergeContext=MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null))
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL: INSERT INTO [Token(t_user)] (ID, USER_ID, NAME, AGE) VALUES (?, ?, ?, ?)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] final route result:[SQLExecutionUnit(dataSource=datasource_01, sql=INSERT INTO t_user_0 (ID, USER_ID, NAME, AGE) VALUES (?, ?, ?, ?), sqlBuilder=INSERT INTO [Token(t_user_0)] (ID, USER_ID, NAME, AGE) VALUES (?, ?, ?, ?))]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] merge context:MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null)
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1e7ae447]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
======================分割线===========================
执行更新语句
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Creating a new SqlSession
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@722ca338] was not registered for synchronization because synchronization is not active
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Fetching JDBC Connection from DataSource
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@508fec17] will not be managed by Spring
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.updateByPrimaryKeySelective] ==> Preparing: UPDATE t_user SET USER_ID = ?,NAME = ?,AGE = ? WHERE ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.updateByPrimaryKeySelective] ==> Parameters: 1001(Integer), 李四update(String), 18(Integer), 24(Integer)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParserFactory] Logic SQL: UPDATE t_user SET USER_ID = ?,NAME = ?,AGE = ? WHERE ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL result: SQLParsedResult(routeContext=RouteContext(tables=[Table(name=t_user, alias=Optional.absent())], sqlStatementType=null, sqlBuilder=null), conditionContexts=[ConditionContext(conditions={})], mergeContext=MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null))
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL: UPDATE [Token(t_user)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] final route result:[SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_0 SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?, sqlBuilder=UPDATE [Token(t_user_0)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?), SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_1 SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?, sqlBuilder=UPDATE [Token(t_user_1)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?), SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_2 SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?, sqlBuilder=UPDATE [Token(t_user_2)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE ID = ?)]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] merge context:MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null)
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@722ca338]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
======================分割线===========================
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Creating new transaction with name [com.mjkf.demo.service.impl.UserServiceImpl.updateByExample]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Acquired Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3] for JDBC transaction
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Switching JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3] to manual commit
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Bound value [org.springframework.jdbc.datasource.ConnectionHolder@68c04a7c] for key [com.dangdang.ddframe.rdb.sharding.spring.datasource.SpringShardingDataSource@45ce43b9] to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Initializing transaction synchronization
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.interceptor.TransactionInterceptor] Getting transaction for [com.mjkf.demo.service.impl.UserServiceImpl.updateByExample]
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Creating a new SqlSession
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40595670]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Bound value [org.mybatis.spring.SqlSessionHolder@2e1de495] for key [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@5adc783a] to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@68c04a7c] for key [com.dangdang.ddframe.rdb.sharding.spring.datasource.SpringShardingDataSource@45ce43b9] bound to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@68c04a7c] for key [com.dangdang.ddframe.rdb.sharding.spring.datasource.SpringShardingDataSource@45ce43b9] bound to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.transaction.SpringManagedTransaction] JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3] will be managed by Spring
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.updateByExampleSelective] ==> Preparing: UPDATE t_user SET USER_ID = ?,NAME = ?,AGE = ? WHERE ( USER_iD = ? )
2016-10-28 17:20:15 [DEBUG]-[com.mjkf.demo.mapper.UserMapper.updateByExampleSelective] ==> Parameters: 1001(Integer), 李四update2(String), 19(Integer), 1001(Integer)
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParserFactory] Logic SQL: UPDATE t_user SET USER_ID = ?,NAME = ?,AGE = ? WHERE ( USER_iD = ? )
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL result: SQLParsedResult(routeContext=RouteContext(tables=[Table(name=t_user, alias=Optional.absent())], sqlStatementType=null, sqlBuilder=null), conditionContexts=[ConditionContext(conditions={})], mergeContext=MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null))
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.parser.SQLParseEngine] Parsed SQL: UPDATE [Token(t_user)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] final route result:[SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_2 SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?, sqlBuilder=UPDATE [Token(t_user_2)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?), SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_0 SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?, sqlBuilder=UPDATE [Token(t_user_0)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?), SQLExecutionUnit(dataSource=datasource_01, sql=UPDATE t_user_1 SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?, sqlBuilder=UPDATE [Token(t_user_1)] SET USER_ID = ?, NAME = ?, AGE = ? WHERE USER_iD = ?)]
2016-10-28 17:20:15 [DEBUG]-[com.dangdang.ddframe.rdb.sharding.router.SQLRouteEngine] merge context:MergeContext(orderByColumns=[], groupByColumns=[], aggregationColumns=[], limit=null)
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Retrieved value [org.mybatis.spring.SqlSessionHolder@2e1de495] for key [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@5adc783a] bound to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Retrieved value [org.mybatis.spring.SqlSessionHolder@2e1de495] for key [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@5adc783a] bound to thread [main]
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40595670]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.transaction.interceptor.TransactionInterceptor] Completing transaction for [com.mjkf.demo.service.impl.UserServiceImpl.updateByExample]
2016-10-28 17:20:15 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Triggering beforeCommit synchronization
2016-10-28 17:20:15 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40595670]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Triggering beforeCompletion synchronization
2016-10-28 17:20:16 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40595670]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Removed value [org.mybatis.spring.SqlSessionHolder@2e1de495] for key [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@5adc783a] from thread [main]
2016-10-28 17:20:16 [DEBUG]-[org.mybatis.spring.SqlSessionUtils] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@40595670]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@68c04a7c] for key [com.dangdang.ddframe.rdb.sharding.spring.datasource.SpringShardingDataSource@45ce43b9] bound to thread [main]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Initiating transaction commit
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Committing JDBC transaction on Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Triggering afterCommit synchronization
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Triggering afterCompletion synchronization
2016-10-28 17:20:16 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Clearing transaction synchronization
2016-10-28 17:20:16 [DEBUG]-[org.springframework.transaction.support.TransactionSynchronizationManager] Removed value [org.springframework.jdbc.datasource.ConnectionHolder@68c04a7c] for key [com.dangdang.ddframe.rdb.sharding.spring.datasource.SpringShardingDataSource@45ce43b9] from thread [main]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Resetting read-only flag of JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceTransactionManager] Releasing JDBC Connection [com.dangdang.ddframe.rdb.sharding.jdbc.ShardingConnection@52ffd2a3] after transaction
2016-10-28 17:20:16 [DEBUG]-[org.springframework.jdbc.datasource.DataSourceUtils] Returning JDBC Connection to DataSource
2016-10-28 17:20:16 [DEBUG]-[org.springframework.test.context.TestContextManager] afterTestMethod(): instance [test.mjkf.MainTest@5b0f7c0d], method [public void test.mjkf.MainTest.test()], exception [null]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener] After test method: context [DefaultTestContext@29ae5edf testClass = MainTest, testInstance = test.mjkf.MainTest@5b0f7c0d, testMethod = test@MainTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@76d697d9 testClass = MainTest, locations = '{classpath*:spring/applicationContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null], method annotated with @DirtiesContext [false] with mode [null].
2016-10-28 17:20:16 [DEBUG]-[org.springframework.test.context.TestContextManager] afterTestClass(): class [test.mjkf.MainTest]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener] After test class: context [DefaultTestContext@29ae5edf testClass = MainTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@76d697d9 testClass = MainTest, locations = '{classpath*:spring/applicationContext.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null].
2016-10-28 17:20:16 [INFO]-[org.springframework.context.support.GenericApplicationContext] Closing org.springframework.context.support.GenericApplicationContext@7d7c88d4: startup date [Fri Oct 28 17:20:13 CST 2016]; root of context hierarchy
2016-10-28 17:20:16 [DEBUG]-[org.springframework.context.support.GenericApplicationContext] Publishing event in org.springframework.context.support.GenericApplicationContext@7d7c88d4: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.support.GenericApplicationContext@7d7c88d4: startup date [Fri Oct 28 17:20:13 CST 2016]; root of context hierarchy]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'sqlSessionFactory'
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Returning cached instance of singleton bean 'lifecycleProcessor'
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@45f0d31e: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,userServiceImpl,emailServer,propertyConfigurer,dataSource_master,dataSource_slave,datasource_01,userTableStrategy,shardingDataSource,sqlSessionFactory,sqlSession,com.mjkf.framework.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.transaction.config.internalTransactionalEventListenerFactory,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,transactionManager,transactionAdvice,transactionPointCut,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor,userMapper]; root of factory hierarchy
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean '(inner bean)#a1848dc#1': [datasource_01]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DisposableBeanAdapter] Invoking destroy method 'close' on bean with name '(inner bean)#a1848dc#1'
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DisposableBeanAdapter] Invoking destroy method 'close' on bean with name 'dataSource_slave'
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean 'userServiceImpl': [test.mjkf.MainTest]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean '(inner bean)#213466fe': [transactionAdvice]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean 'sqlSessionFactory': [sqlSession]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean '(inner bean)#44b56ed9': [shardingDataSource]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean '(inner bean)#1d04e75b': [(inner bean)#44b56ed9]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DefaultListableBeanFactory] Retrieved dependent beans for bean '(inner bean)#a1848dc': [(inner bean)#1d04e75b]
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DisposableBeanAdapter] Invoking destroy method 'close' on bean with name '(inner bean)#a1848dc'
2016-10-28 17:20:16 [INFO]-[com.alibaba.druid.pool.DruidDataSource] {dataSource-2} closed
2016-10-28 17:20:16 [DEBUG]-[org.springframework.beans.factory.support.DisposableBeanAdapter] Invoking destroy method 'close' on bean with name 'dataSource_master'
2016-10-28 17:20:16 [INFO]-[com.alibaba.druid.pool.DruidDataSource] {dataSource-1} closed