后台(41)——MyBatis的动态SQL

探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制



Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南



自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


版权声明



MyBatis可利用动态SQL极大的简化SQL语句的拼接。

在此介绍几种MyBatis中常用的动态SQL

where和if

还记得我们之前有一个查询学生的例子么?

<select id="findStudentList" parameterType="cn.com.StudentQueryVO" resultType="cn.com.StudentCustom">
        SELECT * FROM student WHERE gender=#{studentCustom.gender} and name like '%${studentCustom.name}%'
</select>

猛地一看这个SQL没啥问题,但是仔细一想又不对,studentCustom有没有可能为null呢?studentCustom.gender和studentCustom.name有没有可能为null呢?当然是有的,那么我们可以怎么处理一下呢?此时就可以用<where>和<if>,请看:

<select id="findStudentList" parameterType="cn.com.StudentQueryVO" resultType="cn.com.StudentCustom">
        SELECT * FROM student
        <where>
            <if test="studentCustom!=null">
                <if test="studentCustom.gender!=null">
                    and gender=#{studentCustom.gender}
                </if>
                <if test="studentCustom.name!=null">
                    and name like '%${studentCustom.name}%'
                </if>
            </if>
        </where>
</select>

在此利用标签<where>和<if>对应了某些查询条件为null的情况。有人或许有疑问,如果两个查询条件都满足的话在这个sql中岂不是有两个and了?甭担心,这种情形下MyBatis会自动删除掉掉第一个and

sql

其实,我们还可以把刚才这个例子继续优化一下利用<sql>提取出<if>作为sql片段从而提高代码的复用性

    <sql id="findStudentList_if">
        <if test="studentCustom!=null">
            <if test="studentCustom.gender!=null">
                and gender=#{studentCustom.gender}
            </if>
            <if test="studentCustom.name!=null">
                and name like '%${studentCustom.name}%'
            </if>
        </if>
    </sql>

然后在查询语句中引用该sql片段即可

<select id="findStudentList" parameterType="cn.com.StudentQueryVO" resultType="cn.com.StudentCustom">
        SELECT * FROM student
        <where>
            <include refid="findStudentList_if"></include>
        </where>
</select>

foreach

来看一种需求:查询出id为2、4、7的学生信息,我们可以这么写sql

SELECT * FROM student WHERE (id=2 OR id=4 OR id=7)

那么这个sql在MyBatis里又该怎么写呢?
在此可采用<foreach>标签来拼装这个条件(id=2 OR id=4 OR id=7)

首先,我们在StudentQueryVO中定义一个字段idsList用于传递这几个id值

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

import java.util.List;

//自定义的包装类型的pojo
public class StudentQueryVO {

    private List<Integer> idsList;

    //用户查询条件
    private StudentCustom studentCustom;

    public StudentCustom getStudentCustom() {
        return studentCustom;
    }

    public void setStudentCustom(StudentCustom studentCustom) {
        this.studentCustom = studentCustom;
    }

    public List<Integer> getIdsList() {
        return idsList;
    }

    public void setIdsList(List<Integer> idsList) {
        this.idsList = idsList;
    }

    //其他查询条件,比如教师,课程,学校等等
}

再来看mapper.xml

<sql id="findStudentList_ids_if">
        <if test="idsList!=null">
            <foreach collection="idsList" item="student_id" open="(" close=")" separator="OR">
                id=#{student_id}
            </foreach>
        </if>
</sql>

<select id="findStudentList" parameterType="cn.com.StudentQueryVO" resultType="cn.com.StudentCustom">
    SELECT * FROM student
    <where>
        <include refid="findStudentList_ids_if"></include>
    </where>
</select>

重点来看这个<foreach>标签

  • collection表示pojo中的集合
  • item表示遍历时集合中每个元素
  • open表示组拼后的语句的开头
  • close表示组拼后的语句的结尾
  • separator表示每个部门的连接符

最后来看测试代码

