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


新建Maven项目



pom.xml


  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:

/*
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

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

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

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

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




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

UserMapper.xml




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

StudentService.java

package com.study.dangdang.sharding.jdbc.service;

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

public interface StudentService {

    boolean insert(Student student);

}

UserService.java

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

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

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

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

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

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

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



		
	
		
			
				classpath:config/resource/jdbc_dev.properties
			
		
	
		
	
		
		
		

		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	
	
		
		
		

		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	
	



spring-sharding.xml



		
	
    
    
    
    
        
        
    
    
    
     
        
        
    
    
    
    
    
        
            
                
                
            
        
    
    
    
    
        
        
            
                t_user_0
                t_user_1
                t_user_2
            
        
        
        
        
    
    
    
    
        
        
            
        
    
    
    
    
        
        
            
        
    
    
    
    
      
    
        
        
            
                t_student_0
                t_student_1
            
        
        
        
        
    
    
     
    
        
        
            
        
    
    
    
    
        
        
            
        
    
    
    
    
    
        
        
            
                
                
            
        
    
    
    
    
        
    

    
    
        
    

    
		


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 = 

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

    
  
  
    
    
       
       
       
         
       
    
  
    
    
       
       
       
       
       
      
       
     
  
     
     
       
       
       
       
       
       
          
       
     
  
     
     
       
       
       
       
       
      
       
     
  
     
     
        
        
        
     
  
     
     
         
         
         
        
        
     
  

好了,到此为止,所有代码都贴出来了,我们开始测试:

ShardingJdbcMybatisTest.java

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



你可能感兴趣的:(spring源码,开源框架)