`
sinokaka
  • 浏览: 327087 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

iBATIS如何复用SQL片段(翻译)

阅读更多

原文链接

http://opensource.atlassian.com/confluence/oss/display/IBATIS/How+do+I+reuse+SQL-fragments


When writing SqlMaps, you often encounter duplicate fragments of SQL, for example a FROM-clause or constraint-statement; iBATIS offers a simple yet powerful tag to reuse them. For the sake of simplicity, let's assume we want to get some items and we want to do a count on them.

Normally, you would write something like this:

当我们写SqlMaps的时候,经常会碰到重复的SQL片段,例如From语句或者约束条件;iBATIS提供了一个强大的标签来复用这些重复片段,简单举例,我们想检索一些字段,并且想统计它们。

通常情况下,你会这样写:

xml 代码
  1. <select id="selectItemCount" resultClass="int">     
  2.   SELECT COUNT(*) AS total      
  3.   FROM items      
  4.   WHERE parentid = 6     
  5. select>     
  6. <select id="selectItems" resultClass="Item">     
  7.   SELECT id, name      
  8.   FROM items      
  9.   WHERE parentid = 6     
  10. select>     
  11.   

 To eliminate this duplication, we use the tags 【sql】 and 【include】. The 【sql】-tag contains the fragment to reuse, the 【include】-tag to include such a fragment:

为了消除重复片段,我们使用【sql】和【include】标签。【sql】标签用来包含重复片段,【include】标签用来引入片段:

 xml 代码

  1. <sql id="selectItem_fragment">     
  2.   FROM items      
  3.   WHERE parentid = 6     
  4. sql>     
  5. <select id="selectItemCount" resultClass="int">     
  6.   SELECT COUNT(*) AS total      
  7.   <include refid="selectItem_fragment"/>     
  8. select>     
  9. <select id="selectItems" resultClass="Item">     
  10.   SELECT id, name      
  11.   <include refid="selectItem_fragment"/>     
  12. select>     
  13.   

 The 【include】-tag is namespace-aware so you can refer to fragments even when they are located in another map (however, due to the way iBATIS loads the SqlMaps, the included fragment should be loaded before the including statement). 

【inclued】标签是一个命名空间可知的,所以你可以引入其他map的片段.(但是,因为iBATIS引入SqlMap的顺序,被引入的片段,要优先于欲引入的sql部分被导入)

The fragments are included and processed on query-execution so parameters can be used too:

重复片段在查询执行时被引入和执行,所以参数依然可以使用:

 xml 代码

  1. <sql id="selectItem_fragment">     
  2.   FROM items      
  3.   WHERE parentid = #value#      
  4. sql>     
  5. <select id="selectItemCount" parameterClass="int" resultClass="int">     
  6.   SELECT COUNT(*) AS total      
  7.   <include refid="selectItem_fragment"/>     
  8. select>     
  9. <select id="selectItems" parameterClass="int" resultClass="Item">     
  10.   SELECT id, name      
  11.   <include refid="selectItem_fragment"/>     
  12. select>     
  13.   
分享到:
评论
21 楼 heartsong 2007-08-03  
还不错,不过如果大量使用的话,对于后来的开发人员阅读来说,可真是要痛苦了,就像在c语言里读goto一样。
20 楼 spiritfrog 2007-05-24  
sinokaka 写道
在sqlmap-config中配置useStatementNamespaces="true"就可以了

晕了,以前我怎么说namespace根本不起作用,不写也不会出错,原来还要这个配置。
19 楼 galaxystar 2007-05-21  
节省代码与提高代码可读性也是把双刃剑,
如果一个xml很大或者id不在一个配置中,你要复用这个id,查找也是一种成本.
并且,好像嵌套做得不好!

比如:

select * from (XX) where rownum <= 10

这里的XX到底是放include里还是select里?
一般XX是会变的,肯定是写在select里对应一个ibatis dao方法,那么include就难做了.
它不能传参数,不能嵌套.

比较丑陋的,就是 select * from ( 定义为一个include
而 ) where rownum <= 10定义为另一个include
18 楼 lszone 2007-05-21  
谁说没用,我们现在就在用这种方法来做记录总数与记录明细的查询条件,节省了不少代码
17 楼 victor1017 2007-05-20  
测试了一下,刚开始没成功,说找不到要include的sql,后来发现我要include的sql放在了xml文件的最后,将他移到最前面就没问题了,所以大家要注意放置的顺序。
16 楼 小嘴看世界 2007-03-21  
<div class='code_title'>我感觉挺有用的,看我的代码</div>
<div class='code_title'/>
<div class='code_title'>xml 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-xml'>
    <li class='alt'><span><span class='tag'>&lt;</span><span class='tag-name'>statement</span><span> </span><span class='attribute'>id</span><span>=</span><span class='attribute-value'>"search"</span><span> </span><span class='attribute'>resultMap</span><span>=</span><span class='attribute-value'>"infoResult"</span><span class='tag'>&gt;</span><span>  </span></span></li>
    <li class=''><span>        SELECT    </span></li>
    <li class='alt'><span>            lnid,   </span></li>
    <li class=''><span>            tpye,   </span></li>
    <li class='alt'><span>            dsc,   </span></li>
    <li class=''><span>            pnid,   </span></li>
    <li class='alt'><span>        FROM F48100    </span></li>
    <li class=''><span>        </span><span class='tag'>&lt;</span><span class='tag-name'>include</span><span> </span><span class='attribute'>refid</span><span>=</span><span class='attribute-value'>"Dy_SC"</span><span class='tag'>/&gt;</span><span>  </span></li>
    <li class='alt'><span>        ORDER BY bcdat DESC   </span></li>
    <li class=''><span>    </span><span class='tag'>&lt;/</span><span class='tag-name'>statement</span><span class='tag'>&gt;</span><span>  </span></li>
</ol>
</div>
<p> 使用的时候include就OK了,如下</p>
<div class='code_title'>
<div class='code_title'>xml 代码</div>
<div class='dp-highlighter'>
<div class='bar'/>
<ol class='dp-xml'>
    <li class='alt'><span><span class='tag'>    &lt;</span><span class='tag-name'>sql</span><span> </span><span class='attribute'>id</span><span>=</span><span class='attribute-value'>"Dy_SC"</span><span class='tag'>&gt;</span><span>  </span></span></li>
    <li class=''><span>        </span><span class='tag'>&lt;</span><span class='tag-name'>dynamic</span><span> </span><span class='attribute'>prepend</span><span>=</span><span class='attribute-value'>"WHERE"</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class='alt'><span>            </span><span class='tag'>&lt;</span><span class='tag-name'>isNotNull</span><span> </span><span class='attribute'>prepend</span><span>=</span><span class='attribute-value'>"AND"</span><span> </span><span class='attribute'>property</span><span>=</span><span class='attribute-value'>"pnid"</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class=''><span>                </span><span class='attribute'>pnid</span><span> = #pnid#   </span></li>
    <li class='alt'><span>            </span><span class='tag'>&lt;/</span><span class='tag-name'>isNotNull</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class=''><span>            </span><span class='tag'>&lt;</span><span class='tag-name'>isNotNull</span><span> </span><span class='attribute'>prepend</span><span>=</span><span class='attribute-value'>"AND"</span><span> </span><span class='attribute'>property</span><span>=</span><span class='attribute-value'>"dsc"</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class='alt'><span>                dsc like #dsc#   </span></li>
    <li class=''><span>            </span><span class='tag'>&lt;/</span><span class='tag-name'>isNotNull</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class='alt'><span>        </span><span class='tag'>&lt;/</span><span class='tag-name'>dynamic</span><span class='tag'>&gt;</span><span>  </span></li>
    <li class=''><span>    </span><span class='tag'>&lt;/</span><span class='tag-name'>sql</span><span class='tag'>&gt;</span><span>  </span></li>
</ol>
</div>
</div>
<span class='tag'><span class='tag'><span class='tag'><span class='tag'><span class='tag'><span class='cdata'><span class='tag'><span class='tag'><span class='tag'>
<p> </p>
<div class='code_title'> </div>
<span class='tag'/></span></span></span></span></span></span></span></span></span>
15 楼 wdl123 2007-01-29  
<include refid="selectItem_fragment"/>     

在这个include里面可不可以放变量,从程序外面传进去
14 楼 ddandyy 2006-12-22  
真的是很方便的  在实际中
至于说例子  好像没有几个例子是有意义的  主要就是用最简单的方式让别人明白怎么用就行了
13 楼 gilber 2006-12-21  
sinokaka 写道
在sqlmap-config中配置useStatementNamespaces="true"就可以了


原先没看到这一块,谢谢了!
12 楼 sinokaka 2006-12-21  
在sqlmap-config中配置useStatementNamespaces="true"就可以了
11 楼 gilber 2006-12-21  
现在有一个问题:如果要取其他namespace里的SQL,好象不能指定namespace,就象这样会报错,请问谁知道怎么解决?

<sqlMap namespace="common">
  <sql id="selectItem_fragment">      
    FROM items       
    WHERE parentid = 6      
  </sql>
</sqlMap>

<sqlMap namespace="test">      
  <select id="selectItems" resultClass="Item">      
    SELECT id, name       
    错误 <include refid="common.selectItem_fragment"/> 
    正确 <include refid="selectItem_fragment"/>           
  </select>
</sqlMap>

10 楼 宏基小键盘 2006-12-16  
早就有这个功能了。而且用起来也非常方便。
9 楼 sinokaka 2006-12-16  
http://opensource.atlassian.com/confluence/oss/display/IBATIS/Not+Yet+Documented

我是在这里找到的,我在2.0里面的中文没有找到:)
8 楼 liuyxit 2006-12-16  
sinokaka 写道
我在网上找了很久才找到这个功能,看了SQL的官方文档这些都属于未记录(Document)的档案


怎么没记录!?
我下载的ibatis-2.3.0.677的iBATIS-SqlMaps-2_en.pdf就记录了。
7 楼 znjq 2006-12-16  
include经常用,对于一些状态的判断还是挺方便的
6 楼 stephen 2006-12-16  
要实现 SQL 的复用,最好是把 ajoo 的 JRC 和 iBatis 结合起来。
这可能要在 iBatis 底层进行修改,以提供更方便的使用接口。
目前还没认真想过如何结合,等遇到这样的需求时再看看。

ajoo 的 JRC:http://www.iteye.com/topic/21903
5 楼 sinokaka 2006-12-16  
我觉得例子仅仅是一个参考,主要是了解这个思路,知道这个功能,实际意义,对于我来说还是比较大的,我在网上找了很久才找到这个功能,看了SQL的官方文档这些都属于未记录(Document)的档案,所以就用我蹩脚的鸟语功夫,翻译了一下,希望对大家来说是一个参考
4 楼 joachimz 2006-12-16  
include还是使用很多的,除了例子中的count/list,还有相同的Mapping,不同的查询条件,在我们项目应用得非常多。
3 楼 deafwolf 2006-12-16  
edusaj 写道
我觉得有实际意义至少我们项目现在的分页就有用,取记录数与明细之前的条件语句就相同,谢谢分享!


我觉得楼主给的例子意义不大,但是在分页中用这个很不错,尤其是多条件查询,count和list分别写一个确实太麻烦
2 楼 edusaj 2006-12-16  
我觉得有实际意义至少我们项目现在的分页就有用,取记录数与明细之前的条件语句就相同,谢谢分享!

相关推荐

    iBatis的动态SQL语句

    上述示例中,`userNameList`是一个List类型的集合,`&lt;iterate&gt;`标签会遍历该集合中的所有元素,并为每个元素生成如下的SQL片段:`AND (username=#userNameList[0] OR username=#userNameList[1] OR ...)`。...

    iBATIS-SqlMaps-2_ja.pdf

    - **SQL 片段重用**:通过 `&lt;sql&gt;` 元素定义通用的 SQL 片段,提高代码复用性。 - **键值自动生成**:配置主键自增或其他机制来自动为新记录生成唯一的标识符。 - **存储过程**:支持调用数据库中的存储过程,并处理...

    ibatis官方资料

    通过&lt;sql&gt;元素可以复用SQL片段,、、和元素分别对应SQL查询、插入、更新和删除操作。 4. **动态SQL**:iBATIS支持条件式SQL,可以通过if、where、choose(when/otherwise)、trim、foreach等元素构建动态SQL,使得...

    iBatis文档

    SQL映射文件中的&lt;sql&gt;标签可以复用SQL片段,、、、标签分别对应查询、插入、更新和删除操作。动态SQL是iBatis的一大亮点,通过、、、等标签,可以在运行时根据条件动态生成SQL语句。 此外,iBatis支持预编译的...

    iBATIS DataMapper1.6 中文翻译

    2. 引入了`&lt;include/&gt;`节点,支持SQL片段的重用,提高代码的可维护性和复用性。 3. 添加了对字典查询的支持,即`QueryForDictionary, V&gt;(...)`方法,使得查询结果可以映射到字典中,方便数据处理。 4. 允许存储过程...

    ibatis拼接字符串

    4. **代码复用**:封装常用的 SQL 动态构建逻辑,减少重复代码。 通过以上分析,我们可以看出 iBatis 在处理动态 SQL 方面具有很大的灵活性和扩展性。在实际开发过程中,合理利用 iBatis 可以极大地提高开发效率和...

    ibatis技术总结

    11. **&lt;sql&gt;SQL语句片段**:定义可重用的SQL片段,方便在多个SQL语句中复用。 12. **组合语句**:用于包含另一个SQL片段,实现SQL语句的组合。 13. ****:定义主键生成策略,常用于自动填充主键字段。 这些标签...

    ibatis动态注入

    为了提高代码复用性,iBATIS还支持将动态SQL片段定义为独立的`&lt;sql&gt;`标签,如: ```xml &lt;sql id="queryCondition"&gt; where user_id = #{userId} &lt;/sql&gt; select * from user &lt;!-- 引入动态的查询条件 --...

    ibatis教程(免费).ppt

    - 使用&lt;sql&gt;元素复用SQL片段 - 、、和元素的使用 - 动态SQL:、、、等标签的应用 4. **Java接口绑定**: - 定义Mapper接口 - 映射接口方法到SQL语句 - 使用@Select、@Insert、@Update、@Delete注解 5. **...

    iBatis.Net 模板文件 for codesmith4.1

    7. `iBatis.inc`:这个文件可能是一个包含文件,其中包含了常量、宏定义或者共享的代码片段,可以被其他模板引用,提高代码复用性。 通过这些模板,开发者可以快速地根据数据库结构生成完整的DAL层和部分Service层...

    ibatis学习资料

    - **二元条件标签**:如`&lt;where&gt;`、`&lt;set&gt;`,用于生成带有条件的SQL片段。 - **其它标签**:如`&lt;foreach&gt;`,用于循环生成SQL片段。 #### 高级查询技术 - **映射继承**:支持继承映射关系,简化重复的映射配置。 - ...

    ibatis参考文档

    为了提高代码复用性和维护性,iBATIS支持重用SQL片段。通过定义通用的SQL模板并在不同的Mapped Statements中引用它们,可以有效减少重复代码。 ##### 4. Auto-Generated Keys 对于需要自动生成主键的情况,iBATIS...

    ibatis的教程

    2. 通过节点标识,支持了SQL片段的复用,使得SQL代码更加模块化。 3. 增加了对字典查询的支持,通过IDictionary,V&gt;QueryForDictionary,V&gt;()方法提供了直接查询字典对象的功能。 4. 支持存储过程无参数映射,简化了...

    IBatis 指导手册

    - **SQL 元素**:可以将通用的SQL片段抽取出来,提高代码复用性。 - **参数处理**:支持动态SQL,例如条件判断、循环等。 - **结果映射**(`resultMap`):用于定义SQL查询结果如何映射到Java对象,支持复杂的一对一...

    ibatise例子

    2. **动态SQL**:iBATIS允许在SQL语句中使用条件判断,使得SQL可以根据传入参数的不同动态生成,提高了代码的可复用性。 3. **事务管理**:iBATIS提供了简单的事务控制,可以在代码中手动开启、提交或回滚事务。 4...

    iBaitis 框架使用技术

    例如,使用`&lt;if&gt;`标签可以判断条件是否满足,然后决定是否执行相应的SQL片段。 4. **结果映射**: - 结果映射用于将数据库查询结果映射到Java对象,通过`&lt;resultMap&gt;` 标签定义字段与Java对象属性的对应关系,支持...

Global site tag (gtag.js) - Google Analytics