Mybatis——Mybatis动态SQL的简介以及使用动态SQL对用户的优化

1. 动态SQL简介

1.1 动态SQL描述

    动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句的繁琐,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。
    利用动态 SQL,可以彻底摆脱这种痛苦。使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

1.2 标签的简介以及项目优化

1.2.1 < sql >标签以及< include >标签

  • < sql >当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。
  • < include > 用于引用定义的常量。

两个结合使用优化了在查询时的语句:

<!--定义sql片段-->
    <sql id="allColumns">
        id,username,birthday,sex,address
    </sql>
    
	 <select id="getAll" resultType="users">
        select  <include refid="allColumns"></include>
        from users
   	 </select>

1.2.2 < where >标签以及< if >标签

  • < if >标签主要是用于条件的判断
  • < where >标签:一般开发复杂业务的查询条件时,如果有多个查询条件,通常会使用标签来进行控制。 标签可以自动的将第一个条件前面的逻辑运算符 (or ,and) 去掉,正如代码中写的,id 查询条件前面是有“and”关键字的,但是在打印出来的 SQL 中却没有,这就是< where > 的作用。
<!--
    //按指定的条件进行多条件查询
    List<Users> getByCondition(Users users);
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    -->
 <select id="getByCondition" parameterType="users" resultType="users">
        select <include refid="allColumns"></include>
        from users
        <where>
            <if test="username != null and username !=''">
                and username like cancat('%',#{username},'%')
            </if>
            <if test="birthday != null">
                and birthday = #{birthday}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
            <if test="address != null and address != ''">
                and address like concat('%',#{address},'%')
            </if>
        </where>
    </select>

1.2.3 < set >标签

  • 使用set标签可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。使用 if+set 标签修改后,在进行表单更新的操作中,哪个字段中有值才去更新,如果某项为 null 则不进行更新,而是保持数据库原值。切记:至少更新一列。主要协助更新操作
<!--
    //有选择的更新
    int updateBySet(Users users);
    -->
    <update id="updateBySet" parameterType="users">
        update users
        <set>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="sex != null and sex != ''">
                sex = #{sex},
            </if>
            <if test="address != null and address != ''">
                address = #{address},
            </if>
        </set>
            where id = #{id}
    </update>

1.2.4 < foreach >标签

标签简介:
    < foreach >主要用来进行集合或数组的遍历,主要有以下参数:
collection:collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合。
    item :循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details,在list和数组中是其中的对象,在map中是value。
    index :在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
    open :表示该语句以什么开始
    close :表示该语句以什么结束
    separator :表示元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。

<!--
    //查多个指定id的信息,匹配查询中的or 或者 in
    List<Users> getByIds(Integer []arr); separator分隔符
    -->
    <select id="getByIds" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where id in
            <foreach collection="array" item="id" separator="," open="(" close=")">
                #{id}
            </foreach>
    </select>

使用foreach标签实现批量增加和删除操作

<!--
    //实现批量删除
    int deleteBatch(Integer []arr);
    -->
    <delete id="deleteBatch">
        delete from users
        where id in
        <foreach collection="array" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

    <!--
    //实现批量增加
    int insertBatch(List<Users> list);
        private String username;
        private Date birthday;
        private String sex;
        private String address;
    -->
    <insert id="insertBatch">
        insert into users (username,birthday,sex,address) values
        <foreach collection="list" item="user" separator=",">
            (#{user.username},#{user.birthday},#{user.sex},#{user.address})
        </foreach>
    </insert>

2. 接口向xml文件中传入参数的优化

2.1 指定参数位置

    可以不使用对象的属性名进行参数值绑定,使用下标值。 mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。

使用方式:
接口中的代码

//查询指定日期范围内的用户
    List<Users> getByBirthday(Date date1,Date date2);

xml文件中的实现

<!--
    //查询指定日期范围内的用户
    List<Users> getByBirthday(Date date1,Date date2);
    -->
    <select id="getByBirthday" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where birthday between #{arg0} and #{arg1}
    </select>

2.2 注解@Param指定参数名称

接口中的实现:

//使用用户名和地址进行模糊查询
    /*使用注解,方便在xml文件中可以使用${}取到数据*/
    List<Users> getUsersByNameOrAddress(
            @Param("columnName") String columnName,
            @Param("columnValue") String columnValue);

xml文件中的实现

<!--使用用户名和地址进行模糊查询
    List<Users> getUsersByNameOrAddress(
            @Param("columnName") String columnName,
            @Param("columnValue") String columnValue);-->
    <select id="getUsersByNameOrAddress"   resultType="users">
        select <include refid="allColumns"></include>
        from users where ${columnName} like concat('%',#{columnValue},'%')
    </select>

2.3 入参使用Map集合传入

接口中代码实现

 //入参数Map【将日期放入Map集合】,查询指定日期内的用户
    List<Users> getByMap(Map map);

xml文件中使用

 <!--
    //入参数Map【将日期放入Map集合】,查询指定日期内的用户
    List<Users> getByMap(Map map);
    -->
    <select id="getByMap" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where birthday between #{birthdayBegin} and #{birthdayEnd}
</select>
此时对测试时创建Map集合中的key就有要求,需要和#{}占位符中的数据名称一样
//入参数Map【将日期放入Map集合】,查询指定日期内的用户
   //List<Users> getByMap(Map map);
    @Test
    public void testGetByMap() throws ParseException {
        Date begin = sdf.parse("2000-01-01");
        Date end = sdf.parse("2000-04-04");
        Map map = new HashMap<>();
        map.put("birthdayBegin",begin);
        map.put("birthdayEnd",end);
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
        List<Users> usersList = usersMapper.getByMap(map);
        usersList.forEach(users -> System.out.println(users));
    }

2.4 返回结果时Map(额外内容)

实现返回一行Map
接口中的实现:

//返回值是Map,返回一行数据
    Map returnMapOne(Integer id);

xml文件中的实现:

 <!--
    //入参数Map【将日期放入Map集合】,查询指定日期内的用户
    List<Users> getByMap(Map map);
    -->
    <select id="getByMap" resultType="users">
        select <include refid="allColumns"></include>
        from users
        where birthday between #{birthdayBegin} and #{birthdayEnd}
</select>

实现返回多行Map

接口中的实现:

//返回多行Map的实现,将Map放入到集合中去
    List<Map> returnMapMul();

xml文件中的实现:

   <!--
    //返回多行Map的实现,将Map放入到集合中去
    List<Map> returnMapMul();
    -->
    <select id="returnMapMul" resultType="map">
        select username ,address
        from users
    </select>

测试返回一行和多行map

 @Test
    public void testReturnMapOne(){
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
        Map map = usersMapper.returnMapOne(7);
        System.out.println(map);
    }

    @Test
    public void testReturnMapMul(){
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
        List<Map> mapList = usersMapper.returnMapMul();
        mapList.forEach(map -> System.out.println(map));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮皮皮皮皮皮皮卡乒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值