美文网首页
Maven项目集成Mybatis 动态SQL

Maven项目集成Mybatis 动态SQL

作者: 乘风破浪的姐姐 | 来源:发表于2021-12-21 13:45 被阅读0次

本文主要介绍 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成灵活的SQL语句,从而提高 SQL 语句的准确性以及开发人员的开发效率。

以表t_dy_member_info 为例:


image.png
pojo类:
package com.sc.pojo;

import lombok.Data;
import java.util.List;

@Data
public class TdyMemberInfo {
    private Long memberId;
    private String memberNo;
    private String mobile;
    private String openId;
    private String shopId;
    private List<Long> ids;

    public void setIds(List<Long> ids) {
        this.ids = ids;
    }
}

接口:

package com.sc.dao;

import com.sc.pojo.TdyMemberInfo;
import java.util.List;

public interface TdyMemberInfoMapper {
    TdyMemberInfo selectMemberByIf(TdyMemberInfo tdyMemberInfo);
    TdyMemberInfo selectMemberByIfWhere(TdyMemberInfo tdyMemberInfo);
    int updateMemberByIfSet(TdyMemberInfo tdyMemberInfo);
    TdyMemberInfo selectMemberByChoose(TdyMemberInfo tdyMemberInfo);
     List<TdyMemberInfo> selectMemberByForeach1(TdyMemberInfo tdyMemberInfo);
     List<TdyMemberInfo> selectMemberByForeach2(TdyMemberInfo tdyMemberInfo);
 
}

Mapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="com.sc.dao.TdyMemberInfoMapper">
    <resultMap id="memberInfo" type="TdyMemberInfo">
        <result property="memberId"   column="member_id"/>
        <result property="memberNo" column="member_no"/>
        <result property="mobile" column="mobile"/>
        <result property="openId" column="open_id"/>
        <result property="shopId" column="shop_id"/>
    </resultMap>
</mapper>
1、动态SQL--- if 语句

1)TdyMemberInfoMapper 接口中定义方法:

 TdyMemberInfo selectMemberByIf(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

   <!--动态IF语句-->
    <select id="selectMemberByIf" resultType="TdyMemberInfo" parameterType="TdyMemberInfo" resultMap="memberInfo">
        select * from t_dy_member_info where
           <if test="memberNo !=null"><!--这里memberNo使用的是pojo中的属性-->
               member_no=#{memberNo}
           </if>
            <if test="mobile !=null">
                and  mobile = #{mobile}
             </if>
    </select>

对应:

select * from t_dy_member_info where member_no=#{memberNo} and mobile =#{mobile}

注意:
if标签中的test属性值,使用的是pojo中对应的属性
上述SQL中,如果 member_no为空时,则该语句就是:

 select * from t_dy_member_info where and mobile = ?

因为where后面多了and所以就会报错。
3)测试类

 @Test
    public void selectMemberByIf(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
        tdyMemberInfo.setMemberNo("202111231463");
        tdyMemberInfo.setMobile("18727460511");
        TdyMemberInfo  member = mapper.selectMemberByIf(tdyMemberInfo);
        System.out.println(member);
        sqlSession.close();
    }
2、动态SQL--- if+where 语句

1)TdyMemberInfoMapper 接口中定义方法:

 TdyMemberInfo selectMemberByIfWhere(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

  <!--动态IF+where 语句-->
    <select id="selectMemberByIfWhere" resultMap="memberInfo" resultType="TdyMemberInfo" parameterType="TdyMemberInfo">
        select * from t_dy_member_info
        <where>
              <if test="memberNo !=null">
               member_no=#{memberNo}
           </if>
            <if test="mobile !=null">
                and  mobile = #{mobile}
             </if>
        </where>
    </select>

上述SQL中,如果 member_no为空时,该语句正常, where 标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
3)测试类

@Test
    public void selectMemberByIfWhere(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
        tdyMemberInfo.setMemberNo("202111231466");
        tdyMemberInfo.setMobile("18727460505");
        TdyMemberInfo  member = mapper.selectMemberByIfWhere(tdyMemberInfo);
        System.out.println(member);
        sqlSession.close();
    }
3、动态SQL--- if+set 语句

1)TdyMemberInfoMapper 接口中定义方法:

 int updateMemberByIfSet(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

 <!--动态set+if 语句-->
    <update id="updateMemberByIfSet" parameterType="TdyMemberInfo" >
        update t_dy_member_info m
        <set>
            <if test="memberNo != null  and memberNo !='' ">
                m.member_no = #{memberNo},
            </if>
            <if test="mobile !=null and mobile !='' ">
                m.mobile = #{mobile}
            </if>
        </set>
       where m.member_id = #{memberId}
   </update>

如果第一个条件 memberNo 为空,set会自动将memberNo后的逗号去掉
那么 sql 语句为:

update t_dy_member_info u set u.mobile =? where member_id =?

如果第一个条件memberNo 不为空,
那么 sql 语句为:

update t_dy_member_info u set u.memberNo = ? ,u.mobile = ? where member_id =?

3)测试类

 @Test
    public void updateMemberByIfSet(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
//        tdyMemberInfo.setMemberNo("2021112311112");
        tdyMemberInfo.setMobile("18727460505");
        tdyMemberInfo.setMemberId(new Long(5));

        int  code = mapper.updateMemberByIfSet(tdyMemberInfo);
        System.out.println(code);
        System.out.println(tdyMemberInfo);
        sqlSession.close();
    }
4、动态SQL---choose(when,otherwise) 语句

