【Spring集成MyBatis】动态sql

文章目录

  • 1. 什么是动态sql
  • 2. 动态sql之`<if>`
  • 3. 动态sql之`<where>`
  • 4. 动态sql之`<foreach>`
  • 5. sql片段抽取

此篇的代码基于 【Spring集成MyBatis】MyBatis的Dao层实现(基于配置,非注解开发)续写

1. 什么是动态sql

MyBatis映射文件中的SQL都比较简单,有时当业务逻辑复杂时,SQL是动态变化的,此时在前面学的简单SQL就无法满足需求了。
具体地说,假如我的数据库中有id,username,password三个字段,假如我想查询username=xxx的所有用户信息时候,查询语句是:
select * from user where username=xxx
当我想查询username=xxxpassword=xxx的所有用户信息时,查询语句是:
select * from user where username=xxx and password=xxx
这两者的共通之处就是,usernamepassword其实都是User里面的的一个属性,假如我的输入以User为条件,而不是以string为条件,让SQL语句自动去判断我要根据什么查询(有username根据username查询,有password根据password查询,有usernamepassword时根据二者共同查询)
如果我写的是select * from user where id=#{id} and username=#{username} and password=#{password},此时sql语句等效为图中红字部分:
在这里插入图片描述

但是这不是我们理想的效果,我们想的是,当password=""时,语句自动变为:
select * from user where id=#{id} and username=#{username}
这时候,就无法查询出结果,如果我们想要查询出结果,就需要使用动态sql去实现

2. 动态sql之<if>

如果有if语法,我们就可以很好地拼接SQL语句,假如id != 0,就写 id=#{id},假如username="",就写username=#{username},依此类推

<?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.example.demo.dao.UserMapper">

    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user where 1=1
        <if test="id!=0">
            and id=#{id}
        </if>
        <if test="username!=null">
            and username=#{username}
        </if>
        <if test="password!=password">
            and password=#{password}
        </if>
    </select>

</mapper>

<if>标签里的test写的就是判断,再次运行测试代码,仍能够查询出结果:

package com.example.demo.service;

import com.example.demo.dao.UserMapper;
import com.example.demo.domain.User;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class ServiceDemo {

    public static void main(String[] args) throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 模拟条件user
        User condition = new User();
        condition.setId(0);
        condition.setUsername("aaa");

        List<User> userList = userMapper.findByCondition(condition);

        System.out.println(userList);

    }
}

结果:
在这里插入图片描述

3. 动态sql之<where>

上面为了保证在无条件的时候不报错、也能够查询,我们还多写了一个where 1=1
为了使得代码更优雅,即有需要写的where时写上where,无需where时不写,还可以修改如下:

<?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.example.demo.dao.UserMapper">

    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user where 1=1
        <where>
            <if test="id!=0">
                and id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=password">
                and password=#{password}
            </if>
        </where>
    </select>

</mapper>

4. 动态sql之<foreach>

假如我们想查询id=1或者id=2或者id=3…的:
select * from user where id=1 or id=2 or id=3
select * from user where id in(1, 2, 3)
这时候我们可能就需要用到循环
在XML文件中:

<select id="findByIds" parameterType="list" resultType="user">
    select * from user
    <where>
        <foreach collection="list" open="id in(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </where>
</select>

其中,foreach中的:
collection指定遍历的类型,如果是列表就写list,如果是数组就写array
open写的是开始的内容
close写的是结束的内容
item里边是循环中当前的元素
seperator写的是分隔符
在接口里需要添加上该方法:

public List<User> findByIds(List<Integer> ids);

在测试类中:

List<Integer> ids = new ArrayList<Integer>();
ids.add(0);
ids.add(1);
List<User> userList = userMapper.findByIds(ids);

这样结果为id=0id=1的数据:
在这里插入图片描述

5. sql片段抽取

Sql中可以将重复的sql提取出来,使用时通过include引用即可,最终达到Sql重用的目的
例如,我们原本有以下文件:

