动态sql之if

文章介绍了在MyBatis中,当业务逻辑复杂,静态SQL无法满足需求时,如何使用动态SQL。重点讲解了if和foreach标签,特别是if标签在处理条件查询时的作用。通过示例展示了如何修改映射文件,使得当对象属性为空时不参与查询条件,避免了无效的过滤条件导致的查询错误。
摘要由CSDN通过智能技术生成

动态sql之if(映射文件深入)

动态SQL语句概述:

MyBatis的映射文件中, 前面我们的SQL都是比较简单的, 但是以后有一些时候业务逻辑比较复杂的时候,我们的SQL是动态变化的, 此时在前面的学习中我们的静态SQL就不能满足了

关于动态SQL, 我们要学习四个标签:

  1. if
  2. choose(when, otherwise)
  3. trim(where, set)
  4. foreach
  • if和foreach标签比较重要, if标签最重要的, 我们以后使用if标签使用的也是最多的

动态sql实际问题引入:

映射文件中:

<mapper namespace="com.ffyc.mapper.UserMapper">
    <select id="findByCondition" parameterType="user" resultType="user">
        select * from user where id=#{id} and username=#{username} and password=#{password}
    </select>
</mapper>

创建Mapper接口:

public interface UserMapper{
    public List<User> findByCondition(User user);
}

编写逻辑层代码:

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 condition = new User();
    condition.setId(1);
    condition.setUsername("zhangsan");
    condition.setPassword("123");
    
    List<User> userList = mapper.findByCondition(condition);
    
    System.out.println(userList);
}
  • 注意: 我们的数据库中是有对应的id属性值为1, username属性值为zhangsan, password属性为123的人的
  1. 所以我们的测试结果应该是将这个id属性值为1, username为zhangsan, password属性值为123的人查询出来

  2. 但是如果我们将condition.setPassword(“123”)注释掉,这个时候我们再查询的时候就会发现是查询不出结果的, 这个时候是因为我们前面映射文件中写的是: select * from user where id=#{id} and username=#{username} and password=#{password}, 但是这个时候我们没有给password属性赋值, 这个时候对应的执行的语句就会是: select * from user where id=1 and username=zhangsan and password=null

    • 因为我们的password是我们的User类中的成员变量, 如果我们没有给这个成员变量赋值的时候就默认值为: null, 所以此时我们查询的时候就是查询表中id值为1, username值为zhangsan, password属性值为null的, 满足这个条件的我们的数据库中是没有的, 所以最终就会返回一个null, 然后我们最终打印的userList的结果就会是一个null

      • 这个时候我们的需求是: 当我们如果给某个字段没有填充值的时候这个字段就不参与where条件后面的判断:
        • eg: 比如此时我们没有给User对象的password属性赋值, 此时那么我们就应该只使用id和username属性来判断数据库中是否有满足条件的记录, 也就是执行的查询语句为: select * from user where id=1 and username=zhangsan
      • 那么我们要如何才能做到我们的需求?

        • 这个时候我们要将映射文件改为如下:
        <mapper namespace="com.ffyc.mapper.UserMapper">
            <select id="findByCondition" parameterType="user" resultType="user">
            	select * from user where 1 = 1
                <if test = "id != 0">
                    and id = #{id}
                </if>
                <if test = "username != null">
                    and username = #{username}
                </if>
                <if test = "password != null">
                    and password = #{password}
                </if>
            </select>
        </mapper>
        
        • 我们此时的if标签的功能就是只有当test中的条件满足的时候, 就会将if标签中的标签体内容进行执行, 如果不满足条件的时候, 对应的if中的标签体内容数据就不会执行了

          • 我们可以发现我们在if标签中的test属性中是不需要通过#{}的方式来取值的, 我们在if标签中的test中只需要直接写实体类的属性名即可

            • 问题遗留:

              • 那么此时的id到底是实体类中的id属性还是数据库中的id字段?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值