sqlyog打开mycat表异常

来源:互联网 发布:linux semaphore 编辑:程序博客网 时间:2024/05/19 23:15

sqlyog打开mycat表会报异常:
这里写图片描述
select * from TESTDB.company limit 0, 30;
前面加了数据库名就不能访问了,只能用 sql 访问。
原因是因为mycat把TESTDB这个数据库名称也传到了mysql中,但是mysql里面是不存在这个数据库的,就报异常了( 调试的结果,个人分析的结论是这个,不一定就对)
navicat工具打开不会有这种异常,因为它发送的是select * from company limit 0, 30;就是这两个工具的差异,当然对这一条查询还会带上其他的sql语句,喜欢捣鼓的可以调试下,就是下面介绍的会输出到控制台上

重点:写过一个默认的拦截器,或者直接在源码上修改
复制io.mycat.server.interceptor.impl.DefaultSqlInterceptor.java重命名成一个新的类(我的是me.MySqlInterceptor.java),或者直接在这个类上修改:
interceptSQL()方法里面第一行添加:
System.out.println(“*我拦截的sql: “+sql+” 类型: “+sqlType);
if(sqlType==7||sqlType==9){//暂时就发现这两个类型时sqlyog会报错,刚开始学,还没发现别的
SubSql ss=new SubSql(sql);//类在下面
sql=ss.getNewSql();
}
这里写图片描述

如果是重写的类,要到mycat的server.xml的system标签里面添加一行(比如我的,是拦截器类路径):
me.MySqlInterceptor
这里写图片描述
默认的拦截器就不用添加了,已经默认了DefaultSqlInterceptor.java

重新写过的类,可以自己生成jar包放到mycat服务器lib目录下,应该就可以跑了,我没这样干,至少理论上是不会错的
package me;

import java.util.ArrayList;
import java.util.List;

/**
* Created by lzf on 2017/9/9.
*/
public class SubSql {
private static final String FULL_STOP=”.”;
//添加表名前面可能出现的关键字,这里就列举了一部分
private static final List MARK_STRING=new ArrayList() {{
add(“FROM “);
add(“from “);
add(“update “);
add(“into “);
add(“show create table “);
}};
private String newSql;

public SubSql(String sql) {    this.newSql=sql;    handle(sql);}public static void main(String[] args) {

// update TESTDB.company set id = ‘21’ where id = ‘1’
// delete from TESTDB.company where id = ‘21’
// select * from TESTDB.company limit 0, 100
String sql1=”SELECT * FROM TESTDB.company where s from a.b”;
SubSql ss=new SubSql(sql1);
System.out.println(“新sql: “+ss.getNewSql());

    String sql2="show create table `TESTDB`.`company`";    SubSql ss2=new SubSql(sql2);    System.out.println("新sql: "+ss2.getNewSql());}public void handle(String sql){            System.out.println("*****需要执行的语句: " + sql);                   boolean isJudge=false;    if(sql.indexOf(FULL_STOP)>0){        for(String mark:MARK_STRING){            if(sql.indexOf(mark)>-1){                judge(sql,mark);                isJudge=true;            }        }    }    if(isJudge==true) {        System.out.println("*****过滤掉表名后的语句: " + this.getNewSql());    }}//分类去除public void judge(String sql,String fromType){    String [] ss=sql.split(fromType);    for(int i=0;i<ss.length;i++){        if(i>0){            //取出表名            String a=ss[i].trim().split(" ")[0];            String newa=getTableName(a);            newSql=newSql.replace(a,newa);        }    }}//返回表名public String getTableName(String s){    String tablename=s.split(" ")[0];;    if(tablename.indexOf(".")>0){        String [] sss=tablename.split("\\.");

// System.out.println(“表名:”+sss[1]);
return sss[1];
}else{
// System.out.println(“表名:”+s);
return s;
}
}

public String getNewSql() {    return newSql;}public void setNewSql(String newSql) {    this.newSql = newSql;}

}
这样sqlyog就可以打开mycat表了(如果不能打开,看看mysql里面有没有建立相关的数据库和表,根据schma.xml的建)
这里写图片描述

如果有其他的语句会导致异常,可以继续修改类使之符合要求
SELECT * FROM zz.company;也能查了,跟数据库名没关系了
按我的设想,应该是换成对应的mysql里面的数据库名称
测试环境中可以这么玩,别放到实际业务上,这做法很可能会导致某些关键性错误,只是为了用sqlyog才玩的(出事了别找我…)
建议还是用navicat

原创粉丝点击