<?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.example.demo.dao.UserMapper">

    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user
        <where>
            <if test="id!=0">
                and id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=password">
                and password=#{password}
            </if>
        </where>
    </select>

    <select id="findByIds" parameterType="list" resultType="user">
        select * from user
        <where>
            <foreach collection="list" open="id in(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

</mapper>

其中,两个语句都包含select * from user
那么,我们就使用以下语法抽取sql片段简化编写(sql标签):

<sql id="selectUser">select * from user</sql>

然后使用inclue标签进行引用,refid中写对应sql片段的id

<include refid="selectUser"></include>

所以以上代码可改写为:

<?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.example.demo.dao.UserMapper">

    <sql id="selectUser">select * from user</sql>

    <select id="findByCondition" parameterType="user" resultType="user">
        <include refid="selectUser"></include>
        <where>
            <if test="id!=0">
                and id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=password">
                and password=#{password}
            </if>
        </where>
    </select>

    <select id="findByIds" parameterType="list" resultType="user">
        <include refid="selectUser"></include>
        <where>
            <foreach collection="list" open="id in(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/183894.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OSG编程指南<十>:OSG几何体的绘制

1、场景基本绘图类 在 OSG 中创建几何体的方法比较简单&#xff0c;通常有 3 种处理几何体的手段&#xff1a; 使用松散封装的OpenGL 绘图基元&#xff1b;使用 OSG 中的基本几何体&#xff1b;从文件中导入场景模型。 使用松散封装的OpenGL 绘图基元绘制几何体具有很强的灵活…

Docker Swarm总结+service创建和部署、overlay网络以及Raft算法(2/3)

博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码下载地址&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb;…

在vscode中添加代码提示

添加配置 run->add_configuration 添加头文件路径 在c_cpp_properties.json中添加头文件路径 效果

PS 计数工具 基础使用方式讲解

上文PS 注释工具 基础使用方法讲解 中 我们讲了注释工具 解析来 我们来看这个计数工具 这里 我们换一张图像 如果 我要你数清楚 这个图上有几个咖啡豆 你能数清楚吗&#xff1f; 哈哈 其实也不难 不是特别大 但是 例如很多 且无规则物品时 我们可能就会数乱 左上角属性的话 我…

APP软件外包开发流程

外包APP软件项目的开发流程可以分为以下几个主要阶段&#xff0c;在整个流程中&#xff0c;沟通和合作是至关重要的&#xff0c;确保开发团队和客户之间有良好的沟通渠道&#xff0c;及时解决问题&#xff0c;保证项目按时交付。北京木奇移动技术有限公司&#xff0c;专业的软件…

时间敏感网络TSN的车载设计实践: 802.1Qbv协议

▎概述 IEEE 802.1Qbv[1]是TSN系列协议中备受关注的技术之一&#xff0c;如图1所示&#xff0c;它定义了一种时间感知整形器&#xff08;Time Aware Shaper&#xff0c;TAS&#xff09;&#xff0c;支持Qbv协议的交换机可以按照配置好的门控列表来打开/关闭交换机出口队列&…

前端编码技巧须知

前端开发中可能会使用到以下软件&#xff0c;它们各自具有不同的作用&#xff1a; 代码编辑器&#xff1a;例如Sublime Text、Atom、Visual Studio Code等&#xff0c;用于编写和编辑HTML、CSS和JavaScript等前端代码。网页浏览器&#xff1a;例如Chrome、Firefox、Safari等&a…

“关爱零距离.情暖老人心”主题活动

为提高社区老年人的生活质量&#xff0c;促进邻里间的互动与友谊&#xff0c;以及弘扬尊老爱幼的社区精神&#xff0c;11月21日山东省潍坊市金阳公益服务中心、重庆市潼南区同悦社会工作服务中心在潼南区桂林街道东风社区共同在潼南区桂林街道东风社区举办了“关爱零距离.情暖老…

EMG肌肉电信号处理合集(三)

本文主要展示常见的肌电信号预处理的实现&#xff0c;开发环境为matlab。 目录 1 肌电信号低通&#xff0c;高通&#xff0c;带通滤波 2 去除DC 0阶偏置&#xff0c;1阶偏置 3 全波整流 4 信号降采样 5 linear envolope / butterworth 低通滤波器 1 肌电信号低通&#xf…

