Mybatis实现多条件模糊查询
以往对数据库进行增删改查时,我使用了Spring内置的Spring DataJPA,这是一种简便的操作手段,数据接口通过继承JpaRepository就能直接调用封装好的方法进行CRUD操作。最近,我又学习了一些mybatis知识,下面我们就来看一下如何使用mybatis实现多条件模糊查询。
一、需求
很多时候,我们会有这样的需求:
- 一个搜索框,可以使用多个条件进行搜索。比如对博客而言,可以是标题、作者、名称等。
- 多个搜索或选项框,依据其中的任意多个进行搜索。
下面以一个博客类进行说明。
二、步骤
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进行测试
数据库简单数据如图
- 需求一(测试通过标题模糊查找),代码如下:
@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();
}
测试结果如图,可以看到成功查找:
小结
对于一个搜索框分别接受三种参数中的一种,可以看出已经成功实现模糊查询,下面来看一个三个条件中任意个条件进行查询。
- 需求二(测试通过一个条件查找),这里我选择author(可以仍选一个条件查询)
结果如图,成功实现: - 需求二(测试通过二个条件查找),这里我选择author和title(可以仍选二个条件查询)
结果如图,成功实现: - 需求二(测试同时通过三个条件查找),即全选
结果如图,成功实现:
总结
通过动态SQL学习,我成功实现了多条件模糊查询,完成了类似JPA中 findByLike的接口编写,实现了功能。后续将进一步探究更多负责查询的实现。