mybatis update动态sql(<set>和<if>)

提出问题

修改密码,在 mapper.xml 中增加一条sql
修改年龄,在 mapper.xml 中 再增加一条sql
按照这个思路,每次实现修改操作,都要增加一条sql,那工作量就太大了,也太笨了

分析

编写一条 动态的SQL,如果需要修改密码,就修改密码;如果需要修改年龄,就修改年龄,那么就只写这一条sql就可以了

解决

修改 mapper.xml

<update id="updateUser" parameterType="org.malaoshi.entity.User">
    update user 
    set
        <if test="password!=null  and password!=''">
            password=#{password} ,
        </if>
        <if test="age!=null ">
            age=#{age} 
        </if>
    where 
    id=#{id}

    </update>

修改 IUserMapper

增加下面代码:

public int updateById(User user);

测试 修改密码

@Test
public void test() throws IOException {

    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);

    User user=new User();
    user.setId("1000");
    user.setPassword("123");

    int num=mapper.updateById(user);
    System.out.println("更新 "+num+" 条记录");
    sqlSession.commit();

    sqlSession.close();
    inputStream.close();
}

测试 修改年龄

@Test
public void test() throws IOException {

    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);

    User user=new User();
    user.setId("1000");
    user.setAge(25);

    int num=mapper.updateById(user);
    System.out.println("更新 "+num+" 条记录");
    sqlSession.commit();

    sqlSession.close();
    inputStream.close();
}

提出问题

问题1

观察下面的代码,使用了 <if> 标签,动态生成 update 语句

<update id="updateUser" parameterType="org.malaoshi.entity.User">
    update user 
    set
        <if test="password!=null  and password!=''">
            password=#{password} ,
        </if>
        <if test="age!=null ">
            age=#{age} 
        </if>
    where 
    id=#{id}

    </update>

如果 password!=null and password!='' 为 true,age!=null 为 false,生成的 sql 为:

update user 
    set
    password=#{password} ,
    where 
    id=#{id}

会多出一个 ,

问题2

如果讲上面的代码改成下面,都没有 ,:

<update id="updateUser" parameterType="org.malaoshi.entity.User">
    update user 
    set
        <if test="password!=null  and password!=''">
            password=#{password} 
        </if>
        <if test="age!=null ">
            age=#{age} 
        </if>
    where 
    id=#{id}

    </update>

如果 password!=null and password!='' 为 true,age!=null 为 true,

生成的 sql 为:

update user 
    set
    password=#{password} 
    age=#{age} 
    where 
    id=#{id}

会少一个 ,

解决

<set> 标签,用于动态生成 update 语句,会 自动删除 后面多出的,

修改 IUserMapper

增加下面代码:

public int updateById(User user);

修改 userMapper.xml

增加下面代码:

<update id="updateById" parameterType="org.malaoshi.entity.User">
    update user
    <set>
        <if test="username!=null">
            username=#{username} ,
        </if>

        <if test="password!=null">
            password=#{password} ,
        </if>
    </set>
    where
    id=#{id}

</update>

测试

@Test
public void test() throws IOException {

    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);

    User user=new User();
    user.setId("1000");
    user.setPassword("123");

    int num=mapper.updateById(user);
    System.out.println("更新 "+num+" 条记录");
    sqlSession.commit();

    sqlSession.close();
    inputStream.close();
}

原文出处:/show_1IXwLOmOIO.html