Mybatis 动态SQL条件查询(注释和XML方式都有)

复制代码

需求 : 根据用户的输入情况进行条件查询

新建了一个 userInfo2Mapper 接口,然后写下如下代码,声明 selectByCondition 这个方法

java 复制代码
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.model.UserInfo;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface UserInfo2Mapper {
   
    List<UserInfo> selectByCondition(UserInfo userInfo);
}

我们先用XML的方式实现

在resources 中创建 Userinfo2XMLMapper.xml 文件

将 Userinfo2XMLMapper.xml 文件中的 namespace 进行修改,改为 userInfo2Mapper 接口中的第一行 package 的内容再加上接口名

然后补充如下代码,用户输入什么条件,什么条件就不为空,就可以根据该条件进行查询

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.example.mybatisdemo.mapper.UserInfo2Mapper">
    <select id="selectByCondition" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo
        where
        <if test="username!=null">
            username = #{username}
        </if>
        <if test="age!=null">
            and age = #{age}
        </if>
        <if test="gender!=null">
            and gender = #{gender}
        </if>
    </select>
</mapper>

再回到接口,然后Generate,test,勾选selectByCondition,ok

然后补充代码

java 复制代码
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;

@Slf4j
@SpringBootTest
class UserInfo2MapperTest {
    @Autowired
    private UserInfo2Mapper userInfo2Mapper;
  
    @Test
    void selectByCondition() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("io");
        userInfo.setAge(23);
        userInfo.setGender(0);
        List<UserInfo> userInfos = userInfo2Mapper.selectByCondition(userInfo);
        log.info(userInfos.toString());
    }
}

然后我的数据库里面是有这些数据的

接下来我们执行看看结果 ,没毛病

接下来我们对代码稍作修改,我们不 set gender了,再看看运行结果

java 复制代码
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;

@Slf4j
@SpringBootTest
class UserInfo2MapperTest {
    @Autowired
    private UserInfo2Mapper userInfo2Mapper;
  
    @Test
    void selectByCondition() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("io");
        userInfo.setAge(23);
        //userInfo.setGender(0);
        List<UserInfo> userInfos = userInfo2Mapper.selectByCondition(userInfo);
        log.info(userInfos.toString());
    }
}

也是可以正常运行的,比限制 gender 多了一条数据

但是当我们把setUsername也给去掉,只查询年龄为23的人,发现报错了

我们看日志会发现,多了一个and

这时候我们就要用 trim 标签来消除这个多余的and (上节博客也有trim的讲解)

然后我们回到 Userinfo2XMLMapper.xml 对代码进行修改,加上 trim 标签

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.example.mybatisdemo.mapper.UserInfo2Mapper">
    <select id="selectByCondition" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo
        where
        <trim prefixOverrides="and">
            <if test="username!=null">
                username = #{username}
            </if>
            <if test="age!=null">
                and age = #{age}
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
        </trim>
    </select>
</mapper>

这时再次运行程序就能成功啦

另一种方法就是 where 标签

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.example.mybatisdemo.mapper.UserInfo2Mapper">
    <select id="selectByCondition" resultType="com.example.mybatisdemo.model.UserInfo">
        select * from userinfo
        <where>
            <if test="username!=null">
                username = #{username}
            </if>
            <if test="age!=null">
                and age = #{age}
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
        </where>
    </select>
</mapper>

这也是可以成功运行的

用 where 还是 用 trim 都可以,这两个没啥差别

但是 trim 标签有个问题就是,如果所有where条件都为null的时候,会报错,因为where后面没东西了

where 标签就不会有上面的问题 ,如果查询条件均为空,直接删除 where 关键字

如果一定要用 trim 标签也有一种解决方式

接下来我们看看如何用注释的方式实现

复制代码
在 UserInfo2Mapper 接口中写入下面的代码,跟XML代码差不多
java 复制代码
package com.example.mybatisdemo.mapper;
import com.example.mybatisdemo.model.UserInfo;
import org.apache.ibatis.annotations.*;
import java.util.List;

@Mapper
public interface UserInfo2Mapper {
   
    @Select("<script>" +
            "select * from userinfo" +
            "        <where>" +
            "            <if test='username!=null'>" +
            "                username = #{username}" +
            "            </if>" +
            "            <if test='age!=null'>" +
            "                and age = #{age}" +
            "            </if>" +
            "            <if test='gender!=null'>" +
            "                and gender = #{gender}" +
            "            </if>" +
            "        </where>"+
            "</script>")
    List<UserInfo> selectByCondition2(UserInfo userInfo);
}

然后就,右键,Generate,test,勾选 selectByCondition2,ok,然后补充下面代码,也跟XML一样

java 复制代码
package com.example.mybatisdemo.mapper;

import com.example.mybatisdemo.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@Slf4j
@SpringBootTest
class UserInfo2MapperTest {
    @Autowired
    private UserInfo2Mapper userInfo2Mapper;

    @Test
    void selectByCondition2() {
        UserInfo userInfo = new UserInfo();
        //userInfo.setUsername("io");
        userInfo.setAge(23);
        //userInfo.setGender(0);
        List<UserInfo> userInfos = userInfo2Mapper.selectByCondition(userInfo);
        log.info(userInfos.toString());
    }
}

运行试试,没毛病

相关推荐
modest —YBW1 小时前
Ollama+OpenWebUI+docker完整版部署,附带软件下载链接,配置+中文汉化+docker源,适合内网部署,可以局域网使用
人工智能·windows·docker·语言模型·llama
code在飞1 小时前
windows 部署 Kafka3.x KRaft 模式 不依赖 ZooKeeper
windows·分布式·zookeeper·kafka
佛祖让我来巡山2 小时前
【Java持久层技术演进全解析】从JDBC到MyBatis再到MyBatis-Plus
mybatis·jdbc·mybatisplus·持久层框架
luo_guibin2 小时前
DVWA在线靶场-SQL注入部分
数据库·sql·mysql
不会飞的鲨鱼3 小时前
Windows系统下使用Kafka和Zookeeper,Python运行kafka(二)
windows·zookeeper·kafka
2501_911121235 小时前
【无标题】
数据库·sql·mysql
冼紫菜9 小时前
【Spring Boot 多模块项目】@MapperScan失效、MapperScannerConfigurer 报错终极解决方案
java·开发语言·mybatis
2501_9153738812 小时前
Electron 打包与发布指南:让你的应用运行在 Windows、macOS、Linux
windows·macos·electron
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧13 小时前
MyBatis快速入门——实操
java·spring boot·spring·intellij-idea·mybatis·intellij idea
烧瓶里的西瓜皮14 小时前
Go语言从零构建SQL数据库(9)-数据库优化器的双剑客
数据库·sql·golang