最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下。在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输出映射,今天这篇博文,小编主要来简单的介绍一下mybatis中的动态sql,有的小伙伴会问,既然有动态sql,那是不是也应该存在静态sql,答案是肯定的。那么什么是静态sql呢,静态sql语句一般用于嵌入式sql应用中,在程序运行之前,sql语句必须是确定的,例如sql语句中涉及的列名和表名必须是存在的,静态sql语句的编译是在应用程序运行前进行的,编译的结果会存储在数据库内容,而后程序进行时,数据库将直接执行编译好的sql语句,降低运行时的开销。所谓的动态sql,是在应用程序运行时被编译和执行的,例如使用DB2的交互式工具CLP访问数据库时,用户输入的sql语句是不确定的,因此sql语句只能被动态的编译,动态的sql的应用较多,常见的CLI和JDBC应用程序都使用动态sql。这篇博文小编主要分三个部分来分别进行介绍,动态sql、sql片段和foreach。

一、动态sql

1.1定义

mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接,组装。

1.2案例需求

用户信息综合查询列表这个statment的定义使用动态sql,对查询条件进行判断,如果输入参数不为空进行查询拼接。

1.3UserMapper.xml

<!-- 用户信息综合查询
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.username}:取出pojo对象中用户名称
-->
    <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo"
    resultType="com.mybatis.entity.UserCustom">
        select * from t_user
        <!-- 动态sql查询:where可以自动去掉第一个and -->
        <where>
            <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!='' ">
                    and sex=#{userCustom.sex}
                </if>
                <if test="userCustom.username!=null and userCustom.username!='' ">
                    and username=#{userCustom.username}
                </if>
            </if>
        </where>
<!--          where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%' -->
    </select>

1.4测试代码

@Test
    public void testFindUserList() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //创造查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        UserCustom userCustom = new UserCustom();
//        userCustom.setSex("2");
        //这里使用动态sql,如果不设置某个值,条件不会拼接sql中
        userCustom.setUsername("小");
        userQueryVo.setUserCustom(userCustom);
        // 创建Usermapper对象,mybatis自动生成mapper代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<UserCustom>list=mapper.findUserList(userQueryVo);
        //测试动态sql,属性的非空判断测试
//        List<UserCustom>list=mapper.findUserList(null);
        System.out.println(list);
        sqlSession.commit();
        sqlSession.close();
    }

二、sql片段

2.1需求

将上边的动态sql判断代码抽取出来,组成一个sql片段,其她的statment中就可以引用sql片段,方便开发。

2.2定义sql片段

<!-- 定义sql片段,Id是唯一标识
         建议:是基于单表来定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包含where
     -->
    <sql id="query_user_where" >
        <if test="userCustom!=null">
                <if test="userCustom.sex!=null and userCustom.sex!='' ">
                    and sex=#{userCustom.sex}
                </if>
               <if test="userCustom.username!=null and userCustom.username!='' ">
                    and username=#{userCustom.username}
                </if>
            </if>
    </sql>

2.3在mapper.xml中定义的statment中引用sql片段

<!-- 用户信息综合查询
    #{userCustom.sex}:取出pojo包装对象中性别值
    ${userCustom.username}:取出pojo对象中用户名称
-->
    <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo"
    resultType="com.mybatis.entity.UserCustom">
        select * from t_user
        <!-- 动态sql查询:where可以自动去掉第一个and -->
        <where>
        <!-- 引用sql片段的id,如果refid指定的不在本mapper.xml中,需要前边加namespace -->
            <include refid="query_user_where"></include>
            <!-- 这里可以引用其它的sql片段 -->
        </where>
    </select>

三、foreach

作用:向sql传递数据或者list,mybatis使用foreach解析,在用户查询列表和查询总数的statment中增加多个id输入查询。

3.1需求:sql语句如下,两种方法:

SELECT * FROM t_user WHERE id=1 OR id=10 OR id=16

SELECT * FROM t_user WHERE id IN(1,10,16)

3.2在输入参数包装类型中添加List<Integer>ids传入多个id

package com.mybatis.entity;

import java.util.List;

/**
 *
 * @ClassName: UserQueryVo
 * @Description: TODO(包装类型)
 * @author 丁国华
 *
 */
public class UserQueryVo {

    public List<Integer> ids;

    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
}

3.3mapper.xml代码

<!-- 实现下边的sql拼接
            select * from t_user where id=1 OR id=2 OR id=3
    -->
    <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo"
    resultType="com.mybatis.entity.User">
            select * from t_user
        <where>
                <if test="ids!=null">
                <!-- 使用foreach遍历ids
                    collection:指定输入对象的集合属性
                    item:每个遍历生成对象中
                    open:开始遍历时拼接的串
                    close:技术遍历时拼接的串
                    separator:遍历的两个对象中需要拼接的串
                 -->
                <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
                    id=#{user_id}
                </foreach>
            </if>
        </where>
    </select>

select *from t_user where id in(1,2,3)的mapper.xml配置

