NutzCN Logo
精华 nutz中动态切换数据源,请教下怎么实现
发布于 3300天前 作者 slonay117 4365 次浏览 复制 上一个帖子 下一个帖子
标签: dao datasource

我想实现在数据库中动态配置N个数据库,数据库的是随时可以增减的,再把用户分配访问不同的数据库
我现在的思路是在service的方法上做个拦截,如下,在dataSourceInterceptor中去根据loginUser分配的数据源去设置数据源
@IocBean(args = { "refer:dynamicDao" })
public class UsingService extends BaseService {
@Aop({"dataSourceInterceptor"})
public void remove(User loginUser, String id) {
....
}
}
现在出现的问题是我用几个线程去跑分配了不同数据库的用户(A,B)请求去测试,会出现串库的情况,就是A用户按设想本来应该调用A1数据库,但是却调用了B用户对应的数据库,后来看了下nutz的dao是单例,我这种思路应该可能是有问题的,后来看了nutz动态表的实现,想用ThreadLocal去做,看了下能改动比较大,不知道怎么去实现我想要的动态切换数据源的问题了,请教下思路。。。感谢

9 回复

做一个DataSource实现, 类似这样

package net.wendal.nutzbook;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

import javax.sql.DataSource;

import org.nutz.lang.Lang;

public class DyDataSorce implements DataSource{
	
	public static ThreadLocal<DataSource> th = new ThreadLocal<>();
	
	public Connection getConnection() throws SQLException {
		return th.get().getConnection();
	}
	
	// ---------------------------------
	// ---- 其他方法没用
	// ---------------------------------
	
	public PrintWriter getLogWriter() throws SQLException {
		throw Lang.noImplement();
	}

	public void setLogWriter(PrintWriter out) throws SQLException {
		throw Lang.noImplement();
	}

	public void setLoginTimeout(int seconds) throws SQLException {
		throw Lang.noImplement();
	}

	public int getLoginTimeout() throws SQLException {
		throw Lang.noImplement();
	}

	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		throw Lang.noImplement();
	}

	public <T> T unwrap(Class<T> iface) throws SQLException {
		throw Lang.noImplement();
	}

	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		throw Lang.noImplement();
	}

	public Connection getConnection(String username, String password) throws SQLException {
		throw Lang.noImplement();
	}
}

PS: nutz的dao不是单例, 单例那是ioc的说法. 你可以定义N个dao

非常感谢,按照你给的思路问题解决了

学习下,也有这种需求,建议论坛弄个收藏功能!

此处

public static ThreadLocal<DataSource> th = new ThreadLocal<>();

的作用是什么?
小白不太理解。

绑定当前线程的连接池实例

还是有点懵,这么做是怎么能解决楼主的问题呢?
不同的用户a,b,根据自己关联的不同数据源dsa,dsb,直接get不行吗?
和线程有关系?

大概就是根据用户选不同的数据源吧,给个思路而已

	public Connection getConnection() throws SQLException {
                int uid = Mvcs.getSession().get(xxxxx);
                swtich (uid) {
                    case 1: return abc.getConnection();
                    case 1: return def.getConnection();
                    default: return ds.getConnection();
               }
	}

是的,这是我能理解的解决思路。
用ThreadLocal的解决思路,我不大理解 — —!

ThreadLocal的话需要配合其他东西才能搞定, 例如加个Proccessor之类的,预先设置值

添加回复
请先登陆
回到顶部