Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片段

点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

在这里插入图片描述

目前已经更新到了:

  • MyBatis(正在更新)

MyBatis 配置深入

核心配置

在这里插入图片描述

动态SQL

动态 SQL 是 MyBatis 的一个重要特性,用于根据条件动态生成不同的 SQL 语句。它允许开发者使用类似编程语言的逻辑结构来构建 SQL,解决了复杂查询条件下 SQL 的拼接问题,提高了开发效率和代码的可读性。
MyBatis 映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL 时动态变化的。

动态 SQL 的用途

  • 灵活性:处理动态变化的查询条件,例如用户界面的表单筛选条件。
  • 避免冗余:可以通过动态语法合并多个类似的 SQL 查询逻辑,减少代码冗余。
  • 提高效率:仅在需要时生成相应的 SQL,避免加载不必要的数据。

在这里插入图片描述

动态 SQL 的注意事项

null 值的处理

MyBatis 不会自动过滤 null 值,需在 SQL 标签中显式判断。

复杂逻辑的可读性

动态 SQL 逻辑过多会导致 XML 文件过于复杂,建议合理拆分。

性能问题

动态生成的 SQL 应尽量减少复杂性,避免影响数据库查询性能。

调试

可以开启 MyBatis 的日志功能,查看生成的 SQL,确保正确性。

参数拼接

我们需要根据实体的不同取值,使用不同的 SQL 语句来进行查询,比如在 ID 如果不为空的时候可以根据 ID 查询,如果 username 不空时还要加入 用户名作为条件,这种情况在我们的多条件组合查询中经常会碰到。

<!-- 查询所有用户信息 -->
<select id="selectList" resultType="icu.wzk.model.UserInfo">
    SELECT
        *
    FROM
        user_info
    <where>
        <if test="username != null and username != ''">
            and username=#{username}
        </if>
        <if test="password != null and password != ''">
            and password=#{password}
        </if>
        <if test="age != null and age != ''">
            and age=#{age}
        </if>
    </where>
</select>

编写的 Mapper 内容如下图所示:
在这里插入图片描述

编写代码, 复用刚才的代码,加入了一些值:

public class WzkIcu05 {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
        UserInfo userInfo = UserInfo
                .builder()
                .username("wzk")
                .build();
        List<UserInfo> dataList = userInfoMapper.selectList(userInfo);
        dataList.forEach(System.out::println);
        sqlSession.close();
    }
}

执行之后,可以看到打印的日志:

24/11/11 15:59:59 DEBUG jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7f010382]
24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: ==>  Preparing: SELECT * FROM user_info WHERE username=?
24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: ==> Parameters: wzk(String)
24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: <==      Total: 1
UserInfo(id=1, username=wzk, password=icu, age=18)

对应的截图如下所示:
在这里插入图片描述

循环拼接

我们在 UserMapper 中添加一个新的方法:


List<UserInfo> selectListByIdList(@Param("idList") List<Integer> idList);

对应的截图如下所示:
在这里插入图片描述

我们编写对应的 Mapper :

<select id="selectListByIdList" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">
    SELECT
        *
    FROM
        user_info
    <where>
        id IN
        <foreach collection="idList" open="(" close=")" separator="," index="index" item="item">
            #{item}
        </foreach>
    </where>
</select>

对应的结果截图如下所示:
在这里插入图片描述

我们编写 Java 代码进行测试:

public class WzkIcu06 {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
        List<Integer> idList = Arrays.asList(1, 2, 3);
        List<UserInfo> dataList = userInfoMapper.selectListByIdList(idList);
        dataList.forEach(System.out::println);
        sqlSession.close();
    }
}

目前数据库的数据如下(手动写了几条):
在这里插入图片描述
我们运行代码,控制台中输出的日志如下所示:

24/11/11 16:15:16 DEBUG jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6d2a209c]
24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: ==>  Preparing: SELECT * FROM user_info WHERE id IN ( ? , ? , ? )
24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: <==      Total: 3
UserInfo(id=1, username=wzk, password=icu, age=18)

对应的截图如下所示:
在这里插入图片描述
foreach 标签属性如下:

  • collection 要遍历的集合元素,主要不要写 #{}
  • open 语句的开始部分
  • close 语句的结束部分
  • item 集合遍历的每个元素,生成的遍历名
  • sperator 分割符号

片段抽取

