暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

谈谈 MyBatis 中用 if 标签实现动态SQL语句,查询、删除、更新都可以用哦!

时代Java 2020-07-31
1271
点击上面 时代Java关注我们,
关注新技术,学习新知识!

MyBatis if 标签

if 标签是我们最常使用的。在查询、删除、更新的时候很可能会使用到。必须结合 test 属性联合使用。


1 在 WHERE 条件中使用 if 标签

这是常见的一种现象, 我们在进行按条件查询的时候, 可能会有多种情况。

1.1 查询条件

根据输入的学生信息进行条件检索

  1. 当只输入用户名时, 使用用户名进行模糊检索;

  2. 当只输入性别时, 使用性别进行完全匹配

  3. 当用户名和性别都存在时, 用这两个条件进行查询匹配查询

1.2 动态 SQL

接口函数

复制
        /**
    * 根据输入的学生信息进行条件检索
    * 1. 当只输入用户名时, 使用用户名进行模糊检索;
    * 2. 当只输入邮箱时, 使用性别进行完全匹配
    * 3. 当用户名和性别都存在时, 用这两个条件进行查询匹配的用
    * @param student
    * @return
    */
    List<Student> selectByStudentSelective(Student student);
    对应的动态 SQL <select id="selectByStudentSelective" resultMap="BaseResultMap" parameterType="com.homejim.mybatis.entity.Student">
    select
    <include refid="Base_Column_List" >
    from student
    where 1=1
    <if test="name != null and name !=''">
    and name like concat('%', #{name}, '%')
    </if>
    <if test="sex != null">
    and sex=#{sex}
    </if>
    </select>
    复制
    在此 SQL 语句中, where 1=1 是多条件拼接时的小技巧, 后面的条件查询就可以都用 and 了。
    复制

    同时, 我们添加了 if 标签来处理动态 SQL

          <if test="name != null and name !=''">
      and name like concat('%', #{name}, '%')
      </if>
      <if test="sex != null">
      and sex=#{sex}
      </if>
      复制

      此 if 标签的 test 属性值是一个符合 OGNL 的表达式, 表达式可以是 true 或 false。如果表达式返回的是数值, 则0为 false, 非 0 为 true;

      1.3 测试

              @Test
        public void selectByStudent() {
        SqlSession sqlSession = null;
        sqlSession = sqlSessionFactory.openSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);


        Student search = new Student();
        search.setName("明");


        System.out.println("只有名字时的查询");
        List<Student> studentsByName = studentMapper.selectByStudentSelective(search);
        for (int i = 0; i < studentsByName.size(); i++) {
        System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE));
        }


        search.setName(null);
        search.setSex((byte) 1);
        System.out.println("只有性别时的查询");
        List<Student> studentsBySex = studentMapper.selectByStudentSelective(search);
        for (int i = 0; i < studentsBySex.size(); i++) {
        System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE));
        }


        System.out.println("姓名和性别同时存在的查询");
        search.setName("明");
        List<Student> studentsByNameAndSex = studentMapper.selectByStudentSelective(search);
        for (int i = 0; i < studentsByNameAndSex.size(); i++) {
        System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE));
        }


        sqlSession.commit();
        sqlSession.close();
        }
        复制
        只有名字时的查询, 发送的语句和结果
        复制

        查询的条件只发送了

          where 1=1 and name like concat('%', ?, '%')
          复制
          只有性别时的查询, 发送的语句和结果
          复制

          查询的条件只发送了

           where 1=1 and sex=?
          复制

          姓名和性别同时存在的查询, 发送的语句和结果

          查询条件

            where 1=1 and name like concat('%', ?, '%') and sex=?
            复制


            2 在 UPDATE 更新列中使用 if 标签

            有时候我们不希望更新所有的字段, 只更新有变化的字段。

            2.1 更新条件

            只更新有变化的字段, 空值不更新。

            2.1 动态 SQL

            接口方法

            复制
                  **
              * 更新非空属性
              */
              int updateByPrimaryKeySelective(Student record);
              对应的 SQL <update id="updateByPrimaryKeySelective" parameterType="com.homejim.mybatis.entity.Student">
              update student
              <set>
              <if test="name != null">
              `name` = #{name,jdbcType=VARCHAR},
              </if>
              <if test="phone != null">
              phone = #{phone,jdbcType=VARCHAR},
              </if>
              <if test="email != null">
              email = #{email,jdbcType=VARCHAR},
              </if>
              <if test="sex != null">
              sex = #{sex,jdbcType=TINYINT},
              </if>
              <if test="locked != null">
              locked = #{locked,jdbcType=TINYINT},
              </if>
              <if test="gmtCreated != null">
              gmt_created = #{gmtCreated,jdbcType=TIMESTAMP},
              </if>
              <if test="gmtModified != null">
              gmt_modified = #{gmtModified,jdbcType=TIMESTAMP},
              </if>
              </set>
              where student_id = #{studentId,jdbcType=INTEGER}
              复制
              复制

              2.3 测试

                    @Test
                public void updateByStudentSelective() {
                SqlSession sqlSession = null;
                sqlSession = sqlSessionFactory.openSession();
                StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);


                Student student = new Student();
                student.setStudentId(1);
                        student.setName("时代Java");
                student.setPhone("13000000000");
                System.out.println(studentMapper.updateByPrimaryKeySelective(student));


                sqlSession.commit();
                sqlSession.close();
                }
                复制
                结果如下
                复制


                3 在 INSERT 动态插入中使用 if 标签

                我们插入数据库中的一条记录, 不是每一个字段都有值的, 而是动态变化的。在这时候使用 if 标签, 可帮我们解决这个问题。

                3.1 插入条件

                只有非空属性才插入。

                3.2 动态SQL

                接口方法

                复制
                      **
                  * 非空字段才进行插入
                  */
                  int insertSelective(Student record);
                  对应的SQL<insert id="insertSelective" parameterType="com.homejim.mybatis.entity.Student">
                  insert into student
                  <trim prefix="(" suffix=")" suffixOverrides=",">
                  <if test="studentId != null">
                  student_id,
                  </if>
                  <if test="name != null">
                  `name`,
                  </if>
                  <if test="phone != null">
                  phone,
                  </if>
                  <if test="email != null">
                  email,
                  </if>
                  <if test="sex != null">
                  sex,
                  </if>
                  <if test="locked != null">
                  locked,
                  </if>
                  <if test="gmtCreated != null">
                  gmt_created,
                  </if>
                  <if test="gmtModified != null">
                  gmt_modified,
                  </if>
                  </trim>
                  <trim prefix="values (" suffix=")" suffixOverrides=",">
                  <if test="studentId != null">
                  #{studentId,jdbcType=INTEGER},
                  </if>
                  <if test="name != null">
                  #{name,jdbcType=VARCHAR},
                  </if>
                  <if test="phone != null">
                  #{phone,jdbcType=VARCHAR},
                  </if>
                  <if test="email != null">
                  #{email,jdbcType=VARCHAR},
                  </if>
                  <if test="sex != null">
                  #{sex,jdbcType=TINYINT},
                  </if>
                  <if test="locked != null">
                  #{locked,jdbcType=TINYINT},
                  </if>
                  <if test="gmtCreated != null">
                  #{gmtCreated,jdbcType=TIMESTAMP},
                  </if>
                  <if test="gmtModified != null">
                  #{gmtModified,jdbcType=TIMESTAMP},
                  </if>
                  </trim>
                  </insert>
                  复制
                  这个 SQL 大家应该很熟悉,毕竟是自动生成的。
                  复制

                  3.3 测试

                       @Test
                    public void insertByStudentSelective() {
                    SqlSession sqlSession = null;
                    sqlSession = sqlSessionFactory.openSession();
                    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);


                    Student student = new Student();
                            student.setName("nowjava");
                    student.setPhone("13000000000");
                    student.setEmail("test@test.com");
                    student.setLocked((byte) 0);


                    System.out.println(studentMapper.insertSelective(student));


                    sqlSession.commit();
                    sqlSession.close();
                    }
                    复制
                    SQL 中, 只有非空的字段才进行了插入。
                    复制

                    --

                    知识分享,时代前行!

                    ~~ 时代Java

                    还有更多好文章……

                    请查看历史文章和官网,

                    ↓有分享,有收获~

                    文章转载自时代Java,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                    评论