JPA在不写sql的情况下实现模糊查询

这篇具有很好参考价值的文章主要介绍了JPA在不写sql的情况下实现模糊查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文已收录于专栏
《Java》

背景介绍

  在我们的项目中很多的业务都会设计模糊查询,例如按照姓氏去获取人员的信息,按照手机号的前三位去获取人员的信息等。我们除了正常的手写模糊查询的sql语句去获取信息之外,还可以使用JPA自带的API来实现任意字段的模糊查询。JPA已经给我们封装好了。当我们对模糊查询非常熟悉了之后直接拿来时候即可。

概念说明

单字段模糊匹配:

说明:在一个字段中无论关键字出现在什么位置上,只要有关键词即可。
场景:获取手机号开头为187的学生
应用:SELECT*FROM table_name WHERE BINARY column_name LIKE'%keyword%';

多字段模糊匹配:

说明:在多个字段中无论关键字出现在什么位置上,只要每个字段有每个字段指定的关键词即可。
场景:获取手机号开头为187并且姓氏为武的学生
应用:SELECT*FROM table_name WHERE BINARY column1_name LIKE'%keyword1%'AND column2_name LIKE'%keyword2%';

  注:BINARY函数是开启大小写敏感的函数,底层逻辑是通过Ascii码的方式比较的。因为数据库默认是对大小写不敏感的,也就是我们在查询名称为wzl数据的时候,也会把名称为Wzl的数据也查询出来。

实现过程

代码实现

1.写一个实体类去实现Specification接口,重写toPredicate方法

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.tfjybj.dao.UserDao;
import com.tfjybj.utils.SnowflakeIdWorker;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.persistence.*;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @BelongsProject: incentive
 * @BelongsPackage: com.tfjybj.service
 * @Author: Wuzilong
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-08-28 14:48
 * @Version: 1.0
 */
@Table
@Entity
@Service
@Data
public class User implements Specification<User> {

    @Id
    @JsonSerialize(using = com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class)
    private Long id;

    private String account;

    private  String password;

    private String phone;

    private Date createTime;

    private Date updateTime;

    private Integer isDelete;

    @Resource
    @Transient
    private UserDao userDao;

