读写数据库的时候,往往要根据传入的参数的不同,改变sql语句。

比如:如果传入了某个参数值,那就查询对应的字段,没传入,那就不查,这就是0048中的where--if

再比如:

  1. 如果传入了某个参数值,那就只查询这个字段,如果没传入,就看下一个字段是否传入,如果这些字段值都没有传入,那就按默认的条件查询。这是choose--when--otherwise
  2. update操作的时候,如果传入了某个参数值,那就更新该字段,如果没传入那就不更新该字段。这是set
  3. 如果要用in查询将某个集合中相关的数据都查出来,这就要foreach
  4. 如果程序传进来的参数值,还需要进一步拼接,这就要bind

choose--when--otherwise

查询书籍信息,如果传入了isbn号,那就只查这个字段,没传入的话,就看书名,有的话就查书名,如果isbn和书名都没有,那就把douban评分大于7分的查出来.

类似于switch,选择一条执行

<mapper namespace="net.sonng.mbt.mapper.BookMapper">
<select id="findBooks" parameterType="net.sonng.mbt.entity.Book" resultType="net.sonng.mbt.entity.Book">
SELECT * FROM book WHERE
<choose>
<when test="isbn!=null" > <!-- 如果传入了isbn号,那就只按isbn查 -->
isbn=#{isbn}
</when>
<when test="name!=null"> <!-- 如果没传入isbn号,就看是否有书名,有的话就只按书名查 -->
`name`=#{name} <!-- 注意name貌似是mysql的关键字,用上横(上划线)括起来 -->
</when>
<otherwise> <!-- 如果isbn和书名都没有,就将douban>7的书籍查出来 -->
douban>7 <!-- 实践证明,大于号>在这里可以正常用,换成转移字符:&gt;,也能用 -->
</otherwise>
</choose>
</select>
</mapper>

BookMapper.java接口略

测试类:

package net.sonng.mbt.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List; import net.sonng.mbt.entity.Book;
import net.sonng.mbt.mapper.BookMapper; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class BookTest {
public static void main(String[] args) throws IOException{
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
BookMapper bookMapper=session.getMapper(BookMapper.class);
Book book=new Book();
book.setName("深入理解Java 7 核心技术与最佳实践");
book.setPress("机械工业出版社");
book.setAuthor("成富著");
book.setDouban(6.9f);
book.setIsbn("9787111380399"); //传入了isbn
List<Book> books=bookMapper.findBooks(book);
for(Book b:books){
System.out.println(b);
}
}
}

输出如下:

DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE isbn=?   //传入了isbn就只按isbn查
DEBUG [main] - ==> Parameters: 9787111380399(String)
DEBUG [main] - <== Total: 1
Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=6.9]

book.setIsbn("9787111380399"); 注释掉,输出如下:

DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE `name`=?         //没有isbn,有name,就只按name查
DEBUG [main] - ==> Parameters: 深入理解Java 7 核心技术与最佳实践(String)
DEBUG [main] - <== Total: 1
Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=6.9]

book.setName("深入理解Java 7 核心技术与最佳实践");注释掉,输出如下:

DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE douban>7   //isbn和书名都没有,就把douban>7的列出了,下面有3条查询结果
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
Book [id=4, name=Java编程思想 第4版, press=机械工业出版社, author=(美)Bruce Eckel著, isbn=9787111213826, douban=9.1]

set

更新一条书籍信息,可能更新name、press、isbn、author、douban的一个或多个

    <select id="findBookById" parameterType="int" resultType="net.sonng.mbt.entity.Book">
SELECT * FROM book WHERE id=#{id}
</select>
<update id="updateBook" parameterType="net.sonng.mbt.entity.Book" >
UPDATE book
<set> <!-- set跟where的作用类似 -->
<if test="name!=null" >`name`=#{name},</if>
<if test="press!=null" >press=#{press},</if>
<if test="author!=null" >author=#{author},</if>
<if test="isbn!=null" >isbn=#{isbn},</if>
<if test="douban!=null" >douban=#{douban}</if>
</set>
WHERE id=${id}
</update>

测试类:

