环境:oracle-11g ,ibatis-2.0 ,java-1.7

  最近因为有个需要是在程序中得到ibatis到sql字符串,即通过以下的ibatis配置得到sql语句

  <select id="queryColumn" parameterClass="map" resultClass="hashMap">
SELECT column_name as id ,comments as name FROM user_col_comments
WHERE table_name=#table_name#
<isNotEmpty prepend="and" property="a0100">
column_name=#a0100#
</isNotEmpty>
</select>

  我想通过这个得到形如以下的语句

    SELECT column_name as id ,comments as name FROM     user_col_comments    WHERE table_name='a01' and column_name='a0100'

  主要思路是通过lbatis的Sql类得到SqlTxt和SqlTag,然后自己拼接sql语句。下面是我的方法,其中ParamMap是我自定义的类继承了Map。

  根据版本不同可能具体的类也不同,以下只是提供一种思路

  直接贴代码:

public class IbatisUtil {
/**
* @Title getSqlStr
* @Descript :根据xml中的id得到执行时的sql语句
* @date : 2017-08-30 15:07:01
* @param
* @return java.lang.String
* @throws
* @version V1.0
*/
public String getSqlStr(SqlMapClient aqlMapClient, String sqlStatement, ParamMap map)map throws Exception {
StringBuffer sqlBuffer=new StringBuffer();
DynamicSql sql=getSql(aqlMapClient,sqlStatement);//得到sql
List list=getChildren(sql);//得到children
String str=getChlidrenStr(list,map);
sqlBuffer.append(str);
return sqlBuffer.toString();
}
/**
* @Title getSql
* @Descript :得到动态的sql
* @date : 2017-08-30 15:07:45
* @param
* @return com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql
* @throws
* @version V1.0
*/
private DynamicSql getSql(SqlMapClient aqlMapClient,String sqlStatement) {
return (DynamicSql)(((SqlMapClientImpl)aqlMapClient).getDelegate().getMappedStatement(sqlStatement).getSql());
}
/**
* @Title getChildren
* @Descript :得到对象的私有属性childen的值 该对象只能是 DynamicSql和SqlTag否则返回null
* @date : 2017-08-30 15:13:08
* @param
* @return java.util.List
* @throws
* @version V1.0
*/
private List getChildren(Object obj) throws NoSuchFieldException, IllegalAccessException {
if(!(obj instanceof DynamicSql || obj instanceof SqlTag))
return null;
Class classs=obj.getClass();
Field field=classs.getDeclaredField("children");
field.setAccessible(true);
return (List)field.get(obj);
}
private String getChlidrenStr(List list,ParamMap map) throws NoSuchFieldException, IllegalAccessException {
StringBuffer sb=new StringBuffer();
for(Object obj :list){
if(obj instanceof SqlText){
sb.append(getSqlTextStr((SqlText)obj,map));
}else if(obj instanceof SqlTag){
sb.append(getSqlTagStr((SqlTag)obj,map));
}
}
return sb.toString();
}
/**
* @Title getSqlTextStr
* @Descript :解析SqlText
* @date : 2017-08-30 15:18:38
* @param
* @return java.lang.String
* @throws
* @version V1.0
*/
private String getSqlTextStr(SqlText sqlText, ParamMap map){
String sqlTemp;
ParameterMapping[] parameterMappings = sqlText.getParameterMappings();
sqlTemp = sqlText.getText().toString();
if (parameterMappings != null && parameterMappings.length > 0) {
Object obj;
int i;
for (ParameterMapping param : parameterMappings) {
i=param.getJdbcType();
switch (i){
case 0://为定义
obj="'"+map.getAsString(param.getPropertyName())+"'";
break;
case 4://INTEGER
obj=map.getAsInteger(param.getPropertyName());
break;
case 12://VARCHAR
obj="'"+map.getAsString(param.getPropertyName())+"'";
break;
case 93://TIMESTAMP
obj="to_date('yyyy-MM-dd','"+map.getAsString(param.getPropertyName())+"')";
break;
default:obj="";
}
if(ValidateUtil.isEmpty(obj))
obj="";
sqlTemp = sqlTemp.replaceFirst("\\?",obj.toString());
}
}
return sqlTemp;
}
/**
* @Title getSqlTagStr
* @Descript :解析SqlTag
* @date : 2017-08-30 15:24:29
* @param
* @return java.lang.String
* @throws
* @version V1.0
*/
private String getSqlTagStr(SqlTag sqlTag,ParamMap map) throws NoSuchFieldException, IllegalAccessException {
StringBuffer sb=new StringBuffer();
List list=getChildren(sqlTag);
String tagName=sqlTag.getName();
switch (tagName){
case "isNotEmpty":
if(ValidateUtil.isEmpty(map.getAsString(sqlTag.getPropertyAttr())))
return "";
if(ValidateUtil.isNotEmpty(list)){
if(ValidateUtil.isNotEmpty(sqlTag.getPrependAttr()))
sb.append(" "+sqlTag.getPrependAttr() +" ");
sb.append(getChlidrenStr(list,map));
}
break;
case "isEmpty":
if(ValidateUtil.isNotEmpty(map.getAsString(sqlTag.getPropertyAttr())))
return "";
if(ValidateUtil.isNotEmpty(list)){
if(ValidateUtil.isNotEmpty(sqlTag.getPrependAttr()))
sb.append(" "+sqlTag.getPrependAttr() +" ");
sb.append(getChlidrenStr(list,map));
}
break;
}
return sb.toString();
}
}

