Mybatis中的动态标签

动态sql

  • if标签
  • where标签
  • choose 标签
  • foeach标签
  • bind标签
  • sql片段

mybatis动态sql是通过OGNL表达式进行的动态sql使用,有以下几种

Mybatis中的动态标签_第1张图片

准备数据表:

CREATE TABLE `user_info` (
  `ID` int NOT NULL AUTO_INCREMENT COMMENT 'id',
  `NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
  `AGE` int NOT NULL COMMENT '年龄',
  `BIRTHDAY` date NOT NULL COMMENT '生日',
  `ADDRESS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '住址',
  `CREATETIME` date DEFAULT NULL COMMENT '创建时间',
  `UPDATETIME` date DEFAULT NULL COMMENT '更新时间',
  `GENDER` varchar(2) NOT NULL COMMENT '性别',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb3;

项目结构:
Mybatis中的动态标签_第2张图片

if标签

if 标签是我们最常使用的。在查询、删除、更新的时候很可能会使用到。必须结合 test 属性联合使用,test属性值是一个OGNL表达式,表达式可以使true或false

  • 查询时,在where标签中使用if标签

mapper接口:

    /**
     * 根据条件查询用户信息
     * @date 2021/11/7 10:24
     * @param userInfo
     * @return java.util.List
     */
    List<UserInfo> queryByUserInfo(UserInfo userInfo);

映射文件中对应的动态sql:

    <select id="queryByUserInfo" parameterType="UserInfo" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info where 1=1
        <if test="name != null and name != ''">
            and name=#{name}
        if>
        <if test="gender != null and gender != ''">
            and gender=#{gender}
        if>
    select>

测试:

    @Test
    public void TestQueryByUserInfo(){
        UserInfo userInfo = new UserInfo();
        userInfo.setName("小明");
        // 根据名称查询
        List<UserInfo> userInfos1 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos1){
            System.out.println(user);
        }
        // 根据性别查询
        userInfo.setName(null);
        userInfo.setGender("男");
        List<UserInfo> userInfos2 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos2){
            System.out.println(user);
        }
        // 根据姓名和性别同时查询
        userInfo.setName("小天");
        List<UserInfo> userInfos3 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos3){
            System.out.println(user);
        }
    }

Mybatis中的动态标签_第3张图片

  • 在update更新中使用if标签

mapper接口:

    /**
     * 更新用户非空字段
     * @date 2021/11/7 10:54
     * @param userInfo
     * @return int
     */
    int updateByPrimaryKey(UserInfo userInfo);

映射文件中对应的动态sql:

    <update id="updateByPrimaryKey" parameterType="UserInfo">
        update user_info
        <set>
            <if test="name != null">
                name = #{name},
            if>
            <if test="age != null">
                age = #{age},
            if>
            <if test="gender != null">
                gender = #{gender},
            if>
            <if test="birthday != null">
                birthday = #{birthday},
            if>
            <if test="address != null">
                address = #{address},
            if>
            <if test="createTime != null">
                createTime = #{createTime},
            if>
            <if test="updateTime != null">
                updateTime = #{updateTime}
            if>
        set>
        where id = #{id}
    update>

测试:

    @Test
    public void TestUpdateByPrimaryKey(){
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setGender("女");
        userInfo.setAddress("北京市朝阳区新华街道139号");
        int i = userInfoMapper.updateByPrimaryKey(userInfo);
        System.out.println(i);
    }

Mybatis中的动态标签_第4张图片

  • 在insert动态插入中使用if标签

mapper接口:

    /**
     * 插入用户信息
     * @date 2021/11/7 11:14
     * @param userInfo
     * @return int
     */
    int insertUserInfo(UserInfo userInfo);

映射文件中对应的动态sql:

   <insert id="insertUserInfo" parameterType="UserInfo">
        insert into user_info
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="name != null">
                name,
            if>
            <if test="age != null">
                age,
            if>
            <if test="gender != null">
                gender,
            if>
            <if test="birthday != null">
                birthday,
            if>
            <if test="address != null">
                address,
            if>
            <if test="createTime != null">
                createTime,
            if>
            <if test="updateTime != null">
                updateTime
            if>
        trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="name != null">
                #{name},
            if>
            <if test="age != null">
                #{age},
            if>
            <if test="gender != null">
                #{gender},
            if>
            <if test="birthday != null">
                #{birthday},
            if>
            <if test="address != null">
                #{address},
            if>
            <if test="createTime != null">
                #{createTime},
            if>
            <if test="updateTime != null">
                #{updateTime}
            if>
        trim>
    insert>

