热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Java的MyBatis框架中对数据库进行动态SQL查询的教程

这篇文章主要介绍了Java的MyBatis框架中对数据库进行动态SQL查询的教程,讲解了MyBatis中一些控制查询流程的常用语句,需要的朋友可以参考下

其实MyBatis具有的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用 JDBC 或其他 相似框架的经验,你就明白要动态的串联 SQL 字符串在一起是十分纠结的,确保不能忘了空格或在列表的最后省略逗号。Mybatis中的动态 SQL 可以彻底处理这种痛苦。对于动态SQL,最通俗简单的方法就是我们自己在硬编码的时候赋予各种动态行为的判断,而在Mybatis中,用一种强大的动态 SQL 语 言来改进这种情形,这种语言可以被用在任意映射的 SQL 语句中。动态 SQL 元素和使用 JSTL 或其他相似的基于 XML 的文本处理器相似。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。
我们常用的几个节点元素有if,choose(when, otherwise),trim(where, if),foreach。真正使用下来我感觉有点像XSLT(文章后面会顺带提一下~)的用法。
(1)if 的用法

在ViisitMapper的分页配置中,如果pageIndex>-1 and pageSize>-1的时候就加入相应的分页SQL,否则就不添加(默认取全部),如下:



  select * from Visitor where
  status>0


  order by ${orderFieldStr} ${orderDirectionStr}


  因为我们的参数pageIndex与pageSize都是int值所以可以这样直接判断,如果是对象实例我们可以利用null判断来进行一些动态逻辑的控制,具体实际开发中就要看业务需求了。这里我认为要注意的是别十分顺手的吧and写成&&,这个在配置中不会被识别~。

(2)choose (when, otherwise)的用法

  choose when 主要在多个条件的情况下只满足其中一个条件的应用场景中使用,例如这里就构建一个query条件,分别传递id,name与createTime。假设我们查询Visitor表时,如果VisitorId有值则,使用Id查询,如果VisitorName有值则采用VisitName查询,如下,还是在david.mybatis.demo.IVisitorOperation接口类中添加List getListChooseWhenDemo(BasicQueryArgs args)方法。在VisitorMapper中添加相应的的select节点配置:

package david.mybatis.demo;

import java.util.List;

import david.mybatis.model.BasicQueryArgs;
import david.mybatis.model.PagenateArgs;
import david.mybatis.model.Visitor;
import david.mybatis.model.VisitorWithRn;

public interface IVisitorOperation {
  /*
   * 添加访问者
   */
  public int add(Visitor visitor);
  
  /*
   * 删除访问者
   */
  public int delete(int id);
  
  /*
   * 更新访问者
   */
  public int update(Visitor visitor);
  
  /*
   * 查询访问者
   */
  public Visitor query(int id);
  
  /*
   * 查询List
   */
  public List getList();
  
  /*
   * 分页查询List
   */
  public List getListByPagenate(PagenateArgs args);
  
  /*
   * 分页查询List(包含Rownum)
   */
  public List getListByPagenateWithRn(PagenateArgs args);
  
  /*
   * 基础查询
   */
  public Visitor basicQuery(int id);
  
  /*
   * 动态条件查询(choose,when)实例
   */
  public List getListChooseWhenDemo(BasicQueryArgs args);
  
  /*
   * 动态条件查询(where,if)实例
   */
  public List getListWhereDemo(BasicQueryArgs args);
  
  /*
   * 动态查询(foreach)实例
   */
  public List getListForeachDemo(List ids);
  
}

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

  
  
    
    
    
    
    
  
  
    select * from Visitor
  
  
  


(3)where if (trim)的用法

where关键词的好处是在于,如果有相应的过滤条件的话,它知道在适当的时候插入where关键词。而且它也知道在何时该去掉相应的AND与OR的连接符,主要应对如下情景



不会因为所有条件不满足变为


