欲通过数据中的特殊标记,将数据存放在不同数据库中。
情节描述:
项目中数据库操作都相同,就是库 不一样。
网上很多都是AOP切换DataSource,之前博文也写了个Springboot+AOP实现。但是这个项目只需要处理点数据然后 存入数据库,感觉太费事。
原来想将数据中的标记,作为参数传入最后Dao层。但是需要修改地方过多,所以想用Threadlocal试试。对应线程,将数据标记存入其Threadlocal中,在Dao层操作的时候,获取Threadlocal中的数据标记,建立对应session连接,将数据存入数据库中。
我不知道这样会有什么后果,多线程测试起来,感觉没有啥毛病,线程理清楚就好,但是感觉性能可能不高。
Threadlocal
package com.siger.storm.model;
public class TableName {
public static ThreadLocal<String> tablename = new ThreadLocal<>();
public static void setTableName(String cid_pid) {
tablename.set(cid_pid);
}
public static String getTableName() {
return tablename.get();
}
public static void removeTableName() {
tablename.remove();
}
}
业务类
业务处理的时候涉及数据库操作,将数据中标记存入ThreadLocal中
创建SqlSession
MybatisUtils
原来是单数据库,静态代码块加载sessionFactory
但是现在由于需要通过Threadlocal获取的参数,创建对应的数据库连接。
这里我不知道如何处理才是效率最高
package com.siger.storm.utils;
import com.siger.storm.model.TableName;
import org.apache.commons.math3.exception.MathIllegalNumberException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.storm.shade.org.joda.time.Seconds;
import java.io.IOException;
import java.io.Reader;
import java.util.concurrent.ConcurrentHashMap;
public class MybatisUtil {
public static final Logger log = LogManager.getLogger(MybatisUtil.class);
private static SqlSessionFactory sessionFactory;
static Reader reader = null;
/**
* @admin Nero
* @date 2020-5-25
*
* */
public static ConcurrentHashMap sessionHashMap = new ConcurrentHashMap();
public static synchronized SqlSession getSqlSession() {
SqlSession session = null;
try {
if (sessionHashMap.get(TableName.getTableName()) != null) {
sessionFactory = (SqlSessionFactory) sessionHashMap.get(TableName.getTableName());
if (sessionFactory.openSession() != null) {
session = sessionFactory.openSession();
}
} else {
reader = Resources.getResourceAsReader("mybatis-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(reader, TableName.getTableName());
if (sessionFactory != null) {
log.error("创建sessionFactory----------" + sessionFactory);
sessionHashMap.put(TableName.getTableName(), sessionFactory);
session = sessionFactory.openSession();
if (sessionFactory.openSession() != null) {
session = sessionFactory.openSession();
}
} else {
log.error("sessionFactory is null");
}
}
} catch (Exception e) {
log.error(e.getMessage() + "catch Exception");
}
return session;
}
}
Mybatis.xml中对应的数据库配置
<environments default="development">
<environment id="test1">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${test1.mysql.jdbc.driver}"/>
<property name="url" value="${test1.mysql.url}"/>
<property name="username" value="${test1.mysql.user}"/>
<property name="password" value="${test1.mysql.password}"/>
<property name="poolPingEnabled" value="true"/>
<property name="poolPingQuery" value="SELECT NOW()"/>
<property name="poolPingConnectionsNotUsedFor" value="3600000"/>
</dataSource>
</environment>
<environment id="test2">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${test2.mysql.jdbc.driver}"/>
<property name="url" value="${test2.mysql.url}"/>
<property name="username" value="${test2.mysql.user}"/>
<property name="password" value="${test2.mysql.password}"/>
<property name="poolPingEnabled" value="true"/>
<property name="poolPingQuery" value="SELECT NOW()"/>
<property name="poolPingConnectionsNotUsedFor" value="3600000"/>
</dataSource>
</environment>
</environments>