0064 MyBatis动态SQL--choose-when-otherwise--foreach--set--bind
读写数据库的时候,往往要根据传入的参数的不同,改变sql语句。
比如:如果传入了某个参数值,那就查询对应的字段,没传入,那就不查,这就是0048中的where--if
再比如:
- 如果传入了某个参数值,那就只查询这个字段,如果没传入,就看下一个字段是否传入,如果这些字段值都没有传入,那就按默认的条件查询。这是choose--when--otherwise
- update操作的时候,如果传入了某个参数值,那就更新该字段,如果没传入那就不更新该字段。这是set
- 如果要用in查询将某个集合中相关的数据都查出来,这就要foreach
- 如果程序传进来的参数值,还需要进一步拼接,这就要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 <!-- 实践证明,大于号>在这里可以正常用,换成转移字符:>,也能用 -->
</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的更多相关文章
- MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】
(第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...
- MyBatis动态SQL之一使用 if 标签和 choose标签
bootstrap react https://segmentfault.com/a/1190000010383464 xml 中 < 转义 to thi tha <if test=&qu ...
- MyBatis从入门到精通(第4章):MyBatis动态SQL【foreach、bind、OGNL用法】
(第4章):MyBatis动态SQL[foreach.bind.OGNL用法] 4.4 foreach 用法 SQL 语句中有时会使用 IN 关键字,例如 id in (1,2,3).可以使用 ${i ...
- mybatis实战教程(mybatis in action)之八:mybatis 动态sql语句
mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:1. if 语句 (简单的条件判断)2. c ...
- 9.mybatis动态SQL标签的用法
mybatis动态SQL标签的用法 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么 ...
- 超全MyBatis动态SQL详解!( 看完SQL爽多了)
MyBatis 令人喜欢的一大特性就是动态 SQL. 在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的. MyBatis 动态 SQL 的出现, 解决了这个麻烦. My ...
- Mybatis动态SQL简单了解 Mybatis简介(四)
动态SQL概况 MyBatis 的强大特性之一便是它的动态 SQL 在Java开发中经常遇到条件判断,比如: if(x>0){ //执行一些逻辑........ } Mybatis应用中,S ...
- mybatis原理分析学习记录,mybatis动态sql学习记录
以下个人学习笔记,仅供参考,欢迎指正. MyBatis 是支持定制化 SQL.存储过程以及高级映射的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转 ...
- mybatis 动态sql和参数
mybatis 动态sql 名词解析 OGNL表达式 OGNL,全称为Object-Graph Navigation Language,它是一个功能强大的表达式语言,用来获取和设置Java对象的属性, ...
- 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 ...
随机推荐
- vim配置总结
本博文转自:http://www.cppblog.com/runsisi/archive/2013/04/06/199152.html? opt=admin 12年的最后一天配置了一下公司RHEL上的 ...
- iOS:风火轮活动刷新视图控件UIActivityIndicatorView的详细使用
动态风火轮视图控件:UIActivityIndicatorView 介绍:它是一种类似于风火轮旋转的视图控件,可用作刷新数据时显示加载过程所用,继承自UIView. 类型: typedef N ...
- go语言基础之不定参数的传递
1.不定参数的传递 示例1: package main //必须有一个main包 import "fmt" func myfunc(tmp ...int) { for _, dat ...
- Servlet学习笔记(一):生命周期
一.Servlet 生命周期: Servlet 生命周期可被定义为从创建直到毁灭的整个过程.以下是 Servlet 遵循的过程:初始化——响应请求——终止——回收 Servlet 通过调用 init ...
- 文本相似性计算总结(余弦定理,simhash)及代码
最近在工作中要处理好多文本文档,要求找出和每个文档的相识的文档.通过查找资料总结如下几个计算方法: 1.余弦相似性 我举一个例子来说明,什么是"余弦相似性". 为了简单起见,我们先 ...
- HTML-Html开发之Viewport的使用
近年来随着移动端的快速发展,越来越多传统的web应用需要适配移动终端,下面记录一下如何通过viewport实现简单的不同型号的手机端的适配问题.不过在此之前,介绍一下如何通过Chrome浏览器,调试在 ...
- 移动端HTML5框架
一:移动端HTML5框架 http://jquerymobile.com/jQuery Mobile http://jqtjs.com/jQTouch http://www.sencha.com/pr ...
- 配置静态监听解决ORA-12514错误的案例
今天做Linux下DG配置的时候,遇到一个现象.tnsname.ora文件配置都正常,tnsping也正常,监听也正常.可是仍然报ORA-12514错误: SQL> set lin 130 pa ...
- synchronized探究
synchronized的加锁方式 synchronized的本质是给对象上锁,对象包括实例对象,也包括类对象.常见的加锁方式有下面几种写法:(1)在非static方法上加synchronized,例 ...
- taro 更新
更新 Taro 提供了更新命令来更新 CLI 工具自身和项目中 Taro 相关的依赖 更新 Taro CLI 工具 # taro $ taro update self # npm npm i -g @ ...