Ibatis在运行期得到可执行到sql的更多相关文章

  1. Apache Spark源码走读之3 -- Task运行期之函数调用关系分析

    欢迎转载,转载请注明出处,徽沪一郎. 概要 本篇主要阐述在TaskRunner中执行的task其业务逻辑是如何被调用到的,另外试图讲清楚运行着的task其输入的数据从哪获取,处理的结果返回到哪里,如何 ...

  2. JVM(1)---虚拟机在运行期的优化策略

    1.解释器与JIT编译器 首先我们先来了解一下运行在虚拟机之上的解释器与JIT编译器.当我们的虚拟机在运行一个java程序的时候,它可以采用两种方式来运行这个java程序: 采用解释器的形式,也就是说 ...

  3. C++学习笔记28:运行期型式信息

    RTTI 运行期标识对象的型式信息 优势:允许使用指向基类的指针或引用自如地操作派生类的对象 typeid:获取表达式的型式:type_info:型式信息类 头文件:typeinfo 对象转型模板 d ...

  4. effective OC2.0 52阅读笔记(二 对象、消息、运行期)

    第二章:对象.消息.运行期 6 理解属性这一概念 总结:OC解决硬编码偏移量问题的做法,一种方案是把实例变量当做一种存储偏移量所用的特殊变量,交由类对象保管,偏移量会在运行期查找,叫做稳固的“应用程序 ...

  5. iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期

    1. 属性 在开发过程中经常要用到定义属性,@property和@synthesize是经常用到的属性, property在.h文件中作声明,@synthesize在.m文件中用于实现 // Stud ...

  6. Access Violation分成两大类:运行期和设计期(很全的解释)

    用Delphi开发程序时,我们可以把遇到的Access Violation分成两大类:运行期和设计期. 一.设计期的Access Violation 1.硬件原因  在启动或关闭Delphi IDE以 ...

  7. 深入了解JVM虚拟机8:Java的编译期优化与运行期优化

    java编译期优化 java语言的编译期其实是一段不确定的操作过程,因为它可以分为三类编译过程:1.前端编译:把.java文件转变为.class文件2.后端编译:把字节码转变为机器码3.静态提前编译: ...

  8. C++编译期多态与运行期多态

    前言 今日的C++不再是个单纯的"带类的C"语言,它已经发展成为一个多种次语言所组成的语言集合,其中泛型编程与基于它的STL是C++发展中最为出彩的那部分.在面向对象C++编程中, ...

  9. Effective Objective-C 2.0 — 第二章 对象、消息、运行期 - 第六条:理解“属性”这一概念

    开发者通过对象来 存储并传递数据. 在对象之间传递数据并执行任务的过程就叫做“消息传递”. 这两条特性的工作原理? Objective-C运行期环境(Objective-C runtime) ,提供了 ...

随机推荐

  1. Linux常用命令学习随笔

    1.ls命令 就是list的缩写,通过ls 命令不仅可以查看linux文件夹包含的文件,而且可以查看文件权限(包括目录.文件夹.文件权限)查看目录信息等等 常用参数搭配: ls -a 列出目录所有文 ...

  2. springMVC常用注解的使用

    一.@ResponseBody注解的使用 1. @responseBody注解的作用是将controller的方法返回的对象通过适当的转换器,转换为指定的格式之后, 写入到response    对象 ...

  3. 树(2)-----leetcode(层、深度、节点)

    1.树的类实现: class TreeNode(object): def __init__(self, x): self.val = x self.left = None self.right = N ...

  4. Project Euler 19 Counting Sundays( 蔡勒公式计算星期数 )

    题意:在二十世纪(1901年1月1日到2000年12月31日)中,有多少个月的1号是星期天? 蔡勒公式:计算 ( year , month , day ) 是星期几 以下图片仅供学习! /****** ...

  5. react 简单在页面中输出一段文字

    之前用脚手架创建了一个react项目,将react自带的src文件夹删除后创建一个空的src文件夹 在src文件夹中创建一个index.jsx文件作为JS入口文件并创建一个hello组件 现在我们进入 ...

  6. robot Framework控制浏览器

    向下 向上为负值

  7. SwipeRefreshLayout与ViewPager滑动事件冲突解决

    问题描写叙述: 开发中发现,SwipeRefreshLayout的下拉刷新,与ViewPager开发的banner的左右滑动事件有一点冲突,导致banner的左右滑动不够顺畅. 非常easy在bann ...

  8. UVa 170 - Clock Patience

    题目:Clock Patience游戏,将52张扑克牌,按时钟依次分成13组(中心一组),每组4张全都背面向上, 从中间组最上面一张牌開始.翻过来设为当前值,然后取当前值相应组中最上面的背过去的牌翻过 ...

  9. Python标准库:内置函数callable(object)

    假设对象object參数是能够调用的对象,就返回True.否则返回False.只是要注意的是,当一个对象是能够调用的.并不表示调用该对象时运行一定成功,但不可调用的对象去调用时一定不会成功.假设类对象 ...

  10. fgets()函数和sscanf()函数的使用方法

    fgets 百度百科:从文件结构体指针stream中读取数据,每次读取一行.读取的数据保存在buf指向的字符数组中.每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),假设文件里 ...