mybatis学习(九)——动态sql
MyBatis 的强大特性之一便是它的动态 SQL。可以根据不同条件拼接 SQL 语句。
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。主要由以下几种元素。
- if
- where
- trim
- choose (when, otherwise)
- set
- foreach
- bind
1、if (判断)
实例:根据条件查询酒店列表
hotelMapper接口
- package com.pjf.mybatis.dao;
- import java.util.List;
import com.pjf.mybatis.po.Hotel;- public interface HotelMapper {
- public List<Hotel> getHotel(Hotel hotel);
- }
hotelMapper.xml
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <!-- resultMap使用 -->
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- where
- <if test="id!=null">
- id=#{id}
- </if>
- <if test="hotelName!=null && hotelName!=""">
- and hotel_name like concat('%',#{hotelName},'%')
- </if>
- <if test="price!=null">
- and price> #{price}
- </if>
- </select>
- </mapper>
测试类
- package com.pjf.mybatis;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.List;import org.apache.ibatis.io.Resources;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.junit.Test;
- import com.pjf.mybatis.dao.HotelMapper;import com.pjf.mybatis.po.Hotel;
- public class TestHotel {
- public SqlSessionFactory sqlSessionFactory() throws IOException {
- // mybatis的配置文件
- String resource = "mybatis_config.xml";
- // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
- InputStream is = Resources.getResourceAsStream(resource);
- // 构建sqlSession的工厂
- SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
- return sessionFactory;
- }
- @Test
- public void getHotel() throws IOException {
- SqlSessionFactory sessionFactory = sqlSessionFactory();
- SqlSession session = sessionFactory.openSession();
- HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
- System.out.println(hotelMapper.getClass());
- Hotel hotel = new Hotel(1001, "南京", "", 800);
- List<Hotel> list = hotelMapper.getHotel(hotel);
- for (Hotel hotel1 : list) {
- System.out.println(hotel1);
- }
- session.close();
- }
- }
查看结果
需要注意的是特殊字符需要转义,
- <if test="hotelName!=null && hotelName!=""">
常用的有以下字符
2、where
对于上面的查询条件,如果在测试类中
- Hotel hotel = new Hotel(1001, "南京", "", 800);改成 Hotel hotel = new Hotel(null,"南京","", 800);
结果会怎么样
sql多了一个and
解决:
a、增加默认条件1=1
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <!-- resultMap使用 -->
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- where 1=1
- <if test="id!=null">
- id=#{id}
- </if>
- <if test="hotelName!=null && hotelName!=""">
- and hotel_name like concat('%',#{hotelName},'%')
- </if>
- <if test="price!=null">
- and price> #{price}
- </if>
- </select>
- </mapper>
结果
b、增加where元素
将所有的元素放在where标签内,where元素会自动去除首位的and或or。注意是首位的and或者or。
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <!-- resultMap使用 -->
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- <where>
- <if test="id!=null">
- id=#{id}
- </if>
- <if test="hotelName!=null && hotelName!=""">
- and hotel_name like concat('%',#{hotelName},'%')
- </if>
- <if test="price!=null">
- and price> #{price}
- </if>
- </where>
- </select>
- </mapper>
3、trim (字符串截取)
如果and写在语句的末尾,该怎么解决呢
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <!-- resultMap使用 -->
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- <where>
- <if test="id!=null">
- id=#{id} and
- </if>
- <if test="hotelName!=null && hotelName!=""">
- hotel_name like concat('%',#{hotelName},'%') and
- </if>
- <if test="price!=null">
- price> #{price}
- </if>
- </where>
- </select>
- </mapper>
测试类
- package com.pjf.mybatis;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.List;
- import java.util.Map;
- import org.apache.ibatis.io.Resources;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.junit.Test;
- import com.pjf.mybatis.dao.HotelMapper;
- import com.pjf.mybatis.po.City;
- import com.pjf.mybatis.po.Hotel;
- public class TestHotel {
- public SqlSessionFactory sqlSessionFactory() throws IOException {
- // mybatis的配置文件
- String resource = "mybatis_config.xml";
- // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
- InputStream is = Resources.getResourceAsStream(resource);
- // 构建sqlSession的工厂
- SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
- return sessionFactory;
- }
- @Test
- public void getHotel() throws IOException {
- SqlSessionFactory sessionFactory = sqlSessionFactory();
- SqlSession session = sessionFactory.openSession();
- HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
- Hotel hotel = new Hotel(1001,"南京","",null);
- System.out.println(hotel);
- List<Hotel> list = hotelMapper.getHotel(hotel);
- for (Hotel hotel1 : list) {
- System.out.println(hotel1);
- }
- session.close();
- }
- }
结果:末尾就会多一个and
这时候就可以通过trim标签来解决:
trim 对trim标签体中拼接后的字符串进行操作
- prefix 对拼接后的字符串加前缀
- prefixOverrides 对拼接后的字符串去前缀
- suffix 对拼接后的字符串加后缀
- suffixOverrides 对拼接后的字符串去后缀
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- <!-- trim 对trim标签体中拼接后的字符串进行操作
- prefix 对拼接后的字符串加前缀
- prefixOverrides 对拼接后的字符串去前缀
- suffix 对拼接后的字符串加后缀
- suffixOverrides 对拼接后的字符串去后缀
- -->
- <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and">
- <if test="id!=null">
- id=#{id} and
- </if>
- <if test="hotelName!=null && hotelName!=""">
- hotel_name like concat('%',#{hotelName},'%') and
- </if>
- <if test="price!=null">
- price> #{price}
- </if>
- </trim>
- </select>
- </mapper>
这样就解决了
4、choose (分支选择)
MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。,但不同的是mybatis进入了一个分支后就不再进入其他分支。
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel
- <where>
- <choose>
- <when test="id!=null">
- id=#{id}
- </when>
- <when test="hotelName!=null && hotelName!=""">
- hotel_name like concat('%',#{hotelName},'%')
- </when>
- <when test="hotelAddress!=null && hotelAddress!=""">
- hotel_address=#{hotelAddress}
- </when>
- <when test="price!=null">
- price>#{price}
- </when>
- <otherwise>
- 1=1
- </otherwise>
- </choose>
- </where>
- </select>
- </mapper>
5、set
前面我们使用update可以进行全字段更新,但是如果是带了什么字段就更新什么字段,该怎么做呢。
可是使用set和if的结合,此外,set标签能自动删除末尾多余的逗号。
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <update id="updateHotel">
- update hotel
- <set>
- <if test="hotelName!=null">
- hotel_name=#{hotelName},
- </if>
- <if test="price!=null">
- price=#{price}
- </if>
- </set>
- <where>
- id=#{id}
- </where>
- </update>
- </mapper>
6、foreach
用来对集合进行遍历
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
- <mapper namespace="com.pjf.mybatis.dao.HotelMapper">
- <resultMap type="com.pjf.mybatis.po.Hotel" id="myHotel">
- <id column="id" property="id" jdbcType="INTEGER" />
- <result column="hotel_name" property="hotelName" jdbcType="VARCHAR" />
- <result column="hotel_address" property="hotelAddress"
- jdbcType="VARCHAR" />
- <result column="price" property="price" jdbcType="INTEGER" />
- </resultMap>
- <!-- resultMap使用 -->
- <select id="getHotel" resultMap="myHotel">
- select*
- from hotel where id in
- <!-- collection 指要遍历的集合 1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
- 2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
- 3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
- item 将遍历出的元素赋值给指定的变量
- separator 每个元素之间的分隔符
- open 遍历出的结果拼接出一个开始符
- close 遍历出的结果拼接一个结束符
- index 索引
- -->
- <foreach collection="list" item="ids" separator="," open="(" close=")">
- #{ids}
- </foreach>
- </select>
- </mapper>
测试类
- package com.pjf.mybatis;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import org.apache.ibatis.io.Resources;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.junit.Test;
- import com.pjf.mybatis.dao.HotelMapper;
- import com.pjf.mybatis.po.City;
- import com.pjf.mybatis.po.Hotel;
- public class TestHotel {
- public SqlSessionFactory sqlSessionFactory() throws IOException {
- // mybatis的配置文件
- String resource = "mybatis_config.xml";
- // 使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)TestHotel.class.getClassLoader()
- InputStream is = Resources.getResourceAsStream(resource);
- // 构建sqlSession的工厂
- SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
- return sessionFactory;
- }
- @Test
- public void getHotel() throws IOException {
- SqlSessionFactory sessionFactory = sqlSessionFactory();
- SqlSession session = sessionFactory.openSession(true);
- HotelMapper hotelMapper = session.getMapper(HotelMapper.class);
- List<Integer> id =new ArrayList<Integer>();
- id.add(1001);
- id.add(1002);
- id.add(1003);
- List<Hotel> list= hotelMapper.getHotel(id);
- for (Hotel hotel : list) {
- System.out.println(hotel);
- }
- session.close();
- }
- }
7、bind
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。
- <select id="getHotel" resultMap="myHotel">
- <bind name="_hotelName" value="'%' + hotelName + '%'" />
- SELECT * FROM hotel
- WHERE hotel_name LIKE #{_hotelName}
- </select>
mybatis学习(九)——动态sql的更多相关文章
- mybatis学习 十 动态 SQL
1. 根据方法传入的参数不同执行不同的 SQL 命令.称为动态 SQL, MyBatis 中动态 SQL 就是在 mapper.xml 中添加逻辑判断等. 2. <if>标签 <s ...
- mybatis学习之动态sql
mybatis的动态sql语句很强大,在mapper映射文件中使用简单的标签即可实现该效果,下面一个个记录: 1.select查询 简单的select类似如下: <select id=" ...
- mybatis 学习五 动态SQL语句
3.1 selectKey 标签 在insert语句中,在Oracle经常使用序列.在MySQL中使用函数来自动生成插入表的主键,而且需要方法能返回这个生成主键.使用myBatis的selectKey ...
- Mybatis学习笔记-动态SQL
概念 根据不同环境生成不同SQL语句,摆脱SQL语句拼接的烦恼[doge] 本质:SQL语句的拼接 环境搭建 搭建数据库 CREATE TABLE `blog`( `id` VARCHAR(50) N ...
- 【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...
- Mybatis入门之动态sql
Mybatis入门之动态sql 通过mybatis提供的各种标签方法实现动态拼接sql. 1.if.where.sql.include标签(条件.sql片段) <sql id="sel ...
- mybatis 详解------动态SQL
mybatis 详解------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...
- mybatis中的动态SQL
在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...
- Mybatis映射文件动态SQL语句-01
因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...
- Java数据持久层框架 MyBatis之API学习九(SQL语句构建器详解)
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...
随机推荐
- xcdatamodel的实质
修改后缀名为zip或者其它,可以查看到xcdatamodel是一个描述文件 <?xml version="1.0" encoding="UTF-8" st ...
- MySQL基础教程——创建数据库并插入数据
本节将介绍 MySQL 新建数据库,新建表,插入数据以及基本数据类型的相关知识.本节实验将创建一个名为 mysql_shiyan 的数据库,其中有两张表 employee和 department. 1 ...
- mac层到ath9k层,ath9k层到硬件层
如上图,整个 mac 层分成两个部分——UMAC 和 LMAC.LMAC 分成 MAC 下半部分和硬件抽象层. 硬件抽象层和ath9k层的连接 在hw.h中的函数struct ath_hw_ops() ...
- bootstrap 翻页的状态
翻页的状态 下面的实例演示了上表中所讨论的 class .disabled 的用法: <!DOCTYPE html><html><head><meta htt ...
- GTA5(侠盗猎车5)中文版破解版
)中文版破解版迅雷下载地址(使用迅雷新建任务填上地址): magnet:?xt=urn:btih:65F16B126D8A656E4FC825DE204EBFAF04B070FC
- 深入理解ES6箭头函数的this以及各类this面试题总结
ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿 它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this 一针见血式总结: 普通函数中的 ...
- tensorflow目标检测API安装及测试
1.环境安装配置 1.1 安装tensorflow 安装tensorflow不再仔细说明,但是版本一定要是1.9 1.2 下载Tensorflow object detection API 下载地址 ...
- 【单调队列】P1886 滑动窗口
GET 单调队列 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: Th ...
- UVa 12171 题解
英文题面不怎么友好,大家还是自行通过紫书了解题面吧... 解题思路: 1. 面对500 ^ 3的数据范围,我们需要先用离散化解决掉爆空间的问题. 2. 由于我们要求的总体积包括内空部分的体积,我们可以 ...
- TSS (任务状态段)的作用及结构
1.什么是TSS TSS全称Task State Segment ,是操作系统在进行进程切换时保存进程现场信息的段 2.TSS什么时候用,有什么用 TSS在任务(进程)切换时起着重要的作用,通过它保存 ...