测试:

    @Test
    public void TestInsertUserInfo(){
        UserInfo userInfo = new UserInfo();
        userInfo.setName("小狄");
        userInfo.setAge(25);
        userInfo.setGender("男");
        int i = userInfoMapper.insertUserInfo(userInfo);
        System.out.println(i);
    }

在这里插入图片描述

where标签

把上面的代码where1=1修改为下面的代码,当存在用户名时根据用户名查询,存在性别根据性别查询,两个都存在是根据两个条件插叙,两个都不存在时查询全部。

    <select id="queryByUserInfo" parameterType="UserInfo" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        <where>
            <if test="name != null and name != ''">
                and name=#{name}
            if>
            <if test="gender != null and gender != ''">
                and gender=#{gender}
            if>
        where>
    select>

测试:


    @Test
    public void TestQueryByUserInfo(){
        UserInfo userInfo = new UserInfo();
        userInfo.setName("小明");
        // 根据名称查询
        List<UserInfo> userInfos1 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos1){
            System.out.println(user);
        }
        // 根据性别查询
        userInfo.setName(null);
        userInfo.setGender("男");
        List<UserInfo> userInfos2 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos2){
            System.out.println(user);
        }
        // 根据姓名和性别同时查询
        userInfo.setName("小天");
        List<UserInfo> userInfos3 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos3){
            System.out.println(user);
        }
        // 姓名和性别同时不存在时查询全部
        userInfo = null;
        List<UserInfo> userInfos4 = userInfoMapper.queryByUserInfo(userInfo);
        for (UserInfo user : userInfos4){
            System.out.println(user);
        }
    }

Mybatis中的动态标签_第5张图片

choose 标签

choose when otherwise 标签可以帮我们实现 if else 的逻辑。一个 choose 标签至少有一个 when, 最多一个otherwise

mapper接口:

    /**
     * 根据id或者名称查询
     * @date 2021/11/7 11:51
     * @param userInfo
     * @return com.dynamic.entity.UserInfo
     */
    UserInfo queryByIdOrName(UserInfo userInfo);

映射文件中对应的动态sql:

<select id="queryByIdOrName" parameterType="UserInfo" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        <where>
            <choose>
                <when test="id != null">
                    and id = #{id}
                when>
                <otherwise>
                    and name = #{name}
                otherwise>
            choose>
        where>
    select>

id和name都传时会根据wher标签匹配的进行查询

foeach标签

该标签用于遍历集合,它的属性:
  collection:代表要遍历的集合元素,注意编写时不要写#{}
  open:代表语句的开始部分   close:代表结束部分
  item:代表遍历集合的每个元素,生成的变量名   sperator:代表分隔符

mapper接口:

    /**
     * 根据id查询用户信息
     * @date 2021/11/7 17:08
     * @param ids
     * @return com.dynamic.entity.UserInfo
     */
    List<UserInfo> queryById(@Param("ids") List<Integer> ids);

映射配置:

    <select id="queryById" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from user_info
        <where>
            <if test="ids != null and ids.size()>0">
                <foreach collection="ids" open="id in (" close=")" item="id" separator=",">
                    #{id}
                foreach>
            if>
        where>
    select>

测试:

    @Test
    public void TestQueryById() {
        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        List<UserInfo> userInfoList = userInfoMapper.queryById(ids);
        for (UserInfo userInfo : userInfoList)
            System.out.println(userInfo);
    }

在这里插入图片描述

bind标签

bind标签中,value对应传入实体类的某个字段,name属性既给对应字段取的变量名。在value属性中可以使用字符串拼接等特殊处理,模糊查询的时候可以处理入参属性

    <select id="selectUserInfo" resultType="com.zhang.entity.UserInfo">
        <bind name="name" value="'%' + name + '%'"/>
        select * from USER_INFO
        <where>
            <if test="name != null and name != '' ">
                and name like #{name}
            if>
        where>
    select>

sql片段

sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

定义片段:

    
    <sql id="defult">
        select * from user
    sql>

引用sql片段:

    <select id="findByUser" resultMap="userMap" parameterType="user">
        <include refid="defult">include>
        <where>
            <if test="userName != null and userName != ''">
                and username=#{userName}
            if>
            <if test="userSex != null and userSex != ''">
                and sex=#{userSex}
            if>
        where>
    select>

你可能感兴趣的:(【mybatis学习笔记】,mybatis)