MyBatis知多少(25)动态SQL
使用动态查询是MyBatis一个非常强大的功能。有时你已经改变WHERE子句条件的基础上你的参数对象的状态。在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的动态SQL标签。
所有的逻辑是使用一些额外的标签放在:XML文件。下面是一个例子,其中的SELECT语句将努力在两个方面:
如果想传递一个ID,然后它会返回所有与该ID的记录,
否则,将返回所有雇员ID为NULL的记录。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Employee">
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNull property="id">
id IS NULL
</isNull>
<isNotNull property="id">
id = #id#
</isNotNull>
</dynamic>
</select>
</sqlMap>
可以使用<isNotEmpty>标签如下检查条件。在此条件下将增加,只有当通过属性不为空。
..................
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotEmpty property="id">
id = #id#
</isNotEmpty>
</dynamic>
</select>
..................
如果想查询对id和/或雇员的名字选取。SELECT语句如下:
..................
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotEmpty prepend="AND" property="id">
id = #id#
</isNotEmpty>
<isNotEmpty prepend="OR" property="first_name">
first_name = #first_name#
</isNotEmpty>
</dynamic>
</select>
..................
例如:动态SQL
下面的例子将展示如何编写SELECT语句中使用动态SQL。考虑,我们已经在MySQL下有EMPLOYEE表:
CREATE TABLE EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
此表有如下只有一条记录:
mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 1 | Zara | Ali | 5000 |
| 2 | Roma | Ali | 3000 |
| 3 | Noha | Ali | 7000 |
+----+------------+-----------+--------+
3 row in set (0.00 sec)
Employee POJO 类:
要执行读取操作,让我们在Employee.java文件Employee类,如下所示:
public class Employee {
private int id;
private String first_name;
private String last_name;
private int salary;
/* Define constructors for the Employee class. */
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.first_name = fname;
this.last_name = lname;
this.salary = salary;
}
/* Here are the method definitions */
public int getId() {
return id;
}
public String getFirstName() {
return first_name;
}
public String getLastName() {
return last_name;
}
public int getSalary() {
return salary;
}
} /* End of Employee */
Employee.xml 文件:
要定义使用iBATIS SQL映射语句,我们将增加在以下文件Employee.xml修改<select>标记和这个标签定义,我们将定义一个“id”,这将被用于IbatisReadDy.java文件上执行动态SQL的SELECT查询数据库。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Employee">
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNotNull property="id">
id = #id#
</isNotNull>
</dynamic>
</select>
</sqlMap>
上面的SELECT语句将努力在两个方面(一)如果想传递一个ID,然后将相应的编号(二)返回的记录,否则将返回所有记录。
IbatisReadDy.java 文件:
文件将应用程序级别的逻辑从Employee表读出的条件记录:
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.*;
import java.sql.SQLException;
import java.util.*; public class IbatisReadDy{
public static void main(String[] args)
throws IOException,SQLException{
Reader rd=Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient smc=SqlMapClientBuilder.buildSqlMapClient(rd); /* This would read all records from the Employee table.*/
System.out.println("Going to read records.....");
Employee rec = new Employee();
rec.setId(1); List <Employee> ems = (List<Employee>)
smc.queryForList("Employee.findByID", rec);
Employee em = null;
for (Employee e : ems) {
System.out.print(" " + e.getId());
System.out.print(" " + e.getFirstName());
System.out.print(" " + e.getLastName());
System.out.print(" " + e.getSalary());
em = e;
System.out.println("");
} System.out.println("Records Read Successfully "); }
}
编译和运行:
下面是步骤来编译并运行上述应用。请确保已在进行的编译和执行之前,适当地设置PATH和CLASSPATH。
创建Employee.xml如上所示。
创建Employee.java如上图所示,并编译它。
创建IbatisReadDy.java如上图所示,并编译它。
执行IbatisReadDy二进制文件来运行程序。
会得到下面的结果,并且将记录从EMPLOYEE表中读取。
Going to read records.....
1 Zara Ali 5000
Record Reads Successfully
试试上面的例子中通过传递空值作为smc.queryForList(“Employee.findByID”,NULL)。
iBATIS OGNL 表达式
iBATIS的提供了强大的基于OGNL的表达式来消除其他元素。
if 语句
choose, when, otherwise 语句
where 语句
foreach 语句
if语句:
最常见的事情在动态SQL是有条件地包括一个where子句的一部分。例如:
<select id="findActiveBlogWithTitleLike"
parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<if test="title != null">
AND title like #{title}
</if>
</select>
这条语句会提供功能的可选的文本搜索类型。如果没有传递title,那么所有激活的博客将被退回。但是,如果传递一个标题,它会寻找标题以like 给定的条件。
可以包括多个if条件如下:
最常见的事情在动态SQL是有条件地包括一个where子句的一部分。例如:
<select id="findActiveBlogWithTitleLike"
parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null">
AND author like #{author}
</if>
</select>
choose, when, otherwise 语句:
iBATIS提供了一个选择的元素,它类似于Java的switch语句。这有助于选择很多种情况。
下面的例子将只搜索标题上如果提供,那么只有由作者如果已提供。如果没有提供,让我们只返回精选的博客:
<select id="findActiveBlogWithTitleLike"
parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE.
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author like #{author}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
where 语句:
如果我们看一下前面的例子中,如果没有一个条件满足会发生什么事?最终SQL看起来像这样:
SELECT * FROM BLOG
WHERE
这会失败,但iBATIS有一个简单的改变一个简单的解决方案,让一切工作正常:
<select id="findActiveBlogLike"
parameterType="Blog" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null>
AND author like #{author}
</if>
</where>
</select>
where元素知道只有插入WHERE ,如果有一个由含标签返回的任何内容。此外,如果该内容开头AND或OR,它知道剥离其关闭。
foreach语句:
foreach元素是非常强大的,并允许你指定一个集合,声明可以在元素的体内可用于项目和索引变量。
它也允许你指定打开和关闭的字符串,并添加一个分隔符放置在迭代之间。可以建立一个IN条件如下:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
系列文章:
MyBatis知多少(13)MyBatis如何解决数据库的常见问题
MyBatis知多少(25)动态SQL的更多相关文章
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- SSM框架之Mybatis(6)动态SQL
Mybatis(6)动态SQL 1.动态SQL 出现原因:有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了 1.1.if标签 我们根据实体类的不 ...
- Spring mybatis源码篇章-动态SQL节点源码深入
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-动态SQL基础语法以及原理 前话 前文描述到通过mybatis默认的解析驱动类org.apache.ibat ...
- SSM框架开发web项目系列(四) MyBatis之快速掌握动态SQL
前言 通过前面的MyBatis部分学习,已经可以使用MyBatis独立构建一个数据库程序,基本的增删查改/关联查询等等都可以实现了.简单的单表操作和关联查询在实际开的业务流程中一定会有,但是可能只会占 ...
- mybatis 接口绑定 和 动态SQL
一.MyBatis 接口绑定方案及多参数传递 1.作用:实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取mapper.xml中编写的sql 2.后面 ...
- Mybatis学习笔记之---动态sql中标签的使用
动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...
- mybatis入门基础(五)----动态SQL
一:动态SQL 1.1.定义 mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.2.案例需求 用户信息综合查询列表这个statement的定义使用动态s ...
- (转)Mybatis高级映射、动态SQL及获得自增主键
原文:http://www.cnblogs.com/edwinchen/p/4105278.html?utm_source=tuicool&utm_medium=referral 一.动态SQ ...
- Mybatis高级映射、动态SQL及获得自增主键
一.动态SQL 相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者 ...
随机推荐
- Spring3.2.4集成quartz2.2.1定时任务(demo).
在JavaEE系统中,我们会经常用到定时任务,下面是我自己写的一个demo. 前面几篇quartz博客感觉看的还是难懂 于是重新整理下 源码地址:http://pan.baidu.com/s/1BXH ...
- wicket基础应用(3)——wicket控件的隐藏和显示
在一个项目,页面经常要显示和隐藏一些控件,用wicket来控制显示和隐藏控件相当的方便. 1.最简单的隐藏和显示方法: wicket的控件大部分都有setVisible(...)方法,用这个方法就可以 ...
- Django基础——Model篇(二)
一 Model连表关系 一对多:models.ForeignKey(其他表) 多对多:models.ManyToManyField(其他表) 一对一:models.OneToOneFiel ...
- Leetcode 83 Remove Duplicates from Sorted List 链表
就是将链表中的重复元素去除 我的方法很简单就是如果链表的前后元素相同的话,将后一个元素删除 /** * Definition for singly-linked list. * struct List ...
- Extjs4中RadioGroup的赋值与取值
1.定义rg var rg = new Ext.form.RadioGroup({ fieldLabel : "test", items : [{ boxLabel : '每天', ...
- GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例
转:http://www.tuicool.com/articles/NVVnMn (1)GCD实现的同步异步.串行并行. ——同步sync应用场景:用户登录,利用阻塞 ——串行异步应用场景:下载等耗时 ...
- .svn批量删除
c.bat @echo on @rem 删除SVN版本控制目录 @rem for /r . %%a in (.) do @if exist "%%a\.svn" @echo &qu ...
- Windows出现BOOT\BCD错误的解决办法
这篇文章主要介绍了Windows出现BOOT\BCD错误的解决办法,本文讲解使用命令的方式解决这个问题,需要的朋友可以参考下 一般碰到 Boot Record Error 问题用系统盘自动修复一下就可 ...
- zz Windows 10安装教程:硬盘安装Win10 系统步骤(适合32位和64位)
Windows 10安装教程:硬盘安装Win10 系统步骤(适合32位和64位) Posted on 2015年01月28日 by 虾虾 22 Comments 最新的Windows 10 MSD ...
- Service Station - An Introduction To RESTful Services With WCF
Learning about REST An Abstract Example Why Should You Care about REST? WCF and REST WebGetAttribute ...