设为首页 收藏本站
查看: 776|回复: 0

[经验分享] MyBatis接口SelectBuilder

[复制链接]

尚未签到

发表于 2016-11-24 10:04:56 | 显示全部楼层 |阅读模式
  SelectBuilder
  一个Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句。通常这么做是因为SQL要动态的生成-否则你可以将它们放到外部的文件或存储过程中。正如你已经看到的,MyBatis在它的XML映射特性中有处理生成动态SQL的很强大的方案。然而,有时必须在Java代码中创建SQL语句的字符串。这种情况下,MyBatis有另外一种特性来帮助你,在减少典型的加号,引号,新行,格式化问题和嵌入条件来处理多余的逗号或AND连接词之前,事实上,在Java代码中动态生成SQL就是一个噩梦。
  MyBatis 3引入了一些不同的理念来处理这个问题,我们可以创建一个类的实例来调用其中的方法来一次构建SQL语句。但是我们的SQL结尾时看起来很像Java代码而不是SQL语句。相反,我们尝试了一些不同的做法。最终的结果是关于特定领域语言的结束,Java也不断实现它目前的形式…
  SelectBuilder的秘密
  SelectBuilder类并不神奇,如果你不了解它的工作机制也不会有什么好的作用。别犹豫,让我们来看看它是怎么工作的。SelectBuilder使用了静态引入和TreadLocal变量的组合来开启简洁的语法可以很容易地用条件进行隔行扫描,而且为你保护所有SQL的格式。它允许你创建这样的方法:
  public String selectBlogsSql() {
  BEGIN(); // Clears ThreadLocal variable
  SELECT("*");
  FROM("BLOG");
  return SQL();
  }
  这是一个非常简单的示例,你也许会选择静态地来构建。所以这里给出一个复杂一点的
  示例:
  private String selectPersonSql() {
  BEGIN(); // Clears ThreadLocal variable
  SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME");
  SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON");
  FROM("PERSON P");
  FROM("ACCOUNT A");
  INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID");
  INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID");
  WHERE("P.ID = A.ID");
  WHERE("P.FIRST_NAME like ?");
  OR();
  WHERE("P.LAST_NAME like ?");
  GROUP_BY("P.ID");
  HAVING("P.LAST_NAME like ?");
  OR();
  HAVING("P.FIRST_NAME like ?");
  ORDER_BY("P.ID");
  ORDER_BY("P.FULL_NAME");
  return SQL();
  }
  用字符串连接的方式来构建上面的SQL就会有一些繁琐了。比如:
  "SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, "
  "P.LAST_NAME,P.CREATED_ON, P.UPDATED_ON " +
  "FROM PERSON P, ACCOUNT A " +
  "INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID " +
  "INNER JOIN COMPANY C on D.COMPANY_ID = C.ID " +
  "WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) " +
  "OR (P.LAST_NAME like ?) " +
  "GROUP BY P.ID " +
  "HAVING (P.LAST_NAME like ?) " +
  "OR (P.FIRST_NAME like ?) " +
  "ORDER BY P.ID, P.FULL_NAME";
  如果你喜欢那样的语法,那么你就可以使用它。它很容易出错,要小心那些每行结尾增加的空间。现在,即使你喜欢这样的语法,下面的示例比Java中的字符串连接要简单也是没有疑问的:
  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();
  }
  这个例子有什么特殊之处?如果你看得仔细,那就不同担心偶然会重复的“AND”关键字,或在“WHERE”和“AND”或两者都没有中选择!上面的语句将会由例子对所有PERSON记录生成一个查询,有像参数一样的ID或firstName或lastName-或这三者的任意组合。SelectBuilder对理解哪里放置“WHERE”,哪里应该使用“AND”还有所有的字符串连接都是很小心的。最好的情况,无论你以何种顺序调用这些方法(只有一种例外使用OR()方法)。
  有两个方法会吸引你的眼球:BEGIN()和SQL()。总之,每个SelectBuilder方法应该以调用BEGIN()开始,以调用SQL()结束。当然你可以在中途提取方法来打断你执行的逻辑,但是SQL生成的范围应该以BEGIN()方法开始而且以SQL()方法结束。BEGIN()方法清理ThreadLocal变量,来确保你不会不小心执行了前面的状态,而且SQL()方法会基于这些调用,从最后一次调用BEGIN()开始组装你的SQL语句。注意BEGIN()有一个称为RESET()的代替方法,它们所做的工作相同,只是RESET()会在特定上下文中读取的更好。
  要按照上面示例的方式使用SelectBuilder,你应该静态引入如下内容:
  import static org.mybatis.jdbc.SelectBuilder.*;
  只要这个被引入了,那么你使用的类就会拥有SelectBuilder的所有可用的方法
  SqlBuilder
  和SelectBuilder相似,MyBatis也包含一个一般性的SqlBuilder。它包含SelectBuilder的所有方法,还有构建insert,update和delete的方法。在DeleteProvider,InsertProvider或UpdateProvider中(还有SelectProvider)构建SQL字符串时这个类就很有用。
  在上述示例中要使用SqlBuilder,你只需简单静态引入如下内容:
  import static org.mybatis.jdbc.SqlBuilder.*;

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-304850-1-1.html 上篇帖子: Mybatis异常汇总: 下篇帖子: 【原创】Mybatis学习笔记(一)——Spring集成Mybatis
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表