package net.sonng.mbt.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List; import net.sonng.mbt.entity.Book;
import net.sonng.mbt.mapper.BookMapper; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class BookTest {
public static void main(String[] args) throws IOException{
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
BookMapper bookMapper=session.getMapper(BookMapper.class);
Book book=bookMapper.findBookById(5); //update的时候,一般先将数据查出来再修改数据再更新
book.setDouban(10.0f);
bookMapper.updateBook(book);
session.commit(); //注意不要忘了提交事务
session.close();
}
}

foreach

用in查询的时候,传入的参数个数不明确,这时候就用foreach进行遍历

    <select id="findBookInId" parameterType="list" resultType="net.sonng.mbt.entity.Book">
SELECT * FROM book WHERE id In
<foreach item="id" index="i" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>

测试类:

package net.sonng.mbt.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import net.sonng.mbt.entity.Book;
import net.sonng.mbt.mapper.BookMapper; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class BookTest {
public static void main(String[] args) throws IOException{
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
BookMapper bookMapper=session.getMapper(BookMapper.class);
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(5);
List<Book> books=bookMapper.findBookInId(ids);
for(Book book:books){
System.out.println(book);
}
session.close();
}
}

输出如下:

DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE id In ( ? , ? , ? )
DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer), 5(Integer)
DEBUG [main] - <== Total: 3
Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=10.0]

foreach元素的几个属性:

----item:迭代元素的别名

----index:指定一个名字,用于表示在迭代过程中,每次迭代到的位置

----collection:传进来的参数的类型:list(单参数且参数类型为List)、array(单参数且参数类型为数组)、map(多参数)

----open:in后面的语句以什么开始

----separator:元素间的分隔符

----close:in后面的语句以什么结束

bind

该元素从OGNL表达式创建一个变量并将其绑定到上下文

    <select id="findBookLikeName" parameterType="string" resultType="net.sonng.mbt.entity.Book">
<bind name="pattern" value="'%'+_parameter+'%'" /> <!-- 传进来的参数是java,这里将其拼接成:%java% -->
SELECT * FROM book WHERE `name` LIKE #{pattern}
</select>

测试类:

package net.sonng.mbt.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; import net.sonng.mbt.entity.Book;
import net.sonng.mbt.mapper.BookMapper; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class BookTest {
public static void main(String[] args) throws IOException{
InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();
BookMapper bookMapper=session.getMapper(BookMapper.class);
List<Book> books=bookMapper.findBookLikeName("java");
for(Book book:books){
System.out.println(book);
}
session.close();
}
}

输出:

DEBUG [main] - ==>  Preparing: SELECT * FROM book WHERE `name` LIKE ?
DEBUG [main] - ==> Parameters: %java%(String) //传入的参数是拼接后的字符串
DEBUG [main] - <== Total: 4
Book [id=1, name=深入理解Java虚拟机 JVM高级特性与最佳实践, press=机械工业出版社, author=周志明著, isbn=9787111421900, douban=8.8]
Book [id=2, name=疯狂Java讲义 第3版, press=电子工业出版社, author=李刚著, isbn=9787121236693, douban=7.8]
Book [id=4, name=Java编程思想 第4版, press=机械工业出版社, author=(美)Bruce Eckel著, isbn=9787111213826, douban=9.1]
Book [id=5, name=深入理解Java 7 核心技术与最佳实践, press=机械工业出版社, author=成富著, isbn=9787111380399, douban=10.0]

bind的value属性:

----_parameter:注意下划线,表示传进来的参数本身

----parameter:没有下划线,表示传进来的参数的parameter属性

----_parameter.getName():注意下划线,表示调用传进来的参数对象的getName()方法的返回值

小结

if:传进来的某个参数不为空,那么查询该字段

where:可以动态的处理and和,

choose--otherwise:从前往后,哪个参数传进来了,那就只查询该参数,否则按otherwise查询

set:用于update语句,跟where作用类似

foreach:多用于IN查询,用于迭代传进来的参数集合

bind:将传进来的参数进行一些修改

这个文档可以看看:https://www.kancloud.cn/digest/andyalien-mybatis/190191

