ibatis3中执行SelectBuilder/SqlBuilder生成的SQL语句。

 

         ibatis3中执行SelectBuilder/SqlBuilder生成的SQL语句。

分类: Road to Java 1129人阅读 评论(2) 收藏 举报

iBatis 3中新增了SelectBuilder/SqlBuilder两个工具类,用于利用类函数的方式动态生成SQL 语句,减少拼接SQL语句时候大量的显式字符串操作,减少字符串操作可能出现的错误,提高程序的易读性。

在iBatis 3的用户指南中,列举出了若干个实例,如下是个最简单的例子,生成一个静态的SQL语句:

 

 

  1. import static org.mybatis.jdbc.SelectBuilder.*;  
  2.   
  3. public String selectBlogsSql() {  
  4. BEGIN(); // Clears ThreadLocal variable  
  5. SELECT("*");  
  6. FROM("BLOG");  
  7. return SQL();  
  8. }  
import static org.mybatis.jdbc.SelectBuilder.*; public String selectBlogsSql() { BEGIN(); // Clears ThreadLocal variable SELECT("*"); FROM("BLOG"); return SQL(); }

 

 

下面几个例子生成动态的SQL语句

 

  1. private String selectPersonLike(Person p){  
  2. BEGIN(); // Clears ThreadLocal variable  
  3. SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");  
  4. FROM("PERSON P");  
  5. if (p.id != null) {  
  6. WHERE("P.ID like #{id}");  
  7. if (  
  8. p.firstName != null) {  
  9. WHERE("P.FIRST_NAME like #{firstName}");  
  10. if (  
  11. p.lastName != null) {  
  12. WHERE("P.LAST_NAME like #{lastName}");  
  13. } ORDER_BY("P.LAST_NAME");  
  14. return SQL();  
  15. }  
  16.   
  17.   
  18. public String deletePersonSql() {  
  19. BEGIN(); // Clears ThreadLocal variable  
  20. DELETE_FROM("PERSON");  
  21. WHERE("ID = ${id}");  
  22. return SQL();  
  23. }  
  24. public String insertPersonSql() {  
  25. BEGIN(); // Clears ThreadLocal variable  
  26. INSERT_INTO("PERSON");  
  27. VALUES("ID, FIRST_NAME""${id}, ${firstName}");  
  28. VALUES("LAST_NAME""${lastName}");  
  29. return SQL();  
  30. }  
  31. public String updatePersonSql() {  
  32. BEGIN(); // Clears ThreadLocal variable  
  33. UPDATE("PERSON");  
  34. SET("FIRST_NAME = ${firstName}");  
  35. WHERE("ID = ${id}");  
  36. return SQL();  
  37. }  
private String selectPersonLike(Person p){ BEGIN(); // Clears ThreadLocal variable SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME"); FROM("PERSON P"); if (p.id != null) { WHERE("P.ID like #{id}"); } if ( p.firstName != null) { WHERE("P.FIRST_NAME like #{firstName}"); } if ( p.lastName != null) { WHERE("P.LAST_NAME like #{lastName}"); } ORDER_BY("P.LAST_NAME"); return SQL(); } public String deletePersonSql() { BEGIN(); // Clears ThreadLocal variable DELETE_FROM("PERSON"); WHERE("ID = ${id}"); return SQL(); } public String insertPersonSql() { BEGIN(); // Clears ThreadLocal variable INSERT_INTO("PERSON"); VALUES("ID, FIRST_NAME", "${id}, ${firstName}"); VALUES("LAST_NAME", "${lastName}"); return SQL(); } public String updatePersonSql() { BEGIN(); // Clears ThreadLocal variable UPDATE("PERSON"); SET("FIRST_NAME = ${firstName}"); WHERE("ID = ${id}"); return SQL(); }

 

 

通过上面的实例,我们已经可以生成SQL语句了,但是如何使用这些SQL,用户指南中并没有提及。当然,对于简单的例子,如例1中生成的静态 SQL,我们完全可以以纯粹的JDBC的方式来执行。但例子2中几个方法,则必须首先将里面的变量替换掉,才能执行,因此,利用iBatis中自带的类进 行变量替换则应该是最好的办法(当然我们可以用Velocity等模板工具来做这件事情,但在iBatis环境下,不是最佳的方案)。

 

iBatis3的一个缺陷就是相关的开发文档太少,要想做这件事情就必须啃源码了。

 

首先通过观察,找到了SelectBuilder/SqlBuilder同一个package下的SqlRunner类,该类封装了针对数据库操作 的select,insert, update和delete的等方法,很显然这是一个SQL执行类,select默认的返回类型为Map。

 

下一步,需要寻找能替换关键字变量的相关类了,得感谢ibatis 3.0 Dynamic Sql 设计解 ...这篇文章,对Dynamic Sql相关类和类关系有了了解,才找到最终的解决方案,如下:

 

 

  1.     private Connection conn=null;  
  2.     private SqlRunner sqlRunner;  
  3.       
  4.     {  
  5.           
  6.         try {  
  7.             conn = sessionFactory.getConfiguration().getEnvironment().getDataSource().getConnection();  
  8.             sqlRunner=new SqlRunner(conn);  
  9.         } catch (SQLException e) {  
  10.             logger.error(e);  
  11.         }  
  12.   
  13.     }  
  14.   
  15. public void deletPerson(Map keysMap) {  
  16.         BEGIN(); // Clears ThreadLocal variable  
  17.         DELETE_FROM("PERSON");  
  18.         WHERE("ID = #{id}");  
  19.   
  20.   
  21.         TextSqlNode node =new TextSqlNode(SQL());     
  22.         DynamicSqlSource s=new DynamicSqlSource(sessionFactory.getConfiguration(),  
  23.                 node);    
  24.         //此外对于静态SQL,ibatis还提供了StaticSqlSource  
  25.         BoundSql sql = s.getBoundSql(keysMap);  
  26.         logger.debug(sql.getSql());       
  27.           
  28.   
  29.         try {  
  30.             sqlRunner.delete(sql.getSql(),keysMap.get("id"));  
  31.             conn.commit();  
  32.         } catch (Exception e) {  
  33.             conn.rollback();  
  34.             throw e;  
  35.         }         
  36. }  
private Connection conn=null; private SqlRunner sqlRunner; { try { conn = sessionFactory.getConfiguration().getEnvironment().getDataSource().getConnection(); sqlRunner=new SqlRunner(conn); } catch (SQLException e) { logger.error(e); } } public void deletPerson(Map keysMap) { BEGIN(); // Clears ThreadLocal variable DELETE_FROM("PERSON"); WHERE("ID = #{id}"); TextSqlNode node =new TextSqlNode(SQL()); DynamicSqlSource s=new DynamicSqlSource(sessionFactory.getConfiguration(), node); //此外对于静态SQL,ibatis还提供了StaticSqlSource BoundSql sql = s.getBoundSql(keysMap); logger.debug(sql.getSql()); try { sqlRunner.delete(sql.getSql(),keysMap.get("id")); conn.commit(); } catch (Exception e) { conn.rollback(); throw e; } }

 

 

 

使用起来很简单:

 

  1. try {             
  2.     Map params= new HashMap();  
  3.     params.put("id","1");  
  4.     deletePerson();  
  5.       
  6. catch (Exception e) {  
  7.     // TODO Auto-generated catch block  
  8.     e.printStackTrace();  
  9. }  
try { Map params= new HashMap(); params.put("id","1"); deletePerson(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }

 

 

如上,使用map是为了支持任意多个参数,同时利用SelectBuilder/SqlBuilder强大的SQL构建能力,我们完全可以封装一些 很通用的数据库操作功能,比如通用删除功能,只需将上面的方法进行修改,将表名和包含主键变量的Map传入就可以实现了,而不需要再去XML文件写 SQL。

上一篇: 通用TitleAreaDialog的实现 下一篇: Eclipse Rcp在程序中指定Welcome(Intro)显示的页面
posted on 2012-02-10 00:50  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/archive/2012/02/10/2344742.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值