20201119黄春跃

20201119黄春跃

知识点

Mybatis 的动态 SQL 语句

Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。
参考的官方文档,描述如下:

动态 SQL 之if标签

我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

持久层 Dao 接口
List<UserInfoModel> findByUser(UserInfoModel user);
持久层 Dao 映射配置
<select id="findByUser" resultMap="userMap" parameterType="com.itlaobing.mybatis.model.UserInfoModel">
        select * from userinfo where 1=1
        <if test="username != null and username !=''">
            and username like #{username}
        </if>
        <if test="name != null ">
            and name like #{name}
        </if>
    </select>

注意:标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。另外要注意 where 1=1 的作用,不写1=1 sql语句相当于select * from userinfo where and username like %a%,就会报错。

满足哪个if里面的条件就会拼接里面对应的sql语句。

@Test
    public void testFindByUser() {
        UserInfoModel u = new UserInfoModel();
        u.setUsername("%a%");
//        u.setName("张");
        List<UserInfoModel> users = userDao.findByUser(u);
            for(UserInfoModel user : users) {
                System.out.println(user);
            }
    }

动态 SQL 之where标签

为了方便,方法名与前面一样,就改一下持久层 Dao 映射配置

持久层 Dao 映射配置

动态标签之foreach标签

需求

传入多个 id 删除用户信息,用下边 sql 实现:

delete from userinfo where id in (id1,id2,id3); 

这样我们在进行删除时,就要将一个集合或数组中的值,作为参数动态添加进来。
这样我们将如何进行参数的传递?

持久层 Dao 接口

int deleteByIds(String... ids); 

参数可以是可变长度参数,数组,集合

持久层 Dao 映射配置

<delete id="deleteByIds" parameterType="List">
        delete from test
        <where>
            <foreach collection="array" item="id" open="id in (" close=")" separator=",">
                #{id}
            </foreach>
        </where>
    </delete>

parameterType 为 list,java.util.List,java.util.ArrayList均可以,切记不可以为Array/array.
foreach 标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果使用Map或对象封装了,collection的属性值为对应的Key
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符

编写测试方法

@Test
    public void testDeleteByIds(){
        int rows = userDao.deleteByIds("5","6","7","8","9");
        System.out.println(rows);
        session.commit();
        session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

动态标签之trim 标签

trim标签一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以
及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作。

trim标签的属性:

持久层 Dao 接口
int saveTest(Model2 user);
持久层 Dao 映射配置
<insert id="saveTest" parameterType="com.itlaobing.mybatis.model.Model2">
        insert into test
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                name,
            </if>
            <if test="id !=null">
                id,
            </if>
        </trim>
        <trim prefix="values(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                #{name},
            </if>
            <if test="id !=null">
                #{id},
            </if>
        </trim>
    </insert>
编写测试方法
@Test
    public  void testSaveTest(){
        Model2 user = new Model2();

        user.setName("黄大");

        int row = userDao.saveTest(user);
        System.out.println("影响行数:" + row);
        session.commit();
        System.out.println(user);//在事务提交后在查看,不然id就是null
        //7.释放资源
        session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

由于id是自增长的,就没有写id

动态标签之set标签

set 标签主要是用在更新操作( update )的时候,它的主要功能和 where 标签元素其实是差不多的,主
要是在包含的语句前输出一个 SET ,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果
包含的内容为空的话则会出错。有了 set 元素就可以动态的更新那些修改了的字段。一般情况
下 set 标签结合 if 一起使用

持久层 Dao 接口
int updateTest(Model2 user);
持久层 Dao 映射配置
<update id="updateTest" parameterType="com.itlaobing.mybatis.model.Model2">
        update test
        <set>
            <if test="name != null">
                name = #{name},
            </if>
        </set>
        where id = #{id}
    </update>
编写测试方法
@Test
    public void testUpdateTest() {
        Model2 user = new Model2();
        user.setName("阿花");
        user.setId(14);
        int rows = userDao.updateTest(user);
        System.out.println(rows);
        session.commit();
        //7.释放资源
        session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

动态标签值choos标签

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用 if 标签时,只要 test 中
的表达式为 true ,就会执行 if 标签中的条件。MyBatis 提供了 choose 元素。 if 标签是与( and )的
关系,而 choose 是或( or )的关系。
choose标签是按顺序判断其内部 when 标签中的 test 条件出否成立,如果有一个成立,则 choose 结
束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的 sql 。类似于 Java 的 if
语句, when 为 if()/else if() , otherwise 则为 else ,只要其中一个成立整个 if 就结束。

总结

敲了敲白天的代码,速度有点慢,只看到单表查询。

标签

评论

© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1