1.配置数据库连接池参数
sharding.jdbc.datasource.names=shardingdruiddatasource
sharding.jdbc.datasource.shardingdruiddatasource.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.shardingdruiddatasource.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.shardingdruiddatasource.url=jdbc:mysql://120.
sharding.jdbc.datasource.shardingdruiddatasource.username=root
sharding.jdbc.datasource.shardingdruiddatasource.password=root
default.jdbc.datasource.driver-class-name=com.mysql.jdbc.Driver
druid.initialSize=10
druid.maxActive=120
druid.minIdle=10
druid.maxWait=10000
druid.validationQuery=SELECT 1 from dual
druid.testWhileIdle=true
druid.testOnBorrow=false
druid.testOnReturn=false
druid.timeBetweenEvictionRunsMillis=60000
druid.minEvictableIdleTimeMillis=14400000
druid.maxEvictableIdleTimeMillis=28800000
druid.removeAbandoned=true
druid.removeAbandonedTimeout=1800
druid.logAbandoned=true
druid.filters=stat
2.导入依赖
```java
<properties>
<shardingsphere.version>3.0.0.M4</shardingsphere.version>
<druid.version>1.1.12</druid.version>
</properties>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${shardingsphere.version}</version>
</dependency>
3.配置数据库表路由
```java
public class ShardingTableConfig {
private final static Integer SHARDING_USER_TABLE_TOTAL = 3;
public static TableRuleConfiguration getUserTableRuleConfiguration() {
TableRuleConfiguration tableConfig = new TableRuleConfiguration();
StandardShardingStrategyConfiguration shardingStrategyConfig = new StandardShardingStrategyConfiguration(
"openid", new ShardingAlgorithm());
tableConfig.setLogicTable("t_mobile_user");
tableConfig.setActualDataNodes(
String.format("shardingdruiddatasource.t_mobile_user${0..%d}", SHARDING_USER_TABLE_TOTAL - 1));
tableConfig.setTableShardingStrategyConfig(shardingStrategyConfig);
tableConfig.setKeyGeneratorColumnName("id");
return tableConfig;
}
}
4.配置数据分片算法
public class ShardingAlgorithm implements PreciseShardingAlgorithm<String> {
/**
* Sharding.
*
* @param availableTargetNames available data sources or tables's names
* @param shardingValue sharding value
* @return sharding result for data source or table's name
*/
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
long hashCode = HashUtils.fnvHash(shardingValue.getValue().toString());
int index =(int)Math.abs(hashCode % availableTargetNames.size());
ArrayList<String> candidateCollect = new ArrayList<>(availableTargetNames);
String item = candidateCollect.get(index);
log.info("shardingValue = {} 被哈希到的表为:{}", shardingValue, item);
return item;
}
}
public class HashUtils {
public static long hash(String key) {
// TODO 实现哈希算法
return "".hashCode();
}
public static long fnvHash(String data) {
int p = 16777619;
long hash = 2166136261L;
for (int i = 0; i < data.length(); i++) {
hash = (hash ^ data.charAt(i)) * p;
}
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return hash;
}
public static String md5Encode(String msg) throws Exception {
byte[] msgBytes = msg.getBytes("utf-8");
// 声明使用Md5算法,获得 MessageDigest 对象
MessageDigest md5 = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
md5.update(msgBytes);
// 完成哈希计算,获得密文
byte[] digest = md5.digest();
return byteArray2HexString(digest);
}
/**
* 将byte数组转化为16进制字符串形式
*
* @param bytes 比特数组
* @return 16进制格式字符串
*/
private static String byteArray2HexString(byte[] bytes) {
StringBuffer buffer = new StringBuffer(bytes.length * 2);
int val;
for (int i = 0; i < bytes.length; i++) {
//将byte转化为int 如果byte是一个负数就必须要和16进制的0xff做一次与运算
val = ((int) bytes[i]) & 0xff;
if (val < 16) {
buffer.append("0");
}
buffer.append(Integer.toHexString(val));
}
return buffer.toString();
}
}
5.添加配置类
/**
* 需要分表的数据源
*
* @author Hurrican
* @Date 2019/1/28 10:59
* @since 1.0.0
*/
@Configuration
@MapperScan(basePackages = "com.huaer.welfare.mapper", sqlSessionFactoryRef = "shardingSqlSessionFactory")
@PropertySource("classpath:jdbc.properties")
public class ShardingDatasourceConfig {
private static final String MAPPER_LOCATION = "classpath:sqlmap/**/*.xml";
private static final String CONFIG_LOCATION = "classpath:dataMapperConfig.xml";
@Value("${sharding.jdbc.datasource.shardingdruiddatasource.url}")
private String url;
@Value("${sharding.jdbc.datasource.shardingdruiddatasource.username}")
private String user;
@Value("${sharding.jdbc.datasource.shardingdruiddatasource.password}")
private String password;
@Value("${sharding.jdbc.datasource.shardingdruiddatasource.driver-class-name}")
private String driverClass;
@Bean(name = "shardingDataSource")
public DataSource getShardingDruidDataSource(@Qualifier("commonDruidProp") DruidProp druidProp )
throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setMaxActive(druidProp.getMaxActive());
dataSource.setMinIdle(druidProp.getMinIdle());
dataSource.setMaxWait(druidProp.getMaxWait());
dataSource.setInitialSize(druidProp.getInitialSize());
dataSource.setTestWhileIdle(druidProp.getTestWhileIdle());
dataSource.setTestOnBorrow(druidProp.getTestOnBorrow());
dataSource.setTestOnReturn(druidProp.getTestOnReturn());
dataSource.setRemoveAbandoned(druidProp.getRemoveAbandoned());
dataSource.setRemoveAbandonedTimeout(druidProp.getRemoveAbandonedTimeout());
dataSource.setTimeBetweenEvictionRunsMillis(druidProp.getTimeBetweenEvictionRunsMillis());
dataSource.setMinEvictableIdleTimeMillis(druidProp.getMinEvictableIdleTimeMillis());
dataSource.setMaxEvictableIdleTimeMillis(druidProp.getMaxEvictableIdleTimeMillis());
dataSource.setLogAbandoned(druidProp.getLogAbandoned());
dataSource.setValidationQuery(druidProp.getValidationQuery());
dataSource.setConnectionErrorRetryAttempts(druidProp.getConnectionErrorRetryAttempts());
HashMap<String, DataSource> dataSourceMap = new HashMap<>(4);
dataSourceMap.put("shardingdruiddatasource", dataSource);
ArrayList<TableRuleConfiguration> tableRuleConfigs = new ArrayList<>(4);
tableRuleConfigs.add(ShardingTableConfig.getUserTableRuleConfiguration());
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.setTableRuleConfigs(tableRuleConfigs);
// ConfigMap用于配置读写分离
HashMap<String, Object> configMap = new HashMap<>(4);
// sql.show 用于调试输出分表的真实SQL语句
Properties props = new Properties();
// props.setProperty("sql.show", "true");
props.setProperty(ShardingPropertiesConstant.MAX_CONNECTIONS_SIZE_PER_QUERY.getKey(), "21");
props.setProperty(ShardingPropertiesConstant.EXECUTOR_SIZE.getKey(), "20");
return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, configMap, props);
}
@Bean(name = "shardingSqlSessionFactory")
public SqlSessionFactory shardingSqlSessionFactory(@Qualifier("shardingDataSource") DataSource shardingDataSource)
throws Exception {
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
configuration.setMapUnderscoreToCamelCase(true);
sessionFactory.setConfiguration(configuration);
sessionFactory.setDataSource(shardingDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
// sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(CONFIG_LOCATION));
return sessionFactory.getObject();
}
// 创建该数据源的事务管理
@Bean(name = "primaryTransactionManager")
public DataSourceTransactionManager primaryTransactionManager(
@Qualifier("shardingDataSource") DataSource shardingDataSource) throws SQLException {
return new DataSourceTransactionManager(shardingDataSource);
}
@Bean(name = "shardingSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory shardingSqlSessionFactory) {
return new SqlSessionTemplate(shardingSqlSessionFactory);
}
源码阅读:
1.根据hash算法获取最终访问的表
|
2.将原来sql中的表名替换成由hash算法获取到的表名
|
|
|
3.调用mybatis excute方法执行sql语句
|
调用query方法查询
|
获取查询结果
|