一个信息系统查询必不可少,如果是定制化的开发那么查询语句还可能是经常变动的;IBATIS提供了这样的sql配置查询的功能;这里有另一种解决方案:利用JAVA动态编译的方式实现SQL语句的配置化!

SQL的拼装有时候会很复杂,这个时候如何使用IBATIS的话,就不得不深入学习他的语法,对于新手来说上手就变得困难啦。如果有一种方案可以配置SQL在XML文件中,同时又使用JAVA的语法来拼SQL,那该多好。

利用JAVA动态编译的方式实现SQL语句的配置化!!!

/**
* 编译文件
*
* @param file
* @throws Exception
*/
private String compileFile(File file) throws Exception {
String classPath = getClassPath();
String[] arg = {"-classpath", classPath, "-d", classPath,
file.getAbsolutePath() };
StringWriter writer = new StringWriter(1024);
int code = com.sun.tools.javac.Main.compile(arg,
new PrintWriter(writer));
return code == 0 ? "0" : writer.toString();
}

/**
* 创建实例
*
* @param file
* @return
* @throws Exception
*/
private SqlBuilder createInstance(File file) throws Exception {
String filename = file.getName();
String classname = filename.substring(0, filename.lastIndexOf('.'));
return (SqlBuilder) Class.forName(packageName + "." + classname)
.newInstance();
}

/**
* 删除临时文件
*
* @param file
* @throws Exception
*/
private void removeTempFile(File file) throws Exception {
String classDir = getClassDir();
int last = file.getName().lastIndexOf('.');
String name = file.getName().substring(0, last);
String classFile = classDir + File.pathSeparator + name + ".java";
String javaFile = classDir + File.pathSeparator + name + ".class";
new File(javaFile).delete();
new File(classFile).delete();
}

/**
* 取得Class路径
*
* @return
*/
private String getClassPath() {
//URL url = this.getClass().getResource("/");
URL url = Thread.currentThread().getContextClassLoader().getResource("/");
File file = new File(url.getPath());
return file.getAbsolutePath();
}

/**
* 生成 JAVA代码片段
* @param classname
* @param sqlCode
* @return
*/
private String getJavaCode (String classname ,String sqlCode ){
StringBuffer code = new StringBuffer(1024);
code.append("\npackage " + packageName + "; \n");
code.append("public class " + classname + " implements "
+ superClass + "{\n");
code.append(" public String getSql(java.util.Map map) throws Exception{ \n");
code.append(" " + sqlCode + " \n");
// 兼容配置中有return语句的SQL
if (!sqlCode.contains("return ")) {
code.append(" return sql.toString();\n");
}
code.append(" }\n");
code.append("}\n");
return code.toString();
}



/**
* 取得Java路径
*
* @return
*/
private String getClassDir() {
return getClassPath() + "/" + packageName;
}

/**
* 验证 JAVA语法
* @param sqlCode
* @return
* @throws Exception
*/
public String validateJavaCode ( String sqlCode) throws Exception {
log.info("################ Class Dir[" + getClassDir()
+ "] #################");
File file = createFile(sqlCode);
String classname = file.getName().substring(0, file.getName().lastIndexOf('.'));
try {
Debug debug = new Debug("Dyna Complie");
debug.start("ComplieFile");
String result = compileFile(file);
if (!"0".equals(result)) {
// 保存错误信息
return "语法验证不通过:\n【\n" + getJavaCode(classname,sqlCode) + "\n】\n"+"验证信息如下:\n【\n" + result + "\n】\n";
}
debug.end("ComplieFile");
log.info(debug);
return "语法验证通过:\n【\n" + getJavaCode(classname,sqlCode) + "\n】\n" ;
} catch (Exception e) {
log.error(e);
return ("\n【\n" + getJavaCode(classname,sqlCode) + "\n】\n");
} finally {
removeTempFile(file);
}
}

更多相关文章

  1. 每条sql语句实际上都是一个事物(事物多种类型解读)
  2. sql 语句 更改默认的sql server 数据库
  3. 怎么用SQL语句实现表中的一个字段加1啊??
  4. PHP获取MySQL执行sql语句的查询时间
  5. MySQL数据库SQL语法
  6. 删除2行1 Sql语句mysql
  7. 使用IN语句缓慢mysql删除查询
  8. 1.4.6 收集sql语句的执行计划 2
  9. 在SQL SELECT语句中重用别名字段

随机推荐

  1. 将敏感数据存储在数据库中,建议
  2. 查找setTimeout()中剩下的时间?
  3. 自定义ComboBox焦点不会切换到选择elem并
  4. 如何在v模型更改时触发事件? (vue js)
  5. Python 内置函数及excel操作
  6. 将所有域添加到CORS的安全隐患(Access-Con
  7. python正则表达式
  8. 某老师给我的javascript学习建议
  9. AngularJS:TypeError:无法读取未定义的属性
  10. 前端开发命名规范(html+css+js)