【elementui】el-popover在列表里循环使用,取消的doClose无效解决办法

目录 一、需求效果二、代码详情html方法接口 一、需求效果 在使用elementui的Popover 弹出框时&#xff0c;需求是在table列表里使用&#xff0c;循环出来&#xff0c;无法取消。 二、代码详情 html <el-table-column v-if"checkPermission([admin,user:resetPass…

DevExpress中文教程 - 如何在macOS和Linux (CTP)上创建、修改报表(下)

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表。 DevExpress Reports — 跨平台报表组件&#x…

TOGAF®9持证人员专属升级福利—标准第10版认证过渡路径学习项目来啦!

TOGAF标准的含金量有多高&#xff1f; 是这些企业的优先选择 ▼ DXC Technology, Fujitsu, HCL Technologies, 华为, IBM, Intel, OpenText, Philips, Amazon, Apple, Capgemini, CISCO, Deloitte, HP, Microsoft, Oracle, SAP&#xff0c;国航&#xff0c;东航&#xff0c;工…

AI“胡说八道”?怎么解?

原创 | 文 BFT机器人 01 引言 近年来&#xff0c;人工智能产业迅猛发展&#xff0c;大型语言模型GPT-4发展势头强劲&#xff0c;OpenAI推出ChatGPT、微软推出Bing、马斯克推出“最好的聊天机器人Grok”……科技巨头纷纷入局AI领域&#xff0c;引入人工智能作为办公工具的行业…

java项目之品牌银饰售卖平台(ssm+vue)

项目简介 主要功能包括首页、个人中心、用户管理、促销活动管理、饰品管理、我的收藏管理、系统管理、订单管理等。管理员模块: 管理员可以查询、编辑、管理每个用户的信息和系统管理员自己的信息&#xff0c;同时还可以编辑、修改、查询用户账户和密码&#xff0c;以及对系统…

如何从 C# 制作报表到 FastReport Cloud

众所周知&#xff0c;我们的世界在不断发展&#xff0c;新技术几乎每天都会出现。如今&#xff0c;不再需要在办公室内建立整个基础设施、雇用人员来监控设备、处理该设备出现的问题和其他困难。 如今&#xff0c;越来越多的服务提供业务云解决方案&#xff0c;例如FastReport…

GEE:梯度提升树(Gradient Boosting Tree)分类教程(样本制作、特征添加、训练、精度、参数优化、贡献度、统计面积)

作者:CSDN @ _养乐多_ 本文将介绍在Google Earth Engine (GEE)平台上进行梯度提升树(Gradient Boosting Tree)分类的方法和代码,其中包括制作样本点教程(本地、在线和本地在线混合制作样本点,合并样本点等),加入特征变量(各种指数、纹理特征、时间序列特征、物候特征…

gitea仓库镜像同步至gitlab

1、参考文档&#xff1a;仓库镜像 | Gitea Documentation 2、错误一&#xff1a;账号密码错误问题 解决方法&#xff1a; 出现以上错误为第三步用户名&#xff08;Oauth2应用名称&#xff09;或者密码&#xff08;Gitlab个人访问令牌&#xff09;错误。 1&#xff09;如下图1…

NX二次开发UF_CURVE_add_faces_ocf_data 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_add_faces_ocf_data Defined in: uf_curve.h int UF_CURVE_add_faces_ocf_data(tag_t face_tag, UF_CURVE_ocf_data_p_t uf_offset_data ) overview 概述 Add a face col…

安索夫矩阵(ANSOFF)

&#x1f449;安索夫矩阵是策略管理之父安索夫博士于1957年提出的营销策略模型&#xff0c;该模型以“产品”和“市场”作为两大基本面&#xff0c;提出了4种不同组合下的营销策略&#xff0c;是营销分析中应用最广泛的工具之一。其主要逻辑是通过选择4种不同的成长性策略来实现…

基于springboot实现冬奥会科普平台系统【项目源码+论文说明】

基于SpringBoot实现冬奥会科普平台系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理平台应运而生&…