1)TdyMemberInfoMapper 接口中定义方法:

TdyMemberInfo selectMemberByChoose(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

 <!--动态where+ choose+when/otherwise 语句-->
    <select id="selectMemberByChoose" resultType="TdyMemberInfo" parameterType="TdyMemberInfo" resultMap="memberInfo">
        select * from t_dy_member_info m
        <where>
            <choose>
                <when test="memberNo != null  and memberNo !='' ">
                    m.member_no = #{memberNo}
                </when>
                <when test="mobile !=null and mobile !='' ">
                    and   m.mobile = #{mobile}
                </when>
                <otherwise>
                    and   m.member_id = #{memberId}
                </otherwise>
            </choose>
        </where>
    </select>

上述SQL中有三个条件,memberNo,mobile,member_id,只能选择一个作为查询条件 当member_no为空时,mobile/member_id不为空则where会自动去掉 and。
如果 memberNo不为空,那么查询语句为:

select * from t_dy_member_info where  memberNo=?

如果 memberNo为空,那么看mobile 是否为空,如果不为空,那么语句为

select * from t_dy_member_info where  mobile =?;

如果 mobile 为空,那么查询语句为

select * from t_dy_member_info where member_id =?

3)测试类

 @Test
    public void selectMemberByChoose(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
//        tdyMemberInfo.setMemberNo("202111231463039461702434821");
//        tdyMemberInfo.setMobile("18727460505");
        tdyMemberInfo.setMemberId(new Long(5));
        TdyMemberInfo  member = mapper.selectMemberByChoose(tdyMemberInfo);
        System.out.println(member);
        sqlSession.close();
    }
5、动态SQL---SQL 片段

有时候某个 sql 语句用到的特别多,为了增加代码的重用性,简化代码,就可以将这些代码抽取出来,在需要用到的地方直接调用。
比如:上述SQL中经常根据member_no 和mobile来进行联合查询,那么就把这个代码抽取出来,如下:

<sql id="selectSql">
        <if test="memberNo !=null">
            member_no=#{memberNo}
        </if>
        <if test="mobile !=null">
            and  mobile = #{mobile}
        </if>
    </sql>

引用 sql 片段

 <!--动态IF语句-->
    <select id="selectMemberByIf" resultType="TdyMemberInfo" parameterType="TdyMemberInfo" resultMap="memberInfo">
        select * from t_dy_member_info where
        <include refid="selectSql"/>
    </select>

    <!--动态IF+where 语句-->
    <select id="selectMemberByIfWhere" resultMap="memberInfo" resultType="TdyMemberInfo" parameterType="TdyMemberInfo">
        select * from t_dy_member_info
        <where>
            <include refid="selectSql"/>
        </where>
    </select>

注意:在 sql 片段中最好不要包括 where

6、动态SQL---foreach 语句(方式1)

1)TdyMemberInfoMapper 接口中定义方法:

 List<TdyMemberInfo> selectMemberByForeach1(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

    <select id="selectMemberByForeach1" resultType="TdyMemberInfo" parameterType="TdyMemberInfo" resultMap="memberInfo">
        select * from t_dy_member_info m
        <where>
            <foreach collection="ids" item="id" separator="or" open="and (" close=")">
               member_id = #{id}
            </foreach>
        </where>
    </select>

上述foreach语句用来改写

 select * from t_dy_member_info where member_id=47 or member_id=48 or member_id=49

3)测试类

  @Test
    public void selectMemberByForeach1(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
        List<Long> ids = new ArrayList<>();
        ids.add(new Long(47));
        ids.add(new Long(48));
        ids.add(new Long(49));

        tdyMemberInfo.setIds(ids);
        List<TdyMemberInfo>  memberList = mapper.selectMemberByForeach1(tdyMemberInfo);
        for(TdyMemberInfo memberInfo:memberList){
            System.out.println(memberInfo);
        }
        sqlSession.close();
    }
7、动态SQL---foreach 语句(方式2)

1)TdyMemberInfoMapper 接口中定义方法:

 List<TdyMemberInfo> selectMemberByForeach2(TdyMemberInfo tdyMemberInfo);

2)TdyMemberInfoMapper.xml中SQL语句块:

    <select id="selectMemberByForeach2" resultType="TdyMemberInfo" parameterType="TdyMemberInfo" resultMap="memberInfo">
        select * from t_dy_member_info m
        <where>
            <foreach collection="ids" item="id" separator="," open="and member_id in (" close=")">
                #{id}
            </foreach>
        </where>
    </select>

collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串

上述foreach语句用来改写

select * from t_dy_member_info m WHERE member_id in ( ? , ? , ? )  

3)测试类

  @Test
    public void selectMemberByForeach2(){
        SqlSession sqlSession =  MyBatisUtils.getSqlSession();
        TdyMemberInfoMapper mapper = sqlSession.getMapper(TdyMemberInfoMapper.class);
        TdyMemberInfo tdyMemberInfo = new TdyMemberInfo();
        List<Long> ids = new ArrayList<>();
        ids.add(new Long(47));
        ids.add(new Long(48));
        ids.add(new Long(49));

        tdyMemberInfo.setIds(ids);
        List<TdyMemberInfo>  memberList = mapper.selectMemberByForeach2(tdyMemberInfo);
        for(TdyMemberInfo memberInfo:memberList){
            System.out.println(memberInfo);
        }
        sqlSession.close();
    }

相关文章

网友评论

      本文标题:Maven项目集成Mybatis 动态SQL

      本文链接:https://www.haomeiwen.com/subject/okhxqrtx.html