数据源获取工具
接口
package com.dlq.blog.datasource.interfaces;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* 数据源获取接口
* @author donglq
* @date 2017/10/4 23:20
*/
public interface IDatasourceGetter {
JdbcTemplate getJdbcTemplate(String tablename);
}
实现
package com.dlq.blog.datasource;
import com.dlq.blog.datasource.interfaces.IDatasourceGetter;
import com.google.common.base.CharMatcher;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
/**
* 数据源获取实现
* @author donglq
* @date 2017/10/4 23:20
*/
public class DatasourceGetterImpl implements IDatasourceGetter{
/**数据源**/
private static JdbcTemplate[] templates;
/**默认数据源**/
private static JdbcTemplate defaultTemplate;
private final static DatasourceIndexFunction DATASOURCE_INDEX_FUNCTION = new DatasourceIndexFunction();
/**
* 初始化
* @param datasources 多数据源,有序
* @param defaultdataSource
*/
public DatasourceGetterImpl(DataSource[] datasources, DataSource defaultdataSource) {
Preconditions.checkNotNull(datasources);
Preconditions.checkNotNull(defaultdataSource);
this.defaultTemplate = new JdbcTemplate(defaultdataSource);
this.templates = new JdbcTemplate[datasources.length];
for (int i = 0; i < datasources.length; i++) {
this.templates[i] = new JdbcTemplate(datasources[i]);
}
}
/**
* 数据源获取类
* 根据表名获取JdbcTemplate
*/
private static class DatasourceIndexFunction implements Function<String, JdbcTemplate> {
@Override
public JdbcTemplate apply(String input) {
if (Strings.isNullOrEmpty(input)) {
return defaultTemplate;
}
try {
int digit = Integer.parseInt(CharMatcher.DIGIT.retainFrom(input));
return templates[digit % templates.length];
} catch (NumberFormatException e) {
}
return defaultTemplate;
}
}
/**
* 缓存表名对应的库JdbcTemplate
*/
private static final LoadingCache<String, JdbcTemplate> cache = CacheBuilder.newBuilder().maximumSize(1024).build(
new CacheLoader<String, JdbcTemplate>() {
@Override
public JdbcTemplate load(String key) throws Exception {
return DATASOURCE_INDEX_FUNCTION.apply(key);
}
}
);
/**
* 通过表名获取JdbcTemplate
* @param tablename
* @return
*/
@Override
public JdbcTemplate getJdbcTemplate(String tablename) {
try {
return cache.get(tablename);
} catch (ExecutionException e) {
}
return defaultTemplate;
}
}
测试
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db.properties"/>
</bean>
<!--默认数据源-->
<bean id="default" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbc.mysql.user_03}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<!--配置多数据源-->
<bean id="user_00" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbc.mysql.user_00}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<bean id="user_01" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbc.mysql.user_01}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<bean id="user_02" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbc.mysql.user_02}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<bean id="user_03" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${driver}"/>
<property name="url" value="${jdbc.mysql.user_03}"/>
<property name="username" value="${jdbc.mysql.username}"/>
<property name="password" value="${jdbc.mysql.password}"/>
</bean>
<!--数据源获取类配置-->
<bean id="datasourceGetter" class="com.dlq.blog.datasource.DatasourceGetterImpl">
<constructor-arg index="0">
<list>
<ref bean="user_00"></ref>
<ref bean="user_01"></ref>
<ref bean="user_02"></ref>
<ref bean="user_03"></ref>
</list>
</constructor-arg>
<constructor-arg index="1" ref="default"/>
</bean>
</beans>
测试方法
@Resource
IDatasourceGetter datasourceGetter;
public List<User> getByIdcard(String idcard) {
//获取表明
String tableName = new Function<String, String>() {
@Override
public String apply(String s) {
String suffix = "";
//共8张表,用身份证前6位计算位于哪张表
int tableIndex = Integer.valueOf(s.substring(0, 6)) % 8;
DecimalFormat df = new DecimalFormat();
df.applyPattern("_00");
suffix = df.format(tableIndex);
return "user" + suffix;
}
}.apply(idcard);
List<User> users = datasourceGetter.getJdbcTemplate(tableName).query("select * from " + tableName + " where idcard='" + idcard + "'", new RowMapper<User>() {
@Nullable
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("idcard: " + rs.getString("idcard"));
User user = new User();
user.setId(rs.getInt("id"));
user.setFirstname(rs.getString("firstname"));
user.setLastname(rs.getString("lastname"));
user.setIdcard(rs.getString("idcard"));
user.setAddress(rs.getString("address"));
return user;
}
});
return users;
}