或者因为没有满足第一个条件,单单满足后面的条件变成


所以针对这种我们可以在建立choose when条件示例,同样在IVisitorOperation接口类中加入相应的方法public List getListWhereDemo(BasicQueryArgs args),把VisitorMapper配置文件中的相对应配置加上去如下:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

  
  
    select * from Visitor
  
  
  


(4)foreach的用法

在常用的动态SQL中我们有个业务场景是要where id in 一大串的ID,像这种情况我们就可以用到foreach啦,不必自己辛辛苦苦去拼接Id字符串啦。同样的步骤还是在IVisitorOperation接口类中加入相应的方法public List getListForeachDemo(List ids),然后再对应的Mapper文件中配置上相应的节点元素信息,如下:

<&#63;xml version="1.0" encoding="UTF-8"&#63;>

  
  
    select * from Visitor
  
  
  


最后你只需要在DemoRun中建立相应的测试方法,Mybatis里面的动态SQL也就完成啦,下面测试用的DemoRun方法

/*
   * 动态查询foreach实例
   */
  public static void getListForeachDemo(List ids) {
    SqlSession session = MybatisUtils.getSqlSession();
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    List ls = vOperation.getListForeachDemo(ids);
    for (Visitor visitor : ls) {
      System.out.println(visitor);
    }
  }
  
  /*
   * 动态查询where if实例
   */
  public static void getListWhereCondition(int id, String name, Date createTime) {
    name = name == "" &#63; null : name;
    SqlSession session = MybatisUtils.getSqlSession();
    BasicQueryArgs args = new BasicQueryArgs(id, name, createTime);
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    List ls = vOperation.getListWhereDemo(args);
    if (ls.size() == 0)
      System.out.println("查无匹配!");
    else {
      for (Visitor visitor : ls) {
        System.out.println(visitor);
      }
    }
  }

  /*
   * 动态查询choose when实例
   */
  public static void getListChooseWhenDemo(int id, String name, Date createTime) {
    name = name == "" &#63; null : name;
    SqlSession session = MybatisUtils.getSqlSession();
    BasicQueryArgs args = new BasicQueryArgs(id, name, createTime);
    IVisitorOperation vOperation = session.getMapper(IVisitorOperation.class);
    List ls = vOperation.getListChooseWhenDemo(args);
    if (ls.size() == 0)
      System.out.println("查无匹配!");
    else {
      for (Visitor visitor : ls) {
        System.out.println(visitor);
      }
    }
  }

201646151131782.png (795×440)   
PS:关于OGNL
OGNL 是 Object-Graph Navigation Language 的缩写,从语言角度来说:它是一个功能强大的表达式语言,用来获取和设置 java 对象的属性 , 它旨在提供一个更高抽象度语法来对 java 对象图进行导航,OGNL 在许多的地方都有应用,例如:
作为 GUI 元素(textfield,combobox, 等)到模型对象的绑定语言。
数据库表到 Swing 的 TableModel 的数据源语言。
web 组件和后台 Model 对象的绑定语言 (WebOGNL,Tapestry,WebWork,WebObjects) 。
作为 Jakarata Commons BeanUtils 或者 JSTL 的表达式语言的一个更具表达力的替代语言。
另外,java 中很多可以做的事情,也可以使用 OGNL 来完成,例如:列表映射和选择。 对于开发者来说,使用 OGNL,可以用简洁的语法来完成对 java 对象的导航。通常来说: 通过一个“路径”来完成对象信息的导航,这个“路径”可以是到 java bean 的某个属性,或者集合中的某个索引的对象,等等,而不是直接使用 get 或者 set 方法来完成。


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SQL中查询分组后每组行数的统计方法。通过使用count()函数和GROUP BY子句可以统计每组的行数,但是如何统计所有组的行数呢?本文提供了一种实现方法,并给出了相应的SQL查询语句。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
author-avatar
妩媚天天想我
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有