学习sharding-jdbc(二)之spring+mybatis+sharding-jdbc整合

[quote]http://blog.csdn.net/linuu/article/details/50929904[/quote]


新建Maven项目


pom.xml
[html] view plain copy
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0

org.study
sharding-jdbc-mybatis
0.0.1-SNAPSHOT
jar

sharding-jdbc-mybatis
http://maven.apache.org


UTF-8
3.2.5.RELEASE
3.2.4




junit
junit
4.10


com.dangdang
sharding-jdbc-core
1.0.0


org.springframework
spring-orm
${spring.version}


commons-dbcp
commons-dbcp
1.4


org.mybatis
mybatis-spring
1.2.2


org.mybatis
mybatis
${mybatis.version}



org.springframework
spring-expression
${spring.version}


org.springframework
spring-aop
${spring.version}


org.springframework
spring-beans
${spring.version}


org.springframework
spring-context
${spring.version}


org.springframework
spring-context-support
${spring.version}


org.springframework
spring-test
${spring.version}


org.springframework
spring-tx
${spring.version}


mysql
mysql-connector-java
5.1.28


log4j
log4j
1.2.16


org.slf4j
slf4j-log4j12
1.7.5




新建2个库,sharding_0和sharding_1


分别在这2个库运行sql:
[java] view plain copy
/*
Navicat MySQL Data Transfer

Source Server : PMS
Source Server Version : 50624
Source Host : localhost:3306
Source Database : sharding_0

Target Server Type : MYSQL
Target Server Version : 50624
File Encoding : 65001

Date: 2016-03-19 14:18:22
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for t_student_0
-- ----------------------------
DROP TABLE IF EXISTS `t_student_0`;
CREATE TABLE `t_student_0` (
`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;

DROP TABLE IF EXISTS `t_student_1`;
CREATE TABLE `t_student_1` (
`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;

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 DEFAULT CHARSET=utf8;

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 DEFAULT CHARSET=utf8;

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 DEFAULT CHARSET=utf8;
Student.Java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.entity;

import java.io.Serializable;

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;
}

}
User.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.entity;

import java.io.Serializable;

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;
}

@Override
public String toString() {
return "User [id=" + id + ", userId=" + userId + ", name=" + name + ", age=" + age + "]";
}

}

StudentMapper.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.mapper;

import java.util.List;

import com.study.dangdang.sharding.jdbc.entity.Student;

public interface StudentMapper {

Integer insert(Student s);

List findAll();

List findByStudentIds(List studentIds);

}

UserMapper.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.mapper;

import java.util.List;

import com.study.dangdang.sharding.jdbc.entity.User;

public interface UserMapper {

Integer insert(User u);

List findAll();

List findByUserIds(List userIds);


}

StudentMapper.xml
[html] view plain copy











insert into t_student (student_id,name,age) values (#{studentId},#{name},#{age})







id,student_id,name,age






UserMapper.xml
[html] view plain copy











insert into t_user (user_id,name,age) values (#{userId},#{name},#{age})







id,user_id,name,age






StudentService.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.service;

import com.study.dangdang.sharding.jdbc.entity.Student;

public interface StudentService {

boolean insert(Student student);

}

UserService.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.service;

import java.util.List;

import com.study.dangdang.sharding.jdbc.entity.User;

public interface UserService {

public boolean insert(User u);

public List findAll();

public List findByUserIds(List ids);

public void transactionTestSucess();

public void transactionTestFailure() throws IllegalAccessException;

}

StudentServiceImpl.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.service.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.study.dangdang.sharding.jdbc.entity.Student;
import com.study.dangdang.sharding.jdbc.mapper.StudentMapper;
import com.study.dangdang.sharding.jdbc.service.StudentService;

@Service
public class StudentServiceImpl implements StudentService{

@Resource
public StudentMapper studentMapper;

public boolean insert(Student student) {
return studentMapper.insert(student) > 0 ? true : false;
}

}

UserServiceImpl.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.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.study.dangdang.sharding.jdbc.entity.Student;
import com.study.dangdang.sharding.jdbc.entity.User;
import com.study.dangdang.sharding.jdbc.mapper.StudentMapper;
import com.study.dangdang.sharding.jdbc.mapper.UserMapper;
import com.study.dangdang.sharding.jdbc.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 findAll() {
return userMapper.findAll();
}

public List findByUserIds(List 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();
}

}

StudentSingleKeyDatabaseShardingAlgorithm.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.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 lyncc
*
*/
public class StudentSingleKeyDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm{

/**
* sql 中关键字 匹配符为 =的时候,表的路由函数
*/
public String doEqualSharding(Collection availableTargetNames, ShardingValue shardingValue) {
for (String each : availableTargetNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
throw new IllegalArgumentException();
}

/**
* sql 中关键字 匹配符为 in 的时候,表的路由函数
*/
public Collection doInSharding(Collection availableTargetNames, ShardingValue shardingValue) {
Collection result = new LinkedHashSet(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 doBetweenSharding(Collection availableTargetNames,
ShardingValue shardingValue) {
Collection result = new LinkedHashSet(availableTargetNames.size());
Range range = (Range) 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;
}

}
StudentSingleKeyTableShardingAlgorithm.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.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 lyncc
*
*/
public class StudentSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm{

/**
* sql 中 = 操作时,table的映射
*/
public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {
for (String each : tableNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
throw new IllegalArgumentException();
}

/**
* sql 中 in 操作时,table的映射
*/
public Collection doInSharding(Collection tableNames, ShardingValue shardingValue) {
Collection result = new LinkedHashSet(tableNames.size());
for (Integer value : shardingValue.getValues()) {
for (String tableName : tableNames) {
if (tableName.endsWith(value % 2 + "")) {
result.add(tableName);
}
}
}
return result;
}

/**
* sql 中 between 操作时,table的映射
*/
public Collection doBetweenSharding(Collection tableNames,
ShardingValue shardingValue) {
Collection result = new LinkedHashSet(tableNames.size());
Range range = (Range) shardingValue.getValueRange();
for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
for (String each : tableNames) {
if (each.endsWith(i % 2 + "")) {
result.add(each);
}
}
}
return result;
}

}
UserSingleKeyDatabaseShardingAlgorithm.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.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 lyncc
*
*/
public class UserSingleKeyDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm{

/**
* sql 中关键字 匹配符为 =的时候,表的路由函数
*/
public String doEqualSharding(Collection availableTargetNames, ShardingValue shardingValue) {
for (String each : availableTargetNames) {
if (each.endsWith(shardingValue.getValue() % 2 + "")) {
return each;
}
}
throw new IllegalArgumentException();
}

/**
* sql 中关键字 匹配符为 in 的时候,表的路由函数
*/
public Collection doInSharding(Collection availableTargetNames, ShardingValue shardingValue) {
Collection result = new LinkedHashSet(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 doBetweenSharding(Collection availableTargetNames,
ShardingValue shardingValue) {
Collection result = new LinkedHashSet(availableTargetNames.size());
Range range = (Range) 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;
}

}
UserSingleKeyTableShardingAlgorithm.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc.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;

public class UserSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm{

/**
* sql 中 = 操作时,table的映射
*/
public String doEqualSharding(Collection tableNames, ShardingValue shardingValue) {
for (String each : tableNames) {
if (each.endsWith(shardingValue.getValue() % 3 + "")) {
return each;
}
}
throw new IllegalArgumentException();
}

/**
* sql 中 in 操作时,table的映射
*/
public Collection doInSharding(Collection tableNames, 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的映射
*/
public Collection doBetweenSharding(Collection tableNames,
ShardingValue shardingValue) {
Collection result = new LinkedHashSet(tableNames.size());
Range 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;
}

}

spring-database.xml
[html] view plain copy

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-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.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-3.2.xsd">




classpath:config/resource/jdbc_dev.properties



































































spring-sharding.xml
[html] view plain copy

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-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.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-3.2.xsd">
































t_user_0
t_user_1
t_user_2






























t_student_0
t_student_1









































class="org.springframework.jdbc.datasource.DataSourceTransactionManager">







jdbc_dev.properties
[plain] view plain copy
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 =

jdbc_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 =


validationQuery=SELECT 1

log4j.xml
[html] view plain copy




































class="org.apache.log4j.DailyRollingFileAppender">


























好了,到此为止,所有代码都贴出来了,我们开始测试:
ShardingJdbcMybatisTest.java
[java] view plain copy
package com.study.dangdang.sharding.jdbc;

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.study.dangdang.sharding.jdbc.entity.Student;
import com.study.dangdang.sharding.jdbc.entity.User;
import com.study.dangdang.sharding.jdbc.service.StudentService;
import com.study.dangdang.sharding.jdbc.service.UserService;

@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 users = userService.findAll();
if(null != users && !users.isEmpty()){
for(User u :users){
System.out.println(u);
}
}
}

@Test
public void testSQLIN(){
List users = userService.findByUserIds(Arrays.asList(2,10,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();
}


}
testUserInsert的运行结果是:

替换了我们sql中的数据源和表名

testFindAll的运行结果是:

注意:看日记,一共发出了6条sql,也就是说每个库的每个表都发出一条sql,在平常开发中,这种sql还是少执行,会很大程度上降低性能

testSQLIN的运行结果是:

注意:根据id的路由规则,定位到表后,其实此时已经知道该表中的id了,没必要用3个参数的in了,sharding-jdbc这边还不是很智能的,虽然IN也是支持索引的~有待更进一步的优化


最后事务测试也是没有问题的~
大家自己动手来一遍吧~

代码下载地址:http://download.csdn.NET/detail/linuu/9466514

你可能感兴趣的:(通用技术)