ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片断 [打印本页]

作者: 冬雨财经    时间: 2024-12-2 01:41
标题: Java-05 深入浅出 MyBatis - 配置深入 动态 SQL 参数、循环、片断
点一下关注吧!!!非常感谢!!持续更新!!!

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


目前已经更新到了:


MyBatis 配置深入

焦点配置


动态SQL

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



动态 SQL 的注意事项

null 值的处理

MyBatis 不会自动过滤 null 值,需在 SQL 标签中显式判断。
复杂逻辑的可读性

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

动态生成的 SQL 应只管减少复杂性,制止影响数据库查询性能。
调试

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

我们需要根据实体的不同取值,使用不同的 SQL 语句来举行查询,比如在 ID 如果不为空的时间可以根据 ID 查询,如果 username 不空时还要参加 用户名作为条件,这种情况在我们的多条件组合查询中经常会碰到。
  1. <!-- 查询所有用户信息 -->
  2. <select id="selectList" resultType="icu.wzk.model.UserInfo">
  3.     SELECT
  4.         *
  5.     FROM
  6.         user_info
  7.     <where>
  8.         <if test="username != null and username != ''">
  9.             and username=#{username}
  10.         </if>
  11.         <if test="password != null and password != ''">
  12.             and password=#{password}
  13.         </if>
  14.         <if test="age != null and age != ''">
  15.             and age=#{age}
  16.         </if>
  17.     </where>
  18. </select>
复制代码
编写的 Mapper 内容如下图所示:

编写代码, 复用刚才的代码,参加了一些值:
  1. public class WzkIcu05 {
  2.     public static void main(String[] args) throws IOException {
  3.         InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
  4.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
  5.                 .build(resourceAsStream);
  6.         SqlSession sqlSession = sqlSessionFactory.openSession();
  7.         UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
  8.         UserInfo userInfo = UserInfo
  9.                 .builder()
  10.                 .username("wzk")
  11.                 .build();
  12.         List<UserInfo> dataList = userInfoMapper.selectList(userInfo);
  13.         dataList.forEach(System.out::println);
  14.         sqlSession.close();
  15.     }
  16. }
复制代码
实行之后,可以看到打印的日志:
  1. 24/11/11 15:59:59 DEBUG jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7f010382]
  2. 24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: ==>  Preparing: SELECT * FROM user_info WHERE username=?
  3. 24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: ==> Parameters: wzk(String)
  4. 24/11/11 15:59:59 DEBUG UserInfoMapper.selectList: <==      Total: 1
  5. UserInfo(id=1, username=wzk, password=icu, age=18)
复制代码
对应的截图如下所示:

循环拼接

我们在 UserMapper 中添加一个新的方法:
  1. List<UserInfo> selectListByIdList(@Param("idList") List<Integer> idList);
复制代码
对应的截图如下所示:

我们编写对应的 Mapper :
  1. <select id="selectListByIdList" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">
  2.     SELECT
  3.         *
  4.     FROM
  5.         user_info
  6.     <where>
  7.         id IN
  8.         <foreach collection="idList" open="(" close=")" separator="," index="index" item="item">
  9.             #{item}
  10.         </foreach>
  11.     </where>
  12. </select>
复制代码
对应的结果截图如下所示:

我们编写 Java 代码举行测试:
  1. public class WzkIcu06 {
  2.     public static void main(String[] args) throws IOException {
  3.         InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
  4.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
  5.                 .build(resourceAsStream);
  6.         SqlSession sqlSession = sqlSessionFactory.openSession();
  7.         UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
  8.         List<Integer> idList = Arrays.asList(1, 2, 3);
  9.         List<UserInfo> dataList = userInfoMapper.selectListByIdList(idList);
  10.         dataList.forEach(System.out::println);
  11.         sqlSession.close();
  12.     }
  13. }
复制代码
目前数据库的数据如下(手动写了几条):

我们运行代码,控制台中输出的日志如下所示:
  1. 24/11/11 16:15:16 DEBUG jdbc.JdbcTransaction: Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6d2a209c]
  2. 24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: ==>  Preparing: SELECT * FROM user_info WHERE id IN ( ? , ? , ? )
  3. 24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: ==> Parameters: 1(Integer), 2(Integer), 3(Integer)
  4. 24/11/11 16:15:16 DEBUG UserInfoMapper.selectListByIdList: <==      Total: 3
  5. UserInfo(id=1, username=wzk, password=icu, age=18)
复制代码
对应的截图如下所示:

foreach 标签属性如下:

片断抽取

SQL 中重复的 SQL 提取出来,使用 include 引用即可,终极达到 SQL 重复使用的目的。
我们在 UserInfoMapper 的接口中添加一个方法:
  1. UserInfo selectOneBySegment(UserInfo userInfo);
复制代码
对应的截图如下所示:

编写对应的 XML:
  1. <sql id="SELECT_USER_INFO">
  2.     SELECT * FROM user_info
  3. </sql>
  4. <select id="selectOneBySegment" parameterType="icu.wzk.model.UserInfo" resultType="icu.wzk.model.UserInfo">
  5.     <include refid="SELECT_USER_INFO"></include>
  6.     <where>
  7.         id=#{id}
  8.     </where>
  9. </select>
复制代码
对应的截图如下所示:

  1. public class WzkIcu07 {
  2.     public static void main(String[] args) throws IOException {
  3.         InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
  4.         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
  5.                 .build(resourceAsStream);
  6.         SqlSession sqlSession = sqlSessionFactory.openSession();
  7.         UserInfoMapper userInfoMapper = sqlSession.getMapper(UserInfoMapper.class);
  8.         UserInfo userInfo = UserInfo
  9.                 .builder()
  10.                 .id(1L)
  11.                 .build();
  12.         userInfo = userInfoMapper.selectOneBySegment(userInfo);
  13.         System.out.println(userInfo);
  14.         sqlSession.close();
  15.     }
  16. }
复制代码
实行之后,控制台输出结果如下:
  1. 24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: ==>  Preparing: SELECT * FROM user_info WHERE id=?
  2. 24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: ==> Parameters: 1(Long)
  3. 24/11/11 17:04:08 DEBUG UserInfoMapper.selectOneBySegment: <==      Total: 1
  4. UserInfo(id=1, username=wzk, password=icu, age=18)
复制代码
对应的截图如下:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4