今天遇到了一个问题,就是当初设计系统的时候,本来只用一个数据库的,
但由于用户新增的一些需求,必须要用两个数据库,而且要根据用户登陆选择的年份连接不同的数据库,大家知道会发生什么麻烦了吧,就是当初设计的数据库接口(dao层)都没有什么信息区分连接那个数据库的,但代码都已经写了好多,不可能每个修改每个调用的地方传入数据库信息(不是没可能,工作量大,而且时间紧项目都这样),得想个办法。
在网上大概看过ThreadLocal的用法 ,看看ThreadLocal是什么:
ThreadLocal是什么 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。线程局部变量并不是Java的新发明,在其它的一些语言编译器实现(如IBM XL FORTRAN)中,它在语言的层次提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支持,所以,在Java中编写线程局部变量的代码相对比较笨拙,这也许是线程局部变量没有在Java中得到很好的普及的一个原因吧。
我们知道,对于每个请求容器都会开一个线程去处理,从servlet到数据库层都是同一个线程,通过ThreadLocal可以把变量在各个层共享,通过这一特性就可以解决我的问题了。
首先我实现一个filter(不知道什么是filter?),使得所有请求都通过这个filter,在filter里面获取用户选择的年份,实际上通过年份就知道了连接哪个数据库,因为系统的数据源名称是通过年份来区分的,根据年份获得数据源名称(jndi name),把jndi name存放在ThreadLocal里面。接着就要在获取数据库连接的地方获得这个jndi name。还好,程序员规范遵循得好(真的深深体会编码规范的重要性),大家统一调用同一个类来获得数据库连接,这就好办,在获取数据库连接的地方通过ThreadLocal取回jndi name,这样就获得了正确的数据库连接,代码改动量也不多。
ThreadLocal的代码如下,很简单:
public class DnsThread(){
private static ThreadLocal tl=new ThreadLocal ();//私有静态变量
public static Object get(){
return tl.get();
}
public static void set(Object object){
tl.set(object);
}
}
在filter里面调用
DnsThread.set("dns2005");
在获取数据库连接的地方调用
String dns=(String)DnsThread.set("dns2005");
这只是一个简单的应用,但它确实解决了实际问题
还有其他一些用法,像事务处理,通过共享Connection来实现
posted on 2005-08-19 00:34
java time 阅读(4004)
评论(3) 编辑 收藏 所属分类:
j2ee技术