读写数据库的时候,往往要根据传入的参数的不同,改变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. 【Hibernate步步为营】--hql查询小介

    HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...

  2. SMTP用户枚举原理简介及相关工具

    前言 SMTP是安全测试中比较常见的服务类型,其不安全的配置(未禁用某些命令)会导致用户枚举的问题,这主要是通过SMTP命令进行的.本文将介绍SMTP用户枚举原理以及相关工具. SMTP SMTP命令 ...

  3. Heap Spray原理

    Heap Spray定义基本描述 Heap Spray并没有一个官方的正式定义,毕竟这是漏洞攻击技术的一部分.但是我们可以根据它的特点自己来简单总结一下.Heap Spray是在shellcode的前 ...

  4. Json转java对象和List集合

    public static void main(String[] args) { // 转换对象 String strJson ="{\"basemenu_id\":\& ...

  5. RS报表从按月图表追溯到按日报表

    相信很多COGNOS开发人员看到这个标题就会感觉很轻松,追溯无非是COGNOS自带的一个下钻的功能,但是这里却是固定的条件: 要求1:A报表显示按月的图表B报表显示按日的明细 2:追溯到B的时候B的开 ...

  6. 数据库case,when学习

    前几天工作中遇到了一个数据库统计相关的东西,主要使用case,when实现.如今说说基本情况: 有两个表school,studens,当中 school表结构例如以下: students表结构例如以下 ...

  7. NSURLConnection经常使用的代理方法

    NSURLConnection的代理Protocol定义有三类:NSURLConnectionDelegate.NSURLConnectionDataDelegate和NSURLConnectionD ...

  8. 转:不在同一个服务器上的数据库之间的数据操作(oracle/sql server的对比)

    如何操做不在同一个数据库中的数据操作: 一.对于SQL server来讲:  1.采用创建链接服务器的方式:    (1).创建链接服务器       exec sp_addlinkedserver  ...

  9. IOS客户端Coding项目记录(三)

    18:图片视图几种填充样式 _imgView.contentMode = UIViewContentModeScaleAspectFill; 如下: typedef NS_ENUM(NSInteger ...

  10. Java设计模式(二)-单例模式

    单例模式建议保证某个对象仅仅仅仅有一个实例,当仅仅有一个对象来协调整个系统的操作时,在计算机系统中.线程池.缓存.日志对象.对话框.打印机.显卡的驱动程序对象常被设计成单例.总之,选择单例模式就是为了 ...