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

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

探索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中

相关文章
|
2月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
167 18
|
7月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
6月前
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
723 0
|
2月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
61 0
|
5月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
373 5
|
7月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
7月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
8月前
|
SQL XML Java
九、MyBatis动态SQL
九、MyBatis动态SQL
95 2
|
7月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
177 0
|
9月前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
867 6