<select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo"
    resultType="com.mybatis.entity.User">
            select * from t_user
        <where>
                <if test="ids!=null">
                <!--
                    使用foreach遍历ids
                    collection:指定输入对象的集合属性
                    item:每个遍历生成对象中
                    open:开始遍历时拼接的串
                    close:技术遍历时拼接的串
                    separator:遍历的两个对象中需要拼接的串
                 -->
                <!-- 实现“ select * from t_user where  id in(1,2,3)”拼接 -->
                <foreach collection="ids" item="user_id" open="AND id in ("  close=")" separator=",">
                    id=#{user_id}
                </foreach>
            </if>
        </where>
    </select>
userMapper.java代码
 public interface UserMapper {
    //ids查询用户数据
     public List<User> findUserByIds(UserQueryVo userQueryVo);
 }

Junit测试代码

@Test
    public void findUserByIdsTest() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 创建Usermapper对象,mybatis自动生成mapper代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //创造查询条件
        UserQueryVo userQueryVo = new UserQueryVo();
        //传入多个id
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        //将ids通过userQueryVo传入statement中
        userQueryVo.setIds(ids);
        //调用userMapper的代码
        List<UserCustom> userList= mapper.findUserList(userQueryVo);
        System.out.println(userList);
        sqlSession.close();
    }

小编寄语:该博文小编主要简单的介绍了mybatis中的动态sql,MyBatis的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他相似框架的经验,你就明白条件地串联 SQL字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号。动态 SQL可以彻底处理这种痛苦。通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中。

动态SQL元素和使用JSTL或其他相似的基于XML的文本处理器相似。在MyBatis之前的版本中,有很多的元素需要来了解。MyBatis3大大提升了它们,现在用不到原先一半的元素就能工作了。MyBatis采用功能强大的基于OGNL的表达式来消除其他元素。 小编博文,小编将继续介绍mybatis的相关知识,敬请期待`(*∩_∩*)′。

【mybatis深度历险系列】mybatis中的动态sql的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的输入映射和输出映射

    在前面的博文中,小编介绍了mybatis的框架原理以及入门程序,还有mybatis中开发到的两种方法,原始开发dao的方法和mapper代理方法,今天博文,我们来继续学习mybatis中的相关知识,随 ...

  2. 【mybatis深度历险系列】mybatis的框架原理+入门程序解析

    在前面的博文中,小编介绍了springmvc的相关知识点,在今天这篇博文中,小编将介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和 ...

  3. 【mybatis深度历险系列】延迟加载

    在前面的博文中,小编主要简单的介绍了mybatis中的高级映射,小伙伴们可以把mybatis和hibernate的因素进行对比,更加有利于理解.今天这篇博文,小编主要来简单介绍一下mybatis中的延 ...

  4. 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发

    使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...

  5. 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  6. Mybatis 系列9-强大的动态sql 语句

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  7. mybatis中的动态SQL

    在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...

  8. MyBatis基础入门《二十》动态SQL(foreach)

    MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...

  9. MyBatis基础入门《十九》动态SQL(set,trim)

    MyBatis基础入门<十九>动态SQL(set,trim) 描述: 1. 问题 : 更新用户表数据时,若某个参数为null时,会导致更新错误 2. 分析: 正确结果: 若某个参数为nul ...

随机推荐

  1. Python求解啤酒问题(携程2016笔试题)

    问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的 ...

  2. jsonViewer json格式化工具

    以前一直以来都觉得xml个可读性要比json的可读性好,后来使用了JSON Viewer这个小工具之后,发现自己错了.之前认为json的可读性差,完全是因为没有很好的查看工具.JSON Viewer这 ...

  3. [LeetCode] Perfect Number 完美数字

    We define the Perfect Number is a positive integer that is equal to the sum of all its positive divi ...

  4. tooltip.css-2.0文档

     tooltip.css 纯CSS鼠标提示工具. v. 2.0.0 更新日期:2018.4.12 预览DEMO.  安装: 只需在页面中引入"tooltip.css"或" ...

  5. Oracle12c功能增强新特性之维护&amp;升级&amp;恢复&amp;数据泵等

    1.   内容提要 1)   表分区维护的增强. 2)   数据库升级改善. 3)   跨网络还原/恢复数据文件. 4)   数据泵的增强. 5)   实时ADDM. 6)   并发统计信息收集. 2 ...

  6. 分析 ajax 请求并抓取今日头条街拍美图

    首先分析街拍图集的网页请求头部: 在 preview 选项卡我们可以找到 json 文件,分析 data 选项,找到我们要找到的图集地址 article_url: 选中其中一张图片,分析 json 请 ...

  7. 51nod 平均数(马拉松14)

    平均数 alpq654321 (命题人)   基准时间限制:4 秒 空间限制:131072 KB 分值: 80 LYK有一个长度为n的序列a. 他最近在研究平均数. 他甚至想知道所有区间的平均数,但是 ...

  8. bzoj4946 Noi2017 蔬菜

    题目描述 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有nn 种蔬菜,小NN 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方案,以获得最多的收益. 在计算销 ...

  9. uva 10118(DP)

    UVA 10118 题意: 有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果, 如果篮子里有两个相同的糖果,那么就可以把这两个(一对)糖果放进自己 ...

  10. [Codeforces]860E Arkady and a Nobody-men

    屯一个虚树的板子,顺便总结一下这样的题型. Description 给定一棵n个节点的有根树,在输入数据通过给出每个节点的父亲来表示这棵树.若某个节点的父亲为0,那么该节点即为根.现在对于每个点,询问 ...