如何将sql`partition by`转换为criteria API查询?

问题描述 投票:0回答:1

如何使用 criteria api 构建复杂查询?我尝试使用criteria api来实现评论中的sql,但是两天后问题并没有解决。我尝试了chatgpt、google、spring-data-jpa、hibernate文档和Jakarta ee文档,但找不到类似的代码。这些api不支持类似的查询吗? 要执行的SQL:

select test_version.*
from test_version
         join (select identification,
                      version,
                      dense_rank()
                      over (partition by identification order by major_version desc ,minor_version desc ,patch_version desc ) as rank
               from test_version) rk
              on test_version.identification = rk.identification
where test_version.version = rk.version
  and rk.rank = 1;

java代码:

package com.example.addtionalcriteriademo;

import jakarta.persistence.*;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.MapAttribute;
import lombok.Data;
import org.hibernate.annotations.IdGeneratorType;
import org.hibernate.metamodel.model.domain.internal.MapAttributeImpl;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.repository.NoRepositoryBean;

@SpringBootApplication
@EnableJpaRepositories
public class AdditionalCriteriaDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(AdditionalCriteriaDemoApplication.class, args);
    }

    @Bean
    ApplicationRunner runner(TestVersionRepository repository) {
        return args -> {
            repository.findAll(repository.query()).forEach(System.out::println);
        };
    }

}

@Data
@MappedSuperclass
class AbstractVersion {
    @Id
    @GeneratedValue(
            strategy = GenerationType.AUTO
    )
    private int id;
    private String identification;
    private String version;
    private int majorVersion;
    private int minorVersion;
    private int patchVersion;
}

@Table
@Entity
class TestVersion extends AbstractVersion {
}

@NoRepositoryBean
interface AbstractVersionRepository<T extends AbstractVersion> extends JpaRepository<T, Integer>, JpaSpecificationExecutor<T> {
    
    default Specification<T> query() {
        return (root, query, cb) -> {
            return null;
        };
    }
}

interface TestVersionRepository extends AbstractVersionRepository<TestVersion> {
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>additional-criteria-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>additional-criteria-demo</name>
    <description>additional-criteria-demo</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <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>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

请帮忙......

java jakarta-ee spring-data-jpa criteria-api
1个回答
0
投票

不幸的是,这些技术中没有“逃生舱口”。 Hibernate 在其标准 API 中有一些(非常有限),但在最新版本(6)中被删除。

解决方法是当您需要 SQL 数据库中的一些重要内容并且不需要条件 SQL 生成时使用

JdbcTemplate
NamedParameterJdbcTemplate
(为此我推荐 JOOQ 或 QueryDSL)。

© www.soinside.com 2019 - 2024. All rights reserved.