0064 MyBatis动态SQL--choose-when-otherwise--foreach--set--bind的更多相关文章

  1. MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】

    (第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...

  2. MyBatis动态SQL之一使用 if 标签和 choose标签

    bootstrap react https://segmentfault.com/a/1190000010383464 xml 中 < 转义 to thi tha <if test=&qu ...

  3. MyBatis从入门到精通(第4章):MyBatis动态SQL【foreach、bind、OGNL用法】

    (第4章):MyBatis动态SQL[foreach.bind.OGNL用法] 4.4 foreach 用法 SQL 语句中有时会使用 IN 关键字,例如 id in (1,2,3).可以使用 ${i ...

  4. mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句

    mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:1. if 语句 (简单的条件判断)2. c ...

  5. 9.mybatis动态SQL标签的用法

    mybatis动态SQL标签的用法   动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么 ...

  6. 超全MyBatis动态SQL详解!( 看完SQL爽多了)

    MyBatis 令人喜欢的一大特性就是动态 SQL. 在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的. MyBatis 动态 SQL 的出现, 解决了这个麻烦. My ...

  7. Mybatis动态SQL简单了解 Mybatis简介(四)

    动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ }   Mybatis应用中,S ...

  8. mybatis原理分析学习记录,mybatis动态sql学习记录

    以下个人学习笔记,仅供参考,欢迎指正. MyBatis 是支持定制化 SQL.存储过程以及高级映射的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转 ...

  9. mybatis 动态sql和参数

    mybatis 动态sql 名词解析 OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性, ...

  10. MyBatis动态SQL(认真看看, 以后写SQL就爽多了)

    目录 0 一起来学习 mybatis 1 数据准备 2 if 标签 2.1 在 WHERE 条件中使用 if 标签 2.1.1 查询条件 2.1.2 动态 SQL 2.1.3 测试 2.2 在 UPD ...

随机推荐

  1. sbusurface scattering

    http://www.iryoku.com 感觉Jorge有这个世界的全部.... 2012年那篇  那年他刚博士毕业.... 抄了他很多东西 ....抄了他这么多年..... 言归正传 对sss我之 ...

  2. SQL 服务没有及时响应启动或控制请求”的解决方法

        解决方法很简单:卸载删除跟IIS相关的几个漏洞安全更新补丁即可,包括KB939373.KB2290570和KB2124261.卸载微软安全更新补丁的方法:打开控制面板的“添加删除程序”面板,勾 ...

  3. HTML5 input file控件使用accept过滤限制的文件类型以及在谷歌下打开很慢的问题

    在文件上传控件(input type='file')中,可以通过accept属性实现对文件类型的过滤. 一.相关代码: 下面给出对应的文件上传控件代码: <input type="fi ...

  4. php 上传视频的代码,

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  5. 【pyhon】nvshens按目录图片批量下载爬虫1.00(多线程版)

    # nvshens按目录图片批量下载爬虫1.00(多线程版) from bs4 import BeautifulSoup import requests import datetime import ...

  6. Git使用帮助

    1. 本地创建新项目 git init git add . git commit -m "First commit" 2. 本地代码同步Push到远程仓库 git remote a ...

  7. C++ 11 - STL - 函数对象(Function Object) (中)

    我们再来看一个复杂的例子 需求: 我们需要对集合内每个元素加上一个特定的值 代码如下: AddInt.h class AddInt { private: int theValue; // the va ...

  8. How to change in the Cocos2d-x project from landscape to portrait both in iOS and Android

    iOS: This is done using XCode project details (select the required orientation) Android: AndroidMani ...

  9. hdu 2896 AC自动机模版题

    题意:输出出现模式串的id,还是用end记录id就可以了. 本题有个关键点:“以上字符串中字符都是ASCII码可见字符(不包括回车).”  -----也就说AC自动机的Trie树需要128个单词分支. ...

  10. SpringMVC请求参数和响应结果全局加密和解密

    前提 前段时间在做一个对外的网关项目,涉及到加密和解密模块,这里详细分析解决方案和适用的场景.为了模拟真实的交互场景,先定制一下整个交互流程.第三方传输(包括请求和响应)数据报文包括三个部分: 1.t ...