iBATIS step by step 2

转载 2004年07月16日 13:37:00
这一节里,使用了一个实际的例子来说明dynamic-mapped-statement 和 insert 的简单使用.

  系统发布后一段时间,对系统留下的一些log,特别是所执行的sql语句进行分析,来获取用户使用习惯的第一手数据,以便以后我们的改进。
    
  今天就做了这样一次简单的分析,由于系统中几乎所有的查询都使用我的一个统一的借口来进行查询,所以SQL的log有统一的标志,收集起来相对容易。
    
  下面一步一步的描述一下整个过程:
    
  一、搜集log
     1. 从服务器上获取log文件,无需多说
     2. 用程序分析log,并将sql解析出来,做一些处理,保存到数据库中。
        要保存一条数据到数据库里,需要配置一个保存的SQL:
        


      <parameter-map name="insert-params">
        <property name="exeTime" />
        <property name="sql"/>
        <property name="parsedSql"/>
        <property name="sqlvalues"/>
      </parameter-map>
      <mapped-statement name="insertSql" parameter-map="insert-params" >
        insert into SQL_STMT (
          ID,
          EXE_TIME,
          SQL,
          PARSED_SQL,
          SQL_valueS)
         values (
         <!--注意这里,可以使用数据库本身的功能,不受限制-->
          seq_sql_stmt.nextval, ?, ?, ?,?  
        )
      </mapped-statement>
      

 

