Spring Data JPA 条件查询详解(一)

版权声明:shnu_lollipop https://blog.csdn.net/weixin_38896998/article/details/85228368

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.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/>
    </parent>

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

<dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </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. 找到我们模块的名称,并选中:
  4. 点击上方的加号,添加JPA功能
  5. 之后便会如下:
  6. 将我们的Persistence窗口显示出来:
    在这里插入图片描述
  7. 右击我们的模块,选中By Database Schema
  8. 点击OK即可自动生成POJO类

生成的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));
    }

在此之前,我预先向数据表里插入了两条数据:

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


可以看到我们的模糊查询功能已经实现了。

猜你喜欢

转载自blog.csdn.net/weixin_38896998/article/details/85228368