环境: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. Node笔记(2)

    写一个可以生成多层级文件夹的函数 const fs = require('fs'); const path = require('path'); function mkdirs (pathname,c ...

  2. 使用Requests+正则表达式爬取猫眼TOP100电影并保存到文件或MongoDB,并下载图片

    需要着重学习的地方:(1)爬取分页数据时,url链接的构建(2)保存json格式数据到文件,中文显示问题(3)线程池的使用(4)正则表达式的写法(5)根据图片url链接下载图片并保存(6)MongoD ...

  3. nginx 301 重定向设置不含www到www域名

    如果需要将不含www主机的域名301重定向到含www的域名,如将 shwww.net 重定向至 www.shwww.net,nginx 配置指令如下: server { server_name shw ...

  4. 1.1 Eclipse的安装

    下载地址:http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/indigosr1 2.java jdk 的 ...

  5. ndk,cygwin编译 .so动态库

    注意: ndk .cygwin 安装路径尽量要和sdk放到一个磁盘里,设置环境变量. 例如D: 根目录  变量名:ndk   值:/cygdrive/d/android-ndk-r8e 打开cygwi ...

  6. $_SERVER 详解

    $_SERVER['HTTP_ACCEPT_LANGUAGE']//浏览器语言 $_SERVER['REMOTE_ADDR'] //当前用户 IP . $_SERVER['REMOTE_HOST'] ...

  7. 支付宝接口程序、文档及解读(ASP.NET)

    最近需要为网站加入支付宝的充值接口,而目前关于支付宝接口开发的资料比较杂乱,这里就我此次开发所用到的资料进行汇总整理,希望能够帮助需要的朋友. 开发步骤: 1. 确定签约类型 支付宝的接口有多种类型, ...

  8. rails 安装后调整gem sources 地址

    rails 安装后调整gem sources 地址 使用https会有认证的问题: 移除原有的: gem sources --remove https://rubygems.org/ 查看当前的: g ...

  9. pthread_create()创建线程时传入多个參数

    因为接口仅仅定义了一个入參void *arg int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, (void*)(*start ...

  10. 构建基于Javascript的移动CMS——生成博客(二).路由

    在有了上部分的基础之后.我们就能够生成一个博客的内容--BlogPosts Detail.这样就完毕了我们这个移动CMS的差点儿基本的功能了,有了上节想必对于我们来说要获取一个文章已经不是一件难的事情 ...