@Test
    public void findStudentList() throws IOException {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        StudentQueryVO studentQueryVO=new StudentQueryVO();
        List<Integer> idsList=new ArrayList<Integer>();
        idsList.add(2);
        idsList.add(4);
        idsList.add(7);
        studentQueryVO.setIdsList(idsList);
        List<StudentCustom> studentList = studentMapper.findStudentList(studentQueryVO);
        for (int i = 0; i <studentList.size(); i++) {
            StudentCustom sc = studentList.get(i);
            System.out.println(sc);
        }
        sqlSession.commit();
        sqlSession.close();
    }


其实,这些动态SQL并不难,也不需要死记硬背。但是要把握住总的原则和目标:利用动态SQL拼装成原始的sql语句。在实际开发时也可以先写出原始sql语句再写到mapper.xml中

时间: 2024-09-08 07:58:09

后台(41)——MyBatis的动态SQL的相关文章

Spring+Mybatis实现动态SQL查询

在报表类应用中,通常需要根据不同的维度去组合复杂的查询条件,然后构造SQL去执行查询.如果只是通过在程序中简单地拼接SQL语句,工作量会非常大,而且代码可能也非常难以维护.Mybatis支持动态SQL查询功能,可以通过配置动态的SQL来简化程序代码中复杂性,不过,这个颇有点XML编程的韵味,通过XML来处理复杂的数据判断.循环的功能,其实也很好理解. 准备工作 下面,我们首先创建一个MySQL示例表,如下所示: 01 CREATE TABLE `traffic_info` ( 02 `id` i

关于mybatis的动态sql问题

问题描述 关于mybatis的动态sql问题 就是在mybatis中我想写一条sql查询两种列表 想通过参数控制,想问一下查询的字段可不可以通过前台传入的参数进行if标签判断如: select <if test=""timeState !=null and timeState='month'""> to_char(trunc(co.CREATE_TIME)'yyyy-mm-dd') as createTime <if test="&quo

Mybatis解析动态sql原理分析

1.MyBatis一般使用步骤 1.1获取Configuration实例或编写配置文件 //获取Configuration实例的样例 TransactionFactory transactionFactory = new JdbcTransactionFactory();//定义事务工厂 Environment environment = new Environment("development", transactionFactory, dataSource); Configurat

MyBatis使用动态SQL标签的小陷阱_java

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 现在MyBatis越来越受大家的喜爱了,它的优势大家都知道,我就不多说了,直接说重点. MyBatis中提供动态SQL功能,我们可以使用<if><when&

MyBatis 执行动态 SQL语句详解_java

大家基本上都知道如何使用 MyBatis 执行任意 SQL,使用方法很简单,例如在一个 XXMapper.xml 中: <select id="executeSql" resultType="map"> ${_parameter} </select> 你可以如下调用: sqlSession.selectList("executeSql", "select * from sysuser where enabled

oracle+mybatis 使用动态Sql当插入字段不确定的情况下实现批量insert_oracle

最近做项目遇到一个挺纠结的问题,由于业务的关系,DB的数据表无法确定,在使用过程中字段可能会增加,这样在insert时给我造成了很大的困扰. 先来看一下最终我是怎么实现的: <insert id="batchInsertLine" parameterType="HashMap"> <![CDATA[ INSERT INTO tg_fcst_lines(${lineColumn}) select result.*,sq_fcst_lines.next

mybatis的动态sql详解(精)

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力.如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号.动态 SQL 可以彻底处理这种痛苦. 通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中. 动态SQL元素和使用 JSTL或其他相似的基于XML的文本处理器相似.在MyBatis之前的版本中,有很多

mybatis中动态sql常用的标签

用来循环容器的标签forEach,查看例子 //mapper中我们要为这个方法传递的是一个容器,将容器中的元素一个一个的 //拼接到xml的方法中就要使用这个forEach这个标签了 public List<Entity> queryById(List<String> userids); //对应的xml中如下 <select id="queryById" resultMap="BaseReslutMap" > select *

MyBatis Review——动态sql

        MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号.利用动态 SQL 这一特性可以彻底摆脱这种痛苦.       通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中.      动态 SQL 元素和使用 JST