    @Override
    public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
        List<String> nonNullFields = new ArrayList<>();
        Field[] declaredFields = this.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            try {
                Object value = field.get(this);
                if (value != null) {
                    nonNullFields.add(field.getName());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        Predicate[] predicates = new Predicate[nonNullFields.size()+1];

        for (int i = 0; i < nonNullFields.size(); i++) {
            try {
                predicates[i] = criteriaBuilder.like(root.get(nonNullFields.get(i)), "%" + this.getClass().getDeclaredField(nonNullFields.get(i)).get(this) + "%");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 添加额外的条件,排除isdelete=1的数据
        predicates[nonNullFields.size()] = criteriaBuilder.notEqual(root.get("isDelete"), 1);

        return criteriaBuilder.and(predicates);
    }
}

本文中实现的是and方式的模糊查询,也可是使用or的方式进行模糊查询,也就是多个字段中都包含一个关键字。

2.定义一个接口去继承JpaRepository接口,并指定返回的类型和参数类型

@Entity
import com.tfjybj.service.User;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @BelongsProject: incentive
 * @BelongsPackage: com.tfjybj.dao
 * @Author: Wuzilong
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-08-28 14:48
 * @Version: 1.0
 */
@Repository
public interface UserDao extends JpaRepository<User, Long> {

    List<User> findAll(Specification<User> userInfo);
}

3.在业务类中调用声明的接口

@Entity
    public List<User> selectToFuzzy(User userInfo){
        List<User> userInfoList = userDao.findAll(userInfo);
        return userInfoList;
    }

4.在Controller中直接调用业务类中的方法即可

    @RequestMapping(value="selectToFuzzy",method= RequestMethod.POST)
    //模糊查询用户的信息
    public List<User> selectToFuzzy(@RequestBody User userInfo){
        List<User> users = user.selectToFuzzy(userInfo);
        return users;
    }

执行结果

JPA在不写sql的情况下实现模糊查询,Java,java,spring,spring cloud

JPA在不写sql的情况下实现模糊查询,Java,java,spring,spring cloud

  可以看到我们的入参都是对应字段值的一部分内容,phone字段传入的是187它会把phone字段中包含187的所有数据都返回回来。同样两个字段一起模糊查询也是一样。

其他方式

1.使用JPQL进行模糊查询:

使用LIKE关键字结合通配符(%)进行模糊匹配。
例如:SELECT e FROM Employee e WHERE e.name LIKE '%John%'

2.使用Spring Data JPA的Query By Example进行模糊查询:

创建一个实体对象作为查询条件,设置需要模糊匹配的属性值。
例如:ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("name", match -> match.contains()); Example<Employee> example = Example.of(employee, matcher);

3.使用Spring Data JPA的@Query注解进行模糊查询:

在Repository接口中使用@Query注解定义自定义的查询方法。
在查询方法中使用%通配符进行模糊匹配。
例如:@Query("SELECT e FROM Employee e WHERE e.name LIKE %?1%") List<Employee> findByName(String name);

总结提升

  根据自己的业务需求去选择使用哪一种模糊查询的方式。底层原理都是一样的。JPA封装了一些公共的内容,我们开发的过程中使用起来就比较容易和简单。但是我们在使用的过程中也要明白底层是如何实现,不能只停留在会使用的阶段中。知其然也要知其所以然。文章来源地址https://www.toymoban.com/news/detail-692219.html


🎯 此文章对你有用的话记得留言+点赞+收藏哦🎯

到了这里,关于JPA在不写sql的情况下实现模糊查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java桌面程序:加载数据-模糊查询-删除-新增

    1.DB.java 2.BaseDao.java 3.两个窗体 完整代码 完整代码 ① 程序一开始执行时,需要加载显示数据: 主窗体中-修改构造器中的代码 ② 定义初始化表格的方法: 主窗体中-完整代码 ③ 点击查询按钮时的操作—模糊查询: 完整代码-在主窗体中编写 ④ 实现删除按钮的功能: 完整代

    2024年02月10日
    浏览(44)
  • JPA自定义SQL查询

    关于自定义SQL查询,方法名可以随意取(遵循驼峰命名法,方法名需能一眼看出此方法的用处),不需要遵循JPA制订的规则来起方法名。 自定义SQL 是指:在方法上使用 @Query 注解,然后写sql。 @Query 注解中有两个常用的属性, value (定义sql), nativeQuery (true表示数据的sql,false表示

    2024年02月02日
    浏览(29)
  • MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询

    MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询 MyBatis-Plus不写任何resultMap和SQL执行一对一、一对多、多对多关联查询 com.github.dreamyoung mprelation 0.0.3.2-RELEASE 注解工具使用优缺点: 优点: 使用简单,通过在实体类上添加@OneToOne / @OneToMany / @ManyToOne / @ManyToM

    2024年01月20日
    浏览(56)
  • 69、Spring Data JPA 的 @Query查询 和 命名查询(半自动:提供 SQL 或 JPQL 查询)

    1、方法名查询(全自动,既不需要提供sql语句,也不需要提供方法体) 2、@Query查询(半自动:提供 SQL 或 JPQL 查询) 3、自定义查询(全手动) @Query查询 和 命名查询的区别: 命名查询与直接用@Query来定义查询的本质是一样,只不过它们定义SQL或JPQL语句的位置不同。

    2024年02月07日
    浏览(43)
  • oracle sql语言模糊查询

    在Where子句中,可以对datetime、char、varchar字段类型的列用Like子句配合通配符选取那些“很像...”的数据记录,以下是可使用的通配符: %   零或者多个字符 _   单一任何字符(下划线) /   特殊字符 []   在某一范围内的字符,如[0-9]或者[aeth] [^]   不在某范围内的字符,如

    2024年02月10日
    浏览(39)
  • MyBatis动态SQL、模糊查询与结果映射

    目录 前言 一、MyBatis动态SQL 1.动态SQL是什么 2.动态SQL的作用 3.常用动态SQL元素 1. where + if 元素 2. set + if 元素 3. choose + when + otherwise 元素 4. 自定义 trim 元素  1. 自定义 trim 元素改写上面的 where + if 语句 2. 自定义 trim 元素改写上面的 set + if 语句 5. foreach 元素 6.SQL片段重用 二、

    2024年02月11日
    浏览(40)
  • SQL Server 数据表模糊查询(like 用法)以及查询函数

    在SQL Server Management Studio (SSMS) 中,进行模糊查询主要是通过使用 like 操作符来实现的。 like 操作符用于在 where 语句中搜索列中具有指定模式的数据。 我们在简单例子中来了解: % 通配符:表示任意数量的字符。 这个例子会选择 column_name 列中包含\\\"pattern\\\"这个词的所有记录,就

    2024年01月22日
    浏览(77)
  • 查询sqlserver内存分配情况的SQL

    SELECT mg.granted_memory_kb, mg.session_id, t.text, qp.query_plan  FROM sys.dm_exec_query_memory_grants AS mg CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) AS t CROSS APPLY sys.dm_exec_query_plan(mg.plan_handle) AS qp ORDER BY 1 DESC OPTION (MAXDOP 1) USE master  GO ;WITH    cte   AS ( SELECT   RP.pool_id ,   RP.Name ,   RP.min_memory_percent ,  

    2024年02月09日
    浏览(44)
  • es多字段模糊匹配wildcardQuery,java实现

    es 版本:7.10.1 spring-cloud版本:2.3.5.RELEASE spring-boot-starter-data-elasticsearch 版本 2.3.12.RELEASE spring-data-elasticsearch 版本 4.0.9.RELEASE es查询,需求:title或者content任意一个字段能匹配到即可 使用dsl查询语句如下,构建一个query ,should只要一个匹配即可 运行结果,可以查出数据

    2024年02月11日
    浏览(38)
  • 【Java 进阶篇】使用 SQL 进行排序查询

    在数据库中,我们经常需要对查询的结果进行排序,以便更容易地理解和分析数据。SQL(Structured Query Language)提供了强大的排序功能,允许我们按照指定的列对数据进行升序或降序排序。本文将详细介绍如何使用 SQL 进行排序查询,包括基本的排序语法、多列排序、自定义排

    2024年02月07日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包