Spring Data JPA 动态条件查询

Spring Data JPA是Spring基于Hibernate开发的一个JPA框架。如果用过Hibernate或者MyBatis的话,就会知道对象关系映射(ORM)框架有多么方便。但是Spring Data JPA框架功能更进一步,为我们做了一个数据持久层框架几乎能做的任何事情,本篇主要介绍其强大的条件查询功能。

添加依赖

本次我们采用基于Spring boot的形式讲解Spring Data JPA动态条件查询功能的使用。当前使用的是Spring boot 为2.1.1.RELEASE版本:

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.1.RELEASEversion>
        <relativePath/>
    parent>

搭建完Spring boot项目框架之后,添加如下依赖即可:

<dependencies>
		<dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-jpaartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
    dependencies>

数据库脚本:

create table tb_label
(
  id        varchar(20)  not null comment '标签ID'
    primary key,
  labelname varchar(100) null comment '标签名称',
  state     varchar(1)   null comment '状态',
  count     bigint       null comment '使用数量',
  recommend varchar(1)   null comment '是否推荐',
  fans      bigint       null comment '粉丝数'
)
  comment '标签';

执行以上sql脚本后,可以利用Idea强大的JPA映射转换功能生成POJO类:

  1. 点开Project Structure
  2. 点开Modules
  3. 找到我们模块的名称,并选中:
    Spring Data JPA 动态条件查询_第1张图片
  4. 点击上方的加号,添加JPA功能
  5. 之后便会如下:
    Spring Data JPA 动态条件查询_第2张图片
  6. 将我们的Persistence窗口显示出来:
    Spring Data JPA 动态条件查询_第3张图片
  7. 右击我们的模块,选中By Database Schema
    Spring Data JPA 动态条件查询_第4张图片
  8. 点击OK即可自动生成POJO类
    Spring Data JPA 动态条件查询_第5张图片

生成的POJO类:

package cn.lollipop.base.pojo;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.io.Serializable;

@Entity(name = "tb_label")
public class Label implements Serializable {
    @Id
    private String id;
    private String labelname; //标签名称
    private String state; //状态
    private Long count; //使用数量
    private Long fans; //关注数

	setter、getter 略......
}

定义我们的DAO接口:

这里我们只用定义一个带有@Repository注解的接口,并继承JpaRepository和JpaSpecificationExecutor接口,不必写实现类,Spring boot在启动时,将会为我们自动生成实现类并在容器中管理接口对象。

package cn.lollipop.base.dao;

import cn.lollipop.base.pojo.Label;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

@Repository
public interface LabelDAO extends JpaRepository<Label, String>, JpaSpecificationExecutor<Label> {
}

在JpaRepository接口中传入我们的POJO类的类型和主键类型,在JpaSpecification接口中,我们传入POJO类的类型即可。

服务层实现模糊查询全部标签

本次我们采用JpaSpecification接口提供的findAll(Predicate predicate);方法进行条件查询:

/**
     * 根据条件查询全部标签
     *
     * @param label
     * @return
     */
    public List<Label> findSearch(Label label) {
        return labelDAO.findAll(new Specification<>() {
            /**
             *
             * @param root 根对象,也就是要把条件封装到哪个对象中
             * @param criteriaQuery 封装查询关键字
             * @param criteriaBuilder 封装条件对象
             * @return
             */
            @Override
            public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (label.getLabelname() != null && !"".equals(label.getLabelname())) {
                    // where 数据库中labelname列 LIKE '%' + Label.labelname + '%'
                    predicates.add(criteriaBuilder.like(root.get("labelname"), "%" + label.getLabelname() + "%"));
                }
                if (label.getState() != null && !"".equals(label.getState())) {
                    // where 数据库中state列 = Label.state 
                    predicates.add(criteriaBuilder.equal(root.get("state"), label.getState()));
                }
                Predicate[] pres = new Predicate[predicates.size()];
                predicates.toArray(pres);

                // and语句
                return criteriaBuilder.and(pres);
            }
        });
    }

定义我们的Controller类:

@RestController
@CrossOrigin
@RequestMapping("/label")
public class LabelController {
    private final LabelService labelService;

    @Autowired
    public LabelController(LabelService labelService) {
        this.labelService = labelService;
    }
}
添加如下方法:
    @RequestMapping(value = "/search", method = RequestMethod.POST)
    public Result findSearch(@RequestBody Label label) {
        return new Result(StatusCode.OK, true, "查询成功", labelService.findSearch(label));
    }

在此之前,我预先向数据表里插入了两条数据:
Spring Data JPA 动态条件查询_第6张图片

启动我们的项目,打开Postman,发送POST请求:

Spring Data JPA 动态条件查询_第7张图片
可以看到我们的模糊查询功能已经实现了。

你可能感兴趣的:(Spring,Data)