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

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

  1.   <select id="queryColumn" parameterClass="map" resultClass="hashMap">
  2. SELECT column_name as id ,comments as name FROM user_col_comments
  3. WHERE table_name=#table_name#
  4. <isNotEmpty prepend="and" property="a0100">
  5. column_name=#a0100#
  6. </isNotEmpty>
  7. </select>

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

  1. 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。

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

  直接贴代码:

  1. public class IbatisUtil {
  2. /**
  3. * @Title getSqlStr
  4. * @Descript :根据xml中的id得到执行时的sql语句
  5. * @date : 2017-08-30 15:07:01
  6. * @param
  7. * @return java.lang.String
  8. * @throws
  9. * @version V1.0
  10. */
  11. public String getSqlStr(SqlMapClient aqlMapClient, String sqlStatement, ParamMap map)map throws Exception {
  12. StringBuffer sqlBuffer=new StringBuffer();
  13. DynamicSql sql=getSql(aqlMapClient,sqlStatement);//得到sql
  14. List list=getChildren(sql);//得到children
  15. String str=getChlidrenStr(list,map);
  16. sqlBuffer.append(str);
  17. return sqlBuffer.toString();
  18. }
  19. /**
  20. * @Title getSql
  21. * @Descript :得到动态的sql
  22. * @date : 2017-08-30 15:07:45
  23. * @param
  24. * @return com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql
  25. * @throws
  26. * @version V1.0
  27. */
  28. private DynamicSql getSql(SqlMapClient aqlMapClient,String sqlStatement) {
  29. return (DynamicSql)(((SqlMapClientImpl)aqlMapClient).getDelegate().getMappedStatement(sqlStatement).getSql());
  30. }
  31. /**
  32. * @Title getChildren
  33. * @Descript :得到对象的私有属性childen的值 该对象只能是 DynamicSql和SqlTag否则返回null
  34. * @date : 2017-08-30 15:13:08
  35. * @param
  36. * @return java.util.List
  37. * @throws
  38. * @version V1.0
  39. */
  40. private List getChildren(Object obj) throws NoSuchFieldException, IllegalAccessException {
  41. if(!(obj instanceof DynamicSql || obj instanceof SqlTag))
  42. return null;
  43. Class classs=obj.getClass();
  44. Field field=classs.getDeclaredField("children");
  45. field.setAccessible(true);
  46. return (List)field.get(obj);
  47. }
  48. private String getChlidrenStr(List list,ParamMap map) throws NoSuchFieldException, IllegalAccessException {
  49. StringBuffer sb=new StringBuffer();
  50. for(Object obj :list){
  51. if(obj instanceof SqlText){
  52. sb.append(getSqlTextStr((SqlText)obj,map));
  53. }else if(obj instanceof SqlTag){
  54. sb.append(getSqlTagStr((SqlTag)obj,map));
  55. }
  56. }
  57. return sb.toString();
  58. }
  59. /**
  60. * @Title getSqlTextStr
  61. * @Descript :解析SqlText
  62. * @date : 2017-08-30 15:18:38
  63. * @param
  64. * @return java.lang.String
  65. * @throws
  66. * @version V1.0
  67. */
  68. private String getSqlTextStr(SqlText sqlText, ParamMap map){
  69. String sqlTemp;
  70. ParameterMapping[] parameterMappings = sqlText.getParameterMappings();
  71. sqlTemp = sqlText.getText().toString();
  72. if (parameterMappings != null && parameterMappings.length > 0) {
  73. Object obj;
  74. int i;
  75. for (ParameterMapping param : parameterMappings) {
  76. i=param.getJdbcType();
  77. switch (i){
  78. case 0://为定义
  79. obj="'"+map.getAsString(param.getPropertyName())+"'";
  80. break;
  81. case 4://INTEGER
  82. obj=map.getAsInteger(param.getPropertyName());
  83. break;
  84. case 12://VARCHAR
  85. obj="'"+map.getAsString(param.getPropertyName())+"'";
  86. break;
  87. case 93://TIMESTAMP
  88. obj="to_date('yyyy-MM-dd','"+map.getAsString(param.getPropertyName())+"')";
  89. break;
  90. default:obj="";
  91. }
  92. if(ValidateUtil.isEmpty(obj))
  93. obj="";
  94. sqlTemp = sqlTemp.replaceFirst("\\?",obj.toString());
  95. }
  96. }
  97. return sqlTemp;
  98. }
  99. /**
  100. * @Title getSqlTagStr
  101. * @Descript :解析SqlTag
  102. * @date : 2017-08-30 15:24:29
  103. * @param
  104. * @return java.lang.String
  105. * @throws
  106. * @version V1.0
  107. */
  108. private String getSqlTagStr(SqlTag sqlTag,ParamMap map) throws NoSuchFieldException, IllegalAccessException {
  109. StringBuffer sb=new StringBuffer();
  110. List list=getChildren(sqlTag);
  111. String tagName=sqlTag.getName();
  112. switch (tagName){
  113. case "isNotEmpty":
  114. if(ValidateUtil.isEmpty(map.getAsString(sqlTag.getPropertyAttr())))
  115. return "";
  116. if(ValidateUtil.isNotEmpty(list)){
  117. if(ValidateUtil.isNotEmpty(sqlTag.getPrependAttr()))
  118. sb.append(" "+sqlTag.getPrependAttr() +" ");
  119. sb.append(getChlidrenStr(list,map));
  120. }
  121. break;
  122. case "isEmpty":
  123. if(ValidateUtil.isNotEmpty(map.getAsString(sqlTag.getPropertyAttr())))
  124. return "";
  125. if(ValidateUtil.isNotEmpty(list)){
  126. if(ValidateUtil.isNotEmpty(sqlTag.getPrependAttr()))
  127. sb.append(" "+sqlTag.getPrependAttr() +" ");
  128. sb.append(getChlidrenStr(list,map));
  129. }
  130. break;
  131. }
  132. return sb.toString();
  133. }
  134. }

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. 前端开发—BOM对象DOM文档对象操作

    BOM 浏览器对象 BOM:Browser Object Model 操作浏览器,需要调用window对象,它是所有浏览器都支持的对象,表示的就是浏览器窗口 window对象可以通过点调用子对象 wi ...

  2. sklearn学习1----sklearn.SVM.SVC

    1.SVM有两种作用:分类和回归,分类是用SVC,回归用SVR. 2.SVC:(中文官网) 重点在svm.SVC(),fit(X,Y),以及SVC中的参数. 3.SVC参数: ①C,C是控制软间隔中的 ...

  3. 【BZOJ3451】Tyvj1953 Normal - 点分治+FFT

    题目来源:NOI2019模拟测试赛(七) 非原题面,题意有略微区别 题意: 吐槽: 心态崩了. 好不容易场上想出一题正解,写了三个小时结果写了个假的点分治,卡成$O(n^2)$ 我退役吧. 题解: 原 ...

  4. js中数组常用方法

    1.Array.push() 此方法是在数组的后面添加新加元素,此方法改变了数组的长度: var aa=[1,2,3]; var bb=aa.push(4,5); console.log(bb)    ...

  5. [luogu 1270] “访问”美术馆 (树形dp)

    传送门 Description 经过数月的精心准备,Peer Brelstet,一个出了名的盗画者,准备开始他的下一个行动.艺术馆的结构,每条走廊要么分叉为两条走廊,要么通向一个展览室.Peer知道每 ...

  6. docker数据卷的使用 -v --volumes--from

    总结一下docker数据管理的三种方法: 1.普通的挂在数据: -v docker run  -v /father/path:/child/path-v 参数会把当前系统的文件目录/father/pa ...

  7. IP实时传输协议RTP/RTCP详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  8. Cocos2d-x 2.2.3 使用NDK配置安卓编译环境问题之 Cannot find module with tag &#39;CocosDenshion/android&#39; in import path

    1.当做安卓移植的时候遇到例如以下问题: Android NDK: jni/Android.mk: Cannot find module with tag 'CocosDenshion/android ...

  9. android TextView加边框

    为TextView加边框.须要在drawable建xml文件,里面设置shape来设置文本框的特殊效果. <?xml version="1.0" encoding=" ...

  10. EOJ 3000 ROT13加密和解密

    应用 ROT13 到一段文字上仅仅只需要检查字母顺序并取代它在 13 位之后的对应字母,有需要超过时则重新绕回 26 英文字母开头即可.A 换成 N.B 换成 O.依此类推到 M 换成 Z,然后串行反 ...