SQL 中重复的 SQL 提取出来,使用 include 引用即可,最终达到 SQL 重复使用的目的。
我们在 UserInfoMapper 的接口中添加一个方法:

UserInfo selectOneBySegment(UserInfo userInfo);

对应的截图如下所示:
在这里插入图片描述
编写对应的 XML:

<sql id="SELECT_USER_INFO">
    SELECT * FROM user_info
</sql>

<select id="selectOneBySegment" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">
    <include refid="SELECT_USER_INFO"></include>
    <where>
        id=#{id}
    </where>
</select>

对应的截图如下所示:
在这里插入图片描述

public class WzkIcu07 {
    public static void main(String[] args) throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
        UserInfo userInfo = UserInfo
                .builder()
                .id(1L)
                .build();
        userInfo = userInfoMapper.selectOneBySegment(userInfo);
        System.out.println(userInfo);
        sqlSession.close();
    }
}

执行之后,控制台输出结果如下:

24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: ==>  Preparing: SELECT * FROM user_info WHERE id=?
24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: ==> Parameters: 1(Long)
24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: <==      Total: 1
UserInfo(id=1, username=wzk, password=icu, age=18)

对应的截图如下:
在这里插入图片描述

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

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

相关文章

Prompting LLMs to Solve Complex Tasks: A Review

文章目录 题目简介任务分解未来方向结论 题目 促使 LLM 解决复杂任务&#xff1a; 综述 论文地址&#xff1a;https://www.intjit.org/cms/journal/volume/29/1/291_3.pdf 简介 大型语言模型 (LLM) 的最新趋势显而易见&#xff0c;这体现在大型科技公司的投资以及媒体和在线社…

恋爱通信史之完整性

在前面的章节中&#xff0c;介绍了对通信消息的加密&#xff0c;可以保证保密性(机密性)。虽说中间人无法解密通信消息的内容&#xff0c;但是可以篡改通信的消息。在接受者视角来看&#xff0c;是无法识别通信消息是否被篡改。因此&#xff0c;必须引入一种机制&#xff0c;保…

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09; 注解 ColumnWidth Data…

C#调用C++ DLL方法之C++/CLI(托管C++)

托管C与C/CLI前世今生 C/CLI (C/Common Language Infrastructure) 是一种用于编写托管代码的语言扩展&#xff0c;它是为了与 .NET Framework 进行互操作而设计的。C/CLI 是 C 的一种方言&#xff0c;它引入了一些新的语法和关键字&#xff0c;以便更好地支持 .NET 类型和垃圾…

家庭智慧工程师:如何通过科技提升家居生活质量

在今天的数字化时代&#xff0c;家居生活已经不再只是简单的“住”的地方。随着物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;以及自动化技术的快速发展&#xff0c;越来越多的家庭开始拥抱智慧家居技术&#xff0c;将他们的家变得更加智能化、便捷和…

【Unity踩坑】出现d3d11问题导致编辑器崩溃

升级到Unity 6&#xff0c;有时出现下面这种D3D11的问题&#xff0c;会导致编辑器崩溃。 有人总结了这个问题的解决方法&#xff0c;可以做为参考&#xff1a; Failed to present D3D11 swapchain due to device reset/removed. List of Solutions - Unity Engine - Unity Dis…

CSP/信奥赛C++语法基础刷题训练(23):洛谷P1217:[USACO1.5] 回文质数 Prime Palindromes

CSP/信奥赛C语法基础刷题训练&#xff08;23&#xff09;&#xff1a;洛谷P1217&#xff1a;[USACO1.5] 回文质数 Prime Palindromes 题目描述 因为 151 151 151 既是一个质数又是一个回文数&#xff08;从左到右和从右到左是看一样的&#xff09;&#xff0c;所以 151 151 …

SCTransNet验证测试

SCTransNet 是PRCV 2024、ICPR 2024 Track 1、ICPR 2024 Track 2 三项比赛冠军方案的 Baseline, 同时也是多个优胜算法的Baselines. Bilibili 视频分享 【工作分享】SCTransNet:面向红外弱小目标检测的空间 - 通道交叉 Transformer_哔哩哔哩_bilibili 极市平台 推文分享 …

【C++】继承(inheritance)

引入 假设我们有一个动物类 class Animal { public:int age;void eat() {std::cout << "吃东西&#xff01;" << std::endl;} };又想写一个狗类&#xff0c;它也有年龄&#xff0c;也会吃&#xff0c;除此之外还有种类 class Dog { public:const char…

