1 概述
需求:
制作一个SQL外部过滤器,即把将要执行的SQL发至外部服务器,外部服务器解析SQL并返回结果标识(ASQL外部过滤器,即把系统将要执行的任何SQL发至外部服务器,外部服务器解析SQL并返回结果标识(A,执行 或 B.执行修改过后的SQL 或 C.不执行报错) ,再进行下一步操作。
注意:本示例来源于实际项目,原始版本是V6,可作为参考性质,也许是不能运行的。 注意:本示例来源于实际项目,原始版本是V6.2,可作为参考性质,也许是不能运行的。
方案说明
如下图所示,自己建立一个JDBC驱动(com 如下图所示,建立一个起中转作用的JDBC驱动(com.demo.jdbc.MSDriver),然后在驱动类中引用自己的类,然后将原驱动 (comMSDriver),在这个驱动中执行上面的过滤逻辑后再转发到原始数据库驱动中执行,为了做到通用,将链接字符串限定为(其中demo可以自己定义):jdbc:demo:原数据库需求:原数据库连接字符串,譬如:
原驱动为: com.mysql.jdbc.Driver)以及连接信息(jdbcDriver
原数据库连接字符串为:jdbc:mysql://localhost:6688.....)拼接在一起(如:jdbc6688,
新的驱动连接字符串就为:jdbc:demo:com.mysql.jdbc.Driver:jdbc:mysql://localhost:6688......),然后再自己的JDBC驱动(com
新的驱动(com.demo.jdbc.MSDriver)中解析并生成对应的原来的驱动(comMSDriver)会解析这个连接字符串,并生成对应的原来的驱动(com.mysql.jdbc.Driver),这样的话就能达到SQL在访问数据库之前先经过自己定义的JDBC驱动,再走原驱动,从而可以达到中间过滤的功能Driver),这样的话就能达到SQL在访问数据库之前先经过自己定义的JDBC驱动,再走原驱动,从而可以达到中间过滤的功能。
实现方案:
1,新建一个扩展包,参考 插件开发架构
2、新建一个Module类2、新建一个Module类,见自定义Module
com.demo.jdbc.SQLFilterModule 实现 smartbi.framework.IModule
该类主要功能是将当前sql发送给外部服务器,并返回结果,具体代码如下 该类主要提供实现将当前sql发送给外部服务器,并返回结果的方法,具体代码如下
代码块 | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package com.demo.jdbc; import java.io.IOException; import java.util.HashMap; import org.apache.log4j.Logger; import smartbi.framework.IModule; import smartbi.net.sf.json.JSONObject; import smartbi.util.HttpUtil; /** * 处理sql过滤逻辑,可视为工具类 * @author smartbi * */ public class SQLFilterModule implements IModule { private static final Logger log = Logger.getLogger(SQLFilterModule.class); private static SQLFilterModule instance = new SQLFilterModule(); public static SQLFilterModule getInstance() { return instance; } /** * module类初始化方法 */ @Override public void activate() { } /** * sql过滤拦截 * @param sql 目前访问的sql语句 * @param driverInfo 驱动信息 * {"jdbc":"com.mysql.jdbc.Driver","url":"jdbc:mysql//localhost:6688/....","user":"admin","password":"psd"} * @return */ public JSONObject isSQLFilter(String sql , HashMap<String, String> driverInfo){ //传递参数,例如SQL或者JDBC驱动信息等 HashMap<String, String> map = new HashMap<String, String>(); map.put("sql", sql); String url = driverInfo.get("url"); map.put("jdbcInfo","{\'"+url+"\'}"); log.info("访问sql过滤服务器参数:"+map.toString()); String ret; try { ret = HttpUtil.doPost("http://localhost:8080/demo", map); log.error("访问sql过滤服务器返回结果:"+ret); if(ret != null){ //ret 为 "{}" JSONObject jsonObj = new JSONObject(ret); if(jsonObj != null){ return jsonObj; } } } catch (IOException e) { log.error(e.getMessage(),e); } return null; } } |
...
com.demo.jdbc.MSPreparedStatement 实现 java.sql.PreparedStatement接口
当实现接口方法时,必须实现这个接口的方法,在此说说一个eclipse的小技巧,当新建一个MSDriver实现Driver的接口, 当实现接口时,必须实现这个接口的所有方法,在此说说一个eclipse的小技巧,让自动生成实现方法,需要改写的再去改写,当新建一个MSDriver实现Driver的接口,
声明一个Driver driver,
...