Mybatis映射文件中动态sql语句

2022-08-23

Mybatis映射文件深入
动态sql语句

概述:Mybatais的映射文件中,前面我们的SQL都是比较简单的,有时候业务逻辑复杂时,我们的sql时动态变化的,此时在其那面学习的sql就不能满足要求了

官方文档中动态sql

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

    if
    choose (when, otherwise)
    trim (where, set)
    foreach

动态SQL之if
测试示例if

    UserMapper接口下

package com_Mybatis_sql.mapper;
 
import com_Mybatis_sql.pojo.User;
 
import java.util.List;
 
public interface UserMapper {
    public List<User> findByCondition(User user);
}


 UserMapper2.xml文件下

<?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_Mybatis_sql.mapper.UserMapper">
 
<select id="findByCondition" parameterType="user" resultType="user">
 
 select *from user
-- 用where标签保住等价于where 1=1,有条件就进入
 <where>
 <if test="id!=0">
     and id=#{id}
 </if>
 
 <if test="username!=null">
     and username=#{username}
 </if>
 <if test="password!=null">
     and password=#{password}
 </if>
 </where>
</select>
 
 
 
</mapper>


test测试下

 
 
public class MapperTest {
    @Test
    public void test1() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
 
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
 
        //模拟条件user
     User user=new User();
        user.setId(1);
        user.setUsername("zhangsan");
       user.setPassword("123");
        List<User> userList = mapper.findByCondition(user);
        System.out.println(userList);
    }
 
}




运行结果


55f0951aa2054982a136955142eb294a.png


当没有写条件时,原来的sql语句就等价于select *from user

<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>



这样的动态查询无论是有没有条件或者是有多个条件都能查询到


动态sql之foreach

循环执行sql的拼接操作,例如::select *from user where id in(1,2,3)

测试示例foreach

UserMapper接口下

public interface UserMapper {
 
    public List<User> findByIds(List<Integer> ids);
}



配置文件UserMapper2.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>



MapperTest测试类下

public class MapperTest {
 
 
    @Test
    public void test2() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
 
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
 
     //模拟ids的数据
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        List<User> byIds = mapper.findByIds(ids);
        System.out.println(byIds);
 
    }
}



运行结果


0a005c85104845c89b0e79c519b6589c.png



sql片段的抽取

sql中可将重复的sql提取出来,使用include引用即可,最终达到sql重用的目的



a230792666ed49ddae0bba8d03e6c4aa.png

<!--sql语句抽取-->
    <sql id="selectUser"> select *from user</sql>
 
<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>



Mybatis映射文件深入知识小结

<select>:查询

<insert>:插入

<update>:修改

<delete>:删除

<where>:where条件

<if>:if判断

<foreach>:循环

<sql>:sql片段抽取


资料摘自:https://blog.csdn.net/weixin_60719453/article/details/126450239



联系信息

QQ:1827566828
Email: 1827566828@qq.com
Web: https://www.yynet.wang

留言