当前位置: 首页 > news >正文

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*FROMuser_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*FROMuser_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)

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

http://www.lryc.cn/news/488371.html

相关文章:

  • 突破自动驾驶瓶颈!KoMA:多智能体与大模型的完美融合
  • YOLO入门教程(三)——训练自己YOLO11实例分割模型并预测【含教程源码+一键分类数据集 + 故障排查】
  • 【加入默语老师的私域】C#面试题
  • 称重传感器指示器行业全面且深入的分析
  • NAT网络地址转换——Easy IP
  • 【Visual Studio系列教程】如何在 VS 上编程?
  • Mybatis-Plus 多租户插件属性自动赋值
  • AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu
  • Python入门(7)--高级函数特性详解
  • 【数据库原理】理解数据库,基础知识
  • VConsole——(H5调试工具)前端开发使用于手机端查看控制台和请求发送
  • 论文分享 | FuzzLLM:一种用于发现大语言模型中越狱漏洞的通用模糊测试框架
  • vmWare虚拟环境centos7安装Hadoop 伪分布式实践
  • 【C++入门(一)】半小时入门C++开发(深入理解new+List+范围for+可变参数)
  • Vue 3与TypeScript集成指南:构建类型安全的前端应用
  • MATLAB和Python发射光谱
  • IEEE(常用)参考文献引用格式详解 | LaTeX参考文献规范(IEEE Trans、Conf、Arxiv)| 期刊会议名缩写查询
  • 第二十周:机器学习
  • Elasticsearch面试内容整理-Elasticsearch 基础概念
  • 机器学习算法模型系列——Adam算法
  • Qt按钮类-->day09
  • 基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能
  • 基于Kafka2.1解读Consumer原理
  • 深度学习:ResNet每一层的输出形状
  • 国内几大网络安全公司介绍 - 网络安全
  • 修改Android Studio项目配置JDK路径和项目Gradle路径的GUI工具
  • ✅DAY30 贪心算法 | 452. 用最少数量的箭引爆气球 | 435. 无重叠区间 | 763.划分字母区间
  • 关于Redis单线程模型以及IO多路复用的理解
  • 学习ASP.NET Core的身份认证(基于Cookie的身份认证1)
  • 奇门遁甲中看债务时用神该怎么取?