Mybatis实现多条件模糊查询

Mybatis实现多条件模糊查询

以往对数据库进行增删改查时,我使用了Spring内置的Spring DataJPA,这是一种简便的操作手段,数据接口通过继承JpaRepository就能直接调用封装好的方法进行CRUD操作。最近,我又学习了一些mybatis知识,下面我们就来看一下如何使用mybatis实现多条件模糊查询。


一、需求

很多时候,我们会有这样的需求:

  1. 一个搜索框,可以使用多个条件进行搜索。比如对博客而言,可以是标题、作者、名称等。
  2. 多个搜索或选项框,依据其中的任意多个进行搜索。
    下面以一个博客类进行说明。

二、步骤

1.编写实体类

这个实体类就四个属性,我们需要的就只是除ID以外的其他几个属性。代码如下:

public class Blog {
    private int id;
    private String title;
    private String name;
    private String author;

    public Blog(int id, String title, String name, String author) {
        this.id = id;
        this.title = title;
        this.name = name;
        this.author = author;
    }

    public Blog() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Blog{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }

2.依据实体类创建数据库表

数据库表字段如下,id为主键,设置为主键自增
在这里插入图片描述

3.编写数据接口BlogDAO

这里我分别测试了一个3种可能情况,代码如下:

public interface BlogDAO {
    //一个参数(如一个搜索框),依据title或作者或名称中的一个进行搜索
    List<Blog> findAllByTitleLikeOrAuthorLikeOrNameLike(@Param("string") String string);

    //多个参数(多个搜索框)任选其中一个、二个或三个条件搜索
    List<Blog> getAllByTitleLikeOrAuthorLikeOrNameLike(@Param("title") String title,
                                                       @Param("author") String author,
                                                       @Param("name") String name);

    //测试mybatis foreach
    List<Blog> findByForeach(Map map);

}

4.编写BlogMapper.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">
<!--namespace绑定一个对应的dao/mapper接口-->
<mapper namespace="com.zpl.dao.BlogDAO">
    <select id="findAllByTitleLikeOrAuthorLikeOrNameLike" resultType="Blog">
        select * from blog
        <where>
            <if test="string != null">
                or title like concat ('%',#{string},'%')
                or author like concat ('%',#{string},'%')
                or name like concat ('%',#{string},'%')
            </if>
        </where>
    </select>

    <select id="getAllByTitleLikeOrAuthorLikeOrNameLike" resultType="Blog">
        select * from blog
        <where>
            <if test="title != null">
                title like concat('%',#{title},'%')
            </if>
            <if test="author != null">
                and author like concat('%',#{author},'%')
            </if>
            <if test="name != null">
                and name like concat('%',#{name},'%')
            </if>
        </where>
    </select>

    <select id="findByForeach" parameterType="map" resultType="Blog">
        select * from blog
        <where>
            <foreach collection="ids" item="id" open="and (" separator="or" close=")">
                id=#{id}
            </foreach>
        </where>
    </select>
</mapper>

针对第一种情况,可以看到,对于标题、作者、名称我都使用统一参数string,使用mybatis 动态SQL中的if元素,当传入的string不为空时,为其附加SQL语句。同时使用like以及通配符%实现模糊查询。由于可以接受三种类型的参数,中间使用or连接。

针对第二种情况,可以看到,对于标题、作者、名称这三个字段,每一个都使用if元素。除了第一个if语句,后续每一个if中SQL语句均使用and连接(由于where的特性,根据需求自动去除连接词and 或 or)。这样就实现了三个条件中仍以一个或者任意二个、或者三个进行搜索。并且均使用了模糊查询。

最后一种情况则用于测试foreach的功能与实现。

5.在总配置文件中映入mapper.xml配置文件

如图所示:
在这里插入图片描述

三、测试

1.编写MybatisUtils配置文件,分别后续测试

public class MybatisUtils {

    public static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

2.使用Junit进行测试

数据库简单数据如图
在这里插入图片描述

  1. 需求一(测试通过标题模糊查找),代码如下:
@Test
    public void test1()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //执行方式1
        BlogDAO blogDAO = sqlSession.getMapper(BlogDAO.class);
        List<Blog> list = blogDAO.findAllByTitleLikeOrAuthorLikeOrNameLike("h");
        for (Blog blog : list)
        {
            System.out.println(blog);
        }

        sqlSession.close();
    }

测试结果如图,可以看到成功查找:
在这里插入图片描述
2. 需求一(测试通过作者模糊查找),代码如下:

@Test
    public void test1()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //执行方式1
        BlogDAO blogDAO = sqlSession.getMapper(BlogDAO.class);
        List<Blog> list = blogDAO.findAllByTitleLikeOrAuthorLikeOrNameLike("信");
        for (Blog blog : list)
        {
            System.out.println(blog);
        }

        sqlSession.close();
    }

测试结果如图,可以看到成功查找:
在这里插入图片描述
3. 需求一(测试通过名称模糊查找),代码如下:

@Test
    public void test1()
    {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //执行方式1
        BlogDAO blogDAO = sqlSession.getMapper(BlogDAO.class);
        List<Blog> list = blogDAO.findAllByTitleLikeOrAuthorLikeOrNameLike("伟");
        for (Blog blog : list)
        {
            System.out.println(blog);
        }

        sqlSession.close();
    }

测试结果如图,可以看到成功查找:
在这里插入图片描述
小结
对于一个搜索框分别接受三种参数中的一种,可以看出已经成功实现模糊查询,下面来看一个三个条件中任意个条件进行查询。

  1. 需求二(测试通过一个条件查找),这里我选择author(可以仍选一个条件查询)
    在这里插入图片描述
    结果如图,成功实现:
    在这里插入图片描述
  2. 需求二(测试通过二个条件查找),这里我选择author和title(可以仍选二个条件查询)
    在这里插入图片描述
    结果如图,成功实现:
    在这里插入图片描述
  3. 需求二(测试同时通过三个条件查找),即全选
    在这里插入图片描述
    结果如图,成功实现:
    在这里插入图片描述

总结

通过动态SQL学习,我成功实现了多条件模糊查询,完成了类似JPA中 findByLike的接口编写,实现了功能。后续将进一步探究更多负责查询的实现。


版权声明:本文为weixin_40145253原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。