美文网首页
spring jpa查询条件动态拼接+只查询部分字段+多表关联

spring jpa查询条件动态拼接+只查询部分字段+多表关联

作者: 饱饱想要灵感 | 来源:发表于2022-07-17 20:11 被阅读0次

提问: jpa如何同时实现以下3个功能?

  1. 查询条件动态拼接
  2. 多表关联查询
  3. 自定义返回字段

答: 简单实现JpaRepository接口是行不通的; 需要通过EntityManager构造复杂查询, 实现思路如下

实现类

@RequestMapping("/keyword")
@RestController
public class KeywordController{

    @PersistenceContext
    private EntityManager entityManager;
    
    @RequestMapping("/jpaDynamic")
    public Object jpaDynamic(String keyword, String className, String priority){

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

        // 指定结果视图
        CriteriaQuery<KeywordVO> criteriaQuery = criteriaBuilder.createQuery(KeywordVO.class);

        // 查询基础表
        Root<KeywordDO> root = criteriaQuery.from(KeywordDO.class);

        // 关联查询, 需在主体内有对应@JoinColum属性
        Join<Object, Object> joinKeywordClass = root.join("keywordClass", JoinType.LEFT);

        // 查询条件动态拼接
        Predicate predicate = criteriaBuilder.conjunction();
        List<Expression<Boolean>> expressions = predicate.getExpressions();
        if (ObjectUtil.isNotNull(keyword)) {
            expressions.add(criteriaBuilder.or(
                    criteriaBuilder.like(root.get("nameOne"), "%" + keyword + "%"),
                    criteriaBuilder.like(root.get("nameTwo"), "%" + keyword + "%")
            ));
        }
        if (ObjectUtil.isNotNull(className)) {
            expressions.add(criteriaBuilder.like(joinKeywordClass.get("name"), "%" + className + "%"));
        }
        if (ObjectUtil.isNotNull(priority)) {
         expressions.add(criteriaBuilder.in(joinKeywordClass.get("priority")).value(StringUtil.splitToIntList(priority)));
        }

        // 选择返回字段, 需要在VO类添加相应的构造函数
        criteriaQuery.select(criteriaBuilder.construct(KeywordVO.class,
                root.get("nameOne").alias("nameOne"),
                root.get("nameTwo").alias("nameTwo"),
                joinKeywordClass.get("name").alias("className"),
                joinKeywordClass.get("priority").alias("classPriority")
        )).where(predicate);

        // 获取结果集,也可以设置分页查询,对应关键字 limit ?, ?
        return entityManager.createQuery(criteriaQuery).setFirstResult(1).setMaxResults(10).getResultList();
//        return entityManager.createQuery(criteriaQuery).getResultList();
    }
}

VO类, 需要添加相应的构造函数

/**
 * 关键词
 */
public class KeywordVO {
    /** 关键词类型id */
    private Long classId;
    /** 关键词1 */
    private String nameOne;
    /** 关键词2 */
    private String nameTwo;
    /** 使用类型 */
    private String useType;
    private KeywordClassDO keywordClass;
    private String className;
    private Integer classPriority;

    public KeywordVO() {
    }
    
    /**
    * 前面自定义查询返回的字段, 需要按顺序生成构造函数
    */
    public KeywordVO(String nameOne, String nameTwo, String className, Integer classPriority) {
        this.nameOne = nameOne;
        this.nameTwo = nameTwo;
        this.className = className;
        this.classPriority = classPriority;
    }
    ...
}

实体类

/**
 * 关键词类型实体
 */
@Entity
@Table(name = "keyword_class")
public class KeywordClassDO extends RecordEntity {
    /** 名称 */
    @Length(max = 256, message = "0-256个任意字符")
    @Column(name = "name")
    private String name;
    /** 类型优先级, 1优先级最高, 5最小  1,2,3,4,5 */
    @Column(name = "priority")
    private Integer priority;
    ...
}

/**
 * 关键词实体
 */
@Entity
@Table(name = "keyword")
public class KeywordDO extends RecordEntity {
    /** 关键词类型id */
    @Column(name = "class_id")
    private Long classId;
    /** 关键词1 */
    @Length(max = 256, message = "0-256个任意字符")
    @Column(name = "name_one")
    private String nameOne;
    /** 关键词2 */
    @Length(max = 256, message = "0-256个任意字符")
    @Column(name = "name_two")
    private String nameTwo;
    /** 使用类型 */
    @Length(max = 128, message = "0-128个任意字符")
    @Column(name = "use_type")
    private String useType;

    @ManyToOne
    @JoinColumn(name = "class_id", insertable = false, updatable = false)
    private KeywordClassDO keywordClass;
    ...
}

相关文章

  • 【Spring Boot + Kotlin 实战教程】Sprin

    【Spring Boot + Kotlin 实战教程】Spring Data JPA 多表关联查询 映射到 Dt...

  • Spring Data JPA

    Spring Data JPA,一种动态条件查询的写法 我们在使用SpringData JPA框架时,进行条件查询...

  • 关于JPA中动态查询的做法

    原文出处: 【一目了然】Spring Data JPA使用Specification动态构建多表查询、复杂查询及排...

  • JPA多表分页动态多条件查询

    参考文章: 解决 JPA 多表动态查询 JPA EntityManager createNativeQuery 多...

  • 7 Spring-data-jpa查询方法

    springdata-jpa 八种查询方法 Spring Data JPA 简单查询--接口方法 jpa动态查询-...

  • MySQL索引失效

    哪些情况需要创建索引 主键自动建立唯一索引频繁作为查询条件的字段应该创建索引多表关联查询中,关联字段应该创建索引 ...

  • Spring Data JPA进阶

    Spring Data JPA进阶 目录 ddl属性配置 通过解析方法名查询 关联查询 spring.jpa.pr...

  • JPA-复杂查询

    时间相关查询 Spring data jpa 条件查询-按时间段查询Jpa查询排序,时间范围查询,当天时间范围查询...

  • Spring Data Jpa的使用(二)

    使用Jpa进行多表关联查询,利用java反射将查询结果封装到对象中 在使用Jpa进行数据库查询的时候,经常会遇到这...

  • python面试题01

    1、什么是多表关联查询,有几种多表关联的查询方式,分别是什么? 多表关联查询概念: 多表关联查询分类:1.1内连接...

网友评论

      本文标题:spring jpa查询条件动态拼接+只查询部分字段+多表关联

      本文链接:https://www.haomeiwen.com/subject/mvudirtx.html