ThinkPad t61p 作SMB服务器,打印服务器,pc ,android ,ipad利用此服务器互传文件

1.在t61p上安装win7 2,配置好smb 服务 3.再安装好打印驱动程序 4.pc与win7利用系统的网络互相发现,映射为硬盘使用。 5.android&#xff0c;ipad安装ES文件浏览器访问win7 共享文件夹&#xff0c;互传文件。 6.android手机安装FE文件浏览器&#xff0c;可以利用花生壳外网…

Vue.js基础——贼简单易懂!!(响应式 ref 和 reactive、v-on、v-show 和 v-if、v-for、v-bind)

Vue.js是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。它专门设计用于Web应用程序&#xff0c;并专注于视图层。Vue允许开发人员创建可重用的组件&#xff0c;并轻松管理状态和数据绑定。它还提供了一个虚拟DOM系统&#xff0c;用于高效地渲染和重新渲染组件。Vue以…

Hive基础面试-如何理解复用率的

1. 模型的复用率你们是怎么做的&#xff1f; 简单直白的说就是你的模型复用率如何&#xff0c;在业务方是否认可该模型&#xff0c;也是衡量模型建设的一个标准&#xff0c;复用率数&#xff1a;数仓模型涉及的核心是追求模型的复用和共享&#xff0c;引用系数越高&#xff0c;…

Excel - VLOOKUP函数将指定列替换为字典值

背景&#xff1a;在根据各种复杂的口径导出报表数据时&#xff0c;因为关联的表较多、数据量较大&#xff0c;一行数据往往会存在三个以上的字典数据。 为了保证导出数据的效率&#xff0c;博主选择了导出字典code值后&#xff0c;在Excel中处理匹配字典值。在查询百度之后&am…

鸿蒙学习笔记:初探UI开发

介绍了ArkUI相关内容&#xff0c;涵盖其基本概念&#xff0c;如组件、页面及二者作用。阐述了ArkUI主要特征&#xff0c;包括多态组件、多样布局等多方面能力。还讲解了声明式、类Web两种开发范式及适用场景。声明式开发范式从多维度提供UI能力&#xff0c;介绍了其基础能力、整…

OceanBase Shell开放内核运维接口,运维更便捷

DBA在日常业务中面临着繁琐的运维管理任务&#xff0c;亟需高效的工具和灵活的解决方案帮助他们简化操作、提升效率。因此&#xff0c;命令行操作和维护工具&#xff08;CLI工具&#xff09;&#xff0c;因其高效、灵活、可远程管理以及技术深度等特点&#xff0c;成为DBA和开发…

springboot配置https,并使用wss

学习链接 springboot如何将http转https 可借鉴的参考&#xff1a; springboot如何配置ssl支持httpsSpringBoot配置HTTPS及开发调试的操作方法springboot实现的https单向认证和双向认证(java生成证书)SpringBoot配置Https访问的详细步骤SpringBoot配置Https入门实践springboo…

高精度计算题目合集

高精度计算题目合集 1168&#xff1a;大整数加法 1168&#xff1a;大整数加法 1168&#xff1a;大整数加法 高精度加法原理&#xff1a; a&#xff0c;b&#xff0c;c 都可以用数组表示。这些都是基于c语言的算术运算符形成的运算。 c 3 ( c 1 c 2 ) % 10 c_3(c_1c_2)\%1…

Javaweb前端HTML css 整体布局

最后一个是线条颜色 盒子&#xff0c;整体还是300&#xff0c;400

测试人员--如何区分前端BUG和后端BUG

在软件测试中&#xff0c;发现一个BUG并不算难&#xff0c;但准确定位它的来源却常常让测试人员头疼。是前端页面的问题&#xff1f;还是后台服务的异常&#xff1f;如果搞错了方向&#xff0c;开发人员之间的沟通效率会大大降低&#xff0c;甚至导致问题久拖不决。 那么&#…

嵌入式:Flash的分类以及Jlink/J-flash的编程支持

相关阅读 嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html?spm1001.2014.3001.5482 常见的Flash大致可以分为以下大类&#xff1a; Serial Nor FlashSerial Nand FlashParallel Nor FlashParallel Nand FlashSerial EEPROM Serial Nor Flash 介绍 Se…