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);
    }
 
}运行结果

当没有写条件时,原来的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的拼接操作,例如::select *from user where id in(1,2,3)
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);
 
    }
}运行结果

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

<!--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><select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取
资料摘自:https://blog.csdn.net/weixin_60719453/article/details/126450239