在Amoeba中使用Oracle的外链接(+)

按照之前一篇博客的方法,配置了Amoeba链接Oracle的集群。在使用过程中遇到了一个问题:Amoeba对外使用的是mysql协议,所以通过Amoeba查询的时候也得使用mysql的SQL语法。Oracle和mysql语法在很多地方还是不一样的,比如今天遇到的问题,Oracle的外链接符号(+)mysql就不认识。今天摸索了半天,找到一个解决办法,虽然不是很完美的方法,不过也能解决问题。

首先我们看看如果在Amoeba里用(+)会怎么样。我们先建两个表用于实验,一个STAFF,只有两列ID和NAME;另一个表INFO,两列ID和AGE,两个表通过ID可以链接。然后再往两个表里随便插一些数据。之后用mysql客户端连接上Amoeba。如果我们查询这个SQL:

SELECT STAFF.ID, STAFF.NAME FROM STAFF, INFO WHERE STAFF.ID=INFO.ID

返回的结果是正确的,结果是从各个DB返回的结果再合并一起的结果。然后,我们查询这个SQL:

SELECT STAFF.ID, STAFF.NAME FROM STAFF, INFO WHERE STAFF.ID=INFO.ID(+)

返回的结果就不对了,看上去只是其中一个DB的结果,而且就是amoeba.xml里defaultPool里配置的那个数据库。

如果我们再看看logs目录下的project.log文件,发现我们查询了上述SQL后Amoeba报出的异常,异常信息就是SQL parse错误。

所以我们大概能猜出是怎么回事:Amoeba试图解析SQL的时候出错了,所以就跳过了我们配置的rule,直接把SQL原封不动地仍给配置的defaultPool。问题是,在amoeba.xml的defaultPool中是只能配置一个pool的,如果能配置多个pool的话,问题就解决了。

经过一番探索,我想出一个办法:改代码。Google Code上下载Amoeba的代码:http://code.google.com/p/amoeba/source/checkout 。我checkout的是trunk.2.0.1,不知道最新版本会不会有什么问题。在amoeba工程里找到com.meidusa.amoeba.route.AbstractQueryRouter类,大概在470行左右的地方,找到:

public void init() throws InitialisationException {
        defaultPools = new ObjectPool[] { ProxyRuntimeContext.getInstance().getPoolMap().get(defaultPool) };
	//......
}

我们欣喜地发现,虽然配置文件里defaultPool只有一个pool,但是在程序里面实际上是先从一个pool的名字,生成一个pool的数组defaultPools。所以我们只要在defaultPool里写多个pool的名字,然后在这个自己解析一下,把多个pool塞进defaultPools里就行了。我们把这段代码改成这样:

    private ObjectPool[] getDefaultPools() {
    	String[] defaultPoolStrs = defaultPool.trim().split("[\\,\\s]+");
    	int size = defaultPoolStrs.length;
    	ObjectPool[] pools = new ObjectPool[size];
    	for(int i=0; i<size; i++) {
    		pools[i] = ProxyRuntimeContext.getInstance().getPoolMap().get(defaultPoolStrs[i]);
    	}
    	return pools;
    }
    
    public void init() throws InitialisationException {
        defaultPools = getDefaultPools();
       //.....
    }

之后在trunk根目录下执行ant编译,在dist/lib下找到编译出来的amoeba-2.0.1-BETA.jar,放在amoeba服务器中amoeba目录下的lib里面。然后在amoeba.xml里,把defaultPool配置成:

<defaultPool>server1,server2,server3</defaultPool>

重新启动Amoeba,再查询带有(+)的SQL,结果就正确了。

这个办法并不是个完美的方法,因为这样查询之后在project.log里面还是有异常信息的。

最正确的方法应该是修改在amoeba-aladdin工程下com.meidusa.amoeba.aladdin.parser.sql包里的AladdinParser类(这个类应该是从AladdinParser.jj文件自动生成的)。具体做法还要以后在研究研究。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值