程序里只需要提供一个简单的bean,这个bean只需要带有"insert-params"配置的那几个field就可以了,在程序里我们只需要:
       


       SqlLog log = parseSqlLog(sqlString);//set 相关字段
       SqlMapConfig.getSqlMap().executeUpdate("insertSql", log);
       



       这样就保存好了,简单吧。
     3. 用程序跑,把所有log分析完,都写到数据库里去
          
  三、分析LOG
        也许保存数据上,看不出多少和其他ORM工具的差别,甚至还会觉得更麻烦一点,下面用一个查询的例子来说明iBATIS的灵活与强大。
        为了分析这些log,我在往数据库里写的时候,把sql里的值都去掉了,替换成prepared类似的sql,以便于分析sql的普遍性。在这里提一句题外话,在设计DAO框架的时候,最好考虑以后可能的扩展,使用比较好的框架是很重要的,就象这里搜集log,由于我们使用了统一的接口,不仅log搜集容易,对于以后的扩展与修改也很重要,比如现在我就在修改我们的一个UTIL,让所有的sql都用绑定的方式执行,如果没有以前好的设计,现在要修改几乎是不可能的!
  log分析出来大概有80多万记录,我们需要从中获取一些有用的信息,就必须提供一个简单的查询。经过简单的了解后,我们大致需要几个条件:执行时间,sql语句(模糊查询),统计的条数。
        于是,就开始写配置文件:
         [code]
      <dynamic-mapped-statement name="getSqlLogStatistics" cache-model="sqllog-cache" 
         result-map="sqllog-hashmap-result" >
          SELECT * FROM (SELECT ROWNUM count_row_num, w_o_l_f_w.* FROM ( 
          select * from (
               select PARSED_SQL,COUNT(*) CNT from SQL_STMT
            <dynamic prepend="WHERE">
<isNotNull prepend="AND" property="exetimestart">
                <![CDATA[EXE_TIME >= #exetimestart#]]>
              </isNotNull>
           <isNotNull prepend="AND" property="exetimeend">
             <![CDATA[ EXE_TIME <= #exetimeend# ]]>
              </isNotNull>
              <isNotEmpty prepend="AND" property="sql">
                (SQL like '%'||#sql#||'%' or PARSED_SQL like '%'||#sql#||'%' )
              </isNotEmpty>
            </dynamic>
            <dynamic prepend="HAVING">
                <isNotEmpty property="countfrom">
                    <![CDATA[ COUNT(*) >= #countfrom# ]]>
                </isNotEmpty>
                <isNotEmpty prepend="AND" property="countto">
                    <![CDATA[ COUNT(*) <= #countto# ]]>
                </isNotEmpty>
            </dynamic>
            GROUP by PARSED_SQL
        
          <![CDATA[
          ) order by cnt  desc  ) w_o_l_f_w
           WHERE ROWNUM < #__EndPoint#)
          WHERE (count_row_num >= #__StartPoint#) 
        ]]>
      </dynamic-mapped-statement>
      [/code]
          以上的就是一个动态的sql,看起来可能比较难看,但是他管用。
          这样,程序里就简单了,在action里,我们把提交的数据简单的处理一下:

[code]
        ParameterParser pp = data.getParameters();
        Map params = new HashMap(pp.getKeys().length-2);
        Object[] keys = pp.getKeys();
        for(int i=0;i<keys.length;i++){
            String key = (String) keys[i];
            if(!"template".equals(key) && !"action".equals(key)){
                Date tmp = TemplateUtil.getDateFromPicker(pp,key);
                if(tmp!=null){
                    params.put(key,tmp);
                }else{
                 params.put(key,pp.getString(key).trim());
                }
            }
        }
        [/code]
            这段代码简单的处理了提交的数据,把他从Parameters里拿出来放到一个Map里,
        做为我们查询的条件,在我们的bean里,只需要:
        


      return SqlMapConfig.getSqlMap().executeQueryForList(
    "getSqlLogStatistics", params);
  


        很简单吧?
           
  其实,就开发上来说,我们只是把一些以前要在java程序里写的逻辑,比如某个字段是不是有值啊什么的放到了sqlmap的xml里去,工作量并没有减少多少,但是,修改和调整的时候,工作量就大大的减少了,我们不需要去修改程序,编译,发布,再运行,我们只需要简单的修改sqlmap的的xml就可以做到这一点,对于项目后期的调整(比如dba要将sql进行tuning),项目发布后的维护等等,可以说是大大的减轻了工作量。
       
  四、后记
  这只是一个非常简单应用,简单的使用了iBATIS 的 sqlmap功能,我想我们以后可以考虑在项目中使用它,但是任何一个工具都有他最适用的地方,我的意见是以后的添加修改和删除还是可以继续使用一些ORM工具,至于查询么,单表或者简单的有规律的查询可以使用代码生成工具中生出来,对于十分复杂,而且用户又可能经常修改或者说很有可能需要在后期进行性能调整的查询,我们可以考虑使用iBATIS.

DEDE CMS安全警告:Safe Alert: Request Error step 2!

我的解决是取消部分安装模块   Safe Alert: Request Error step 2! DEDE CMS安全警告:Safe Alert: Request Error step 2...
  • yxwmzouzou
  • yxwmzouzou
  • 2015年01月24日 17:40
  • 4915

Safe Alert Request Error step 的解决办法

dedecms功能很强大,但总有些东西无法满足我们自己的需求,这就需要我们在设计模板时使用这个标记来编写程序,也总免不了要查询、更新、修改数据库。但是不是欣喜的编写完程序后运行程序系统却提示你Safe...
  • jodan179
  • jodan179
  • 2012年09月26日 16:59
  • 10037

OpenCV Python calcOpticalFlowFarneback

import cv2 def draw_flow(im,flow,step=16): h,w = im.shape[:2] y,x = mgrid[step/2:h:step,step...
  • u014657795
  • u014657795
  • 2017年12月10日 12:52
  • 156

iBATIS step by step (1)

今天抽空写了step by step的 step 1,首先用了一个最简单的例子来说明iBATIS的灵活与方便.   一些说明,  1.例子使用eclipse进行开发,所以附件的包里有eclipse的....
  • JasonSeaver
  • JasonSeaver
  • 2004年07月16日 13:35
  • 1266

Python标准库:内置函数range(stop) range(start, stop[, step])

本函数是产生一系列序列的数组,返回迭代子。参数stop是终止的数字;参数start是指明开始数列开始值;参数step是数列之间的差值。因此这个函数就是产生以start为起点,以stop为终点,以ste...
  • caimouse
  • caimouse
  • 2015年03月13日 08:25
  • 5019

Intellij IDEA调试功能使用总结(step over / step into / force step into/step out等)

Intellij IDEA调试功能使用总结(step over / step into / force step into/step out等)
  • theusProme
  • theusProme
  • 2016年11月03日 00:37
  • 3910

Web_PHP_DedeCMS_织梦DedeCMS出现Safe Alert: Request Error step 1 ! 或Safe Alert: Request Error step 2!解决方法

这是由于新版中使用SQL语句防注入功能引起的安全警告,在自定义模模型中使用下面名称 union|sleep|benchmark|load_file|outfile之一都会引起Safe Alert...
  • u011168154
  • u011168154
  • 2014年12月09日 11:23
  • 608

Step Into和Step Over,Step Out有什么区别呢?

Step Into和Step Over,Step Out有什么区别呢? Step Into(F11) 单步执行,遇到子函数就进入并且继续单步执行 Step Over (F10)在单步执行时,在函数...
  • u013053957
  • u013053957
  • 2015年06月15日 16:25
  • 818

单步调试 step into/step out/step over 区别

step into:单步执行,遇到子函数就进入并且继续单步执行(简而言之,进入子函数);step over:在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也...
  • huangfei711
  • huangfei711
  • 2016年04月22日 15:08
  • 16610

【Python】Python中如何实现for循环step=2,step=-2

>>> for i in xrange(0,10,2): print(i) 0 2 4 6 8 >>> for i in xrange(10,0,-2): print(i) 10 ...
  • ghxbob
  • ghxbob
  • 2013年10月08日 00:17
  • 6398
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iBATIS step by step 2
举报原因:
原因补充:

(最多只允许输入30个字)