当前位置: 首页 > wzjs >正文

中国最好的网站器域名统一seo查询工具网站

中国最好的网站器域名统一,seo查询工具网站,装修平台入驻,福州网站建设费用Spring Data Jpa 提供了基于 Jpa 的抽象层,用于在 Spring 框架下访问数据库,同时也提供了许多简化开发的功能,比如分页、投影、审计等。但是它没有办法方便快捷地自定义查询条件,尤其是条件查询。 QueryDSL 提供了基于 Java 的同一…

Spring Data Jpa 提供了基于 Jpa 的抽象层,用于在 Spring 框架下访问数据库,同时也提供了许多简化开发的功能,比如分页、投影、审计等。但是它没有办法方便快捷地自定义查询条件,尤其是条件查询。
QueryDSL 提供了基于 Java 的同一查询抽象,简化了自定义查询条件的过程。但是现在 QueryDSL 官方的开发进度已经放缓,基本不再更新,不过好在社区自行 Fork 了一个版本(OpenFeign QueryDSL)。本文将介绍如何使用 QueryDSL 简化 Jpa 查询,开发语言以 Kotlin 为主,同时也会介绍使用 Java 时该如何实现。

引入 QueryDSL

Spring Data Jpa 引入 QueryDSL 的部分在 Spring Data Extensions 里面可以找到,这里直接给出 OpenFeign QueryDSL 的引入方法。
Maven:

<dependencies><dependency><groupId>io.github.openfeign.querydsl</groupId><artifactId>querydsl-jpa</artifactId><version>${querydslVersion}</version></dependency>
</dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><!-- Explicit opt-in required via annotationProcessors orannotationProcessorPaths on Java 22+, see https://bugs.openjdk.org/browse/JDK-8306819 --><annotationProcessorPath><groupId>io.github.openfeign.querydsl</groupId><artifactId>querydsl-apt</artifactId><version>${querydslVersion}</version><classifier>jpa</classifier></annotationProcessorPath><annotationProcessorPath><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId></annotationProcessorPath></annotationProcessorPaths><!-- Recommended: Some IDE's might require this configuration to include generated sources for IDE usage --><generatedTestSourcesDirectory>target/generated-test-sources</generatedTestSourcesDirectory><generatedSourcesDirectory>target/generated-sources</generatedSourcesDirectory></configuration></plugin></plugins>
</build>

Gradle(Kotlin语法):

dependencies {implementation "io.github.openfeign.querydsl:querydsl-jpa:${querydslVersion}"annotationProcessor "io.github.openfeign.querydsl:querydsl-apt:${querydslVersion}:jpa"annotationProcessor 'jakarta.persistence:jakarta.persistence-api'testAnnotationProcessor "io.github.openfeign.querydsl:querydsl-apt:${querydslVersion}:jpa"testAnnotationProcessor 'jakarta.persistence:jakarta.persistence-api'
}

如果使用 Java 的话,使用上面方法引入即可,或者使用原版 QueryDSL 也可以使用。不过使用原版可能与一些新的组件(比如 Kotlin KSP、Spring Modulith 等)不兼容,因此如果使用 Kotlin 的话推荐使用 OpenFeign 版本:

plugins {// 省略其他 Kotlin 或相关插件id("com.google.devtools.ksp") version "2.1.20-2.0.0"  
}dependencies {// 省略 Kotlin 和 Spring 等其他依赖// QueryDSLimplementation("io.github.openfeign.querydsl:querydsl-jpa:6.11")ksp("io.github.openfeign.querydsl:querydsl-ksp-codegen:6.11")
}kotlin {compilerOptions {freeCompilerArgs.addAll("-Xjsr305=strict")// 避免覆盖 QuerydslBinderCustomizer 方法后 Spring Data Jpa 尝试解析 customize 方法导致无法启动freeCompilerArgs.addAll("-Xjvm-default=all")}
}allOpen {annotation("jakarta.persistence.Entity")annotation("jakarta.persistence.MappedSuperclass")annotation("jakarta.persistence.Embeddable")
}

注意事项如下:

  • KSP 的版本可以参考 KSP 官方仓库 来获取最新版本。
  • 使用 Kotlin 时需要添加编译选项 -Xjvm-default=all,这个与另一个接口 QuerydslBinderCustomizer 有关,我们放在后面详细说明。
  • 将具有 EntityMappedSuperClassEmbeddable 注解的类配置为开放类,避免 Jpa 查询数据转换为 Kotlin 对象时报错。
    使用 OpenFeign QueryDSL 的话,还可以参考 QueryDSL Examples 上面提供的示例代码,获取其他技术栈的引入方式。

使用 QueryDSL

Spring Data Jpa 通过 QuerydslPredicateExecutor 接口提供了集成 QueryDSL 的方法。定义 Repository 时继承此接口即可。QuerydslPredicateExecutor 提供了如下几个方法:

  • findOne:根据查询条件查询一条数据,返回 Optional<T>,并在有多条数据时抛出异常。
  • findAll:根据查询条件(或/和自定义排序方式)查询所有的数据,返回 Iterable<T>
  • findAll:根据查询条件和分页参数查询所有数据,返回 Page<T>
  • count:根据查询条件返回符合条件的结果数量,返回 long
  • exists:根据查询条件判断是否有符合条件的结果,返回 boolean
  • findBy:通过查询条件,以及对后续结果的操作,实现自定义返回结果,这个方法支持查询投影、自定义排序、限制查询数量等操作,也能自定义返回结果,后续将重点进行介绍。

定义实体

我们定义如下的实体 User

@Entity
public class User(@Id@GeneratedValue(strategy = GenerationType.UUID)val id: String,val name: String,val age: Int
)

执行 gradle build 命令之后,QueryDSL 会自动为我们生成对应的 Q 类。对于 User 实体,就会生成 QUser 类,这是 QueryDSL 提供的定义查询的方式。
如果要查询名称包含 name,并且年龄大于 20 的用户,我们可以这样编写:

val user = QUser.user
val predicate = user.name.contains("name").and(user.age.gt(20))
// 或者
val predicate = BooleanBuilder().apply {and(user.name.contains("name"))and(user.age.gt(20))
}// UserRepository 需要继承 QuerydslPredicateExecutor
val users = userRepository.findAll(predicate)

com.querydsl.core.BooleanBuilder 是 QueryDSL 提供的组合查询逻辑的工具,具有下列方法:
and / or / not:逻辑与 / 或 / 非。
andAnyOf:接受 Predicate 的可变长参数,表示并且右侧任意一个符合条件。
orAllOf:表示或者右侧全部符合条件,同样接受 Predicate 可变长参数。
andNot / orNot:对于右侧的条件取反,然后进行逻辑与 / 或。

查询单条数据

查询单条数据有两种操作:一种是只查询一条,在有多条可选数据时报错;另一种不管有多少数据,只查询第一条。后者的操作可以通过 findBy 方法实现。
首先是使用 findOne 方法,只查询一条,返回 Optional<T>

val optionalUser: Optional<User> = userRepository.findOne(predicate)

之后是使用 findBy 方法,它的函数签名如下:

<S extends T, R> R findBy(Predicate predicate, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction
);

其中各个参数如下:
TST 为实体类型,ST 的子类型,也可以是它本身。
Function<FluentQuery.FetchableFluentQuery<S>, R>:表示对于查询结果的后续操作。需要注意的是,queryFunction 接收的类型是 S,因此使用时需要手动标注类型(Kotlin 需要,Java 没有试过,不过如果类型不匹配,可以考虑标注上参数类型)。
R:表示返回结果类型,可能是 Optional<T>T?,也可能是分页、数量、是否存在等查询结果。

val user = userRepository.findBy(predicate) { query: FluentQuery.FetchableFluentQuery<User> ->query.one()
}

其他方法写法与这类似,因此直接给出函数和对应功能:
one:返回 Optional<T>,在有多条数据时抛出异常。
oneValue:同 one 方法,不过返回类型为 T?
first:返回 Optional<T>,在有多条数据时返回第一条。
firstValue:同 first 方法,不过返回类型为 T?
如果想要返回特定的一条数据,可以使用 FetchableFluentQuery.sortBy 方法,传入一个 Sort 类型的排序方法,先对查询出来的数据进行排序。

是否存在、查询数量

FetchableFluentQuerylong countboolean exists 方法,分别用来查询符合条件的数据数量,以及是否存在。

查询列表、分页

FetchableFluentQueryallpage 方法,可以用来查询符合条件的数据:
List<T> all:以列表的形式返回全部结果。
Page<T> page(Pageable pageable):以分页的形式返回全部结果。

自定义投影、限制数量等

如果只想查询部分行,或者部分列,可以考虑使用 limit 方法和 as / project 方法:
FetchableFluentQuery<T> limit(int limit):限制查询结果数量。
<R> FetchableFluentQuery<R> as(Class<R> resultType):将查询结果转换为类型为 R 的投影。
default FetchableFluentQuery<T> project(String... properties)FetchableFluentQuery<T> project(Collection<String> properties):接收多个属性名称,限制只查询一部分字段。
Spring Data Jpa 有两种类型的投影,分别使用接口和 Class 定义。需要注意的是,使用基于 Class 的投影时,无法使用嵌套投影(自定义属性的属性的类型)。
另外一个需要注意的点是,Spring Data Jpa 直到 3.5.0 版本(Spring Boot 3.5.0)开始,才正式支持 FetchableFluentQuery 使用基于 Class 的投影。在这之前,如果使用此功能,Spring Data Jpa 就会报错“只支持使用基于接口的投影方法”,详情参见 GitHub Issus。

通过 Controller 绑定查询参数

对于继承了 QueryDSL 的存储实现(不只是 Jpa、Spring Data MongoDB 等也受到支持),可以使用 QuerydslPredicate 将查询语句转换为 Predicate

// 下面是一个接口的查询方法,root 需要传入实体类的类型
fun query(@QuerydslPredicate(root = User::class) predicate: Predicate): Void {// ...
}

使用此功能时,需要使用 EnableSpringDataWebSupport 注解(加在启动类或者其他被自动装配的 Bean 上),并且要有 QueryDSL 依赖。
对于这一段 URL:?name=test&age=20,等价于下面的查询语句:

val predicate = BooleanBuilder().apply{and(QUser.user.name.eq("name"))and(QUser.user.age.eq(20))
}

默认的绑定行为如下:
Object 类型参数 + 简单类型属性:eq,例如 ?name=test
Object 类型参数 + 集合类型属性:contains,例如 ?name=a&name=b&name=c
Collection 类型参数 + 简单类型属性:in,例如 ?name=xxx
如果要自定义绑定行为,比如对于字符串类型默认模糊匹配等,可以让 Repository 接口继承 QuerydslBinderCustomizer<Q>,其中 Q 是 QueryDSL 生成的 Q 类型。

// 下面代码引用自 Spring Data Jpa 文档,并改为 Kotlin 语法
interface UserRepository: JpaRepository<User, String>,QuerydslPredicateExecutor<User>,QuerydslBinderCustomizer<QUser> {override fun customize(bindings: QuerydslBindings, user: QUser) {bindings.bind(user.username).first((path, value) -> path.contains(value))bindings.bind(String.class).first((StringPath path, String value) -> path.containsIgnoreCase(value))bindings.excluding(user.password)}
}

它的含义是:

  1. 对于 username 属性,传入参数时模糊匹配,但是区分大小写。
  2. 对于其他字符串类型的属性,传入参数时模糊匹配,不区分大小写。
  3. 不绑定对于 password 属性的查询参数。
    使用 Java 时,这里需要是默认方法。如果不声明为默认方法,那么 Spring Data Jpa 会将其视为一个查询方法,并尝试从中解析查询语句,在解析失败后报错,导致 Spring Boot 无法启动。
    使用 Kotlin 时,需要添加编译器选项,保证 Kotlin 编译为 Java 时生成默认方法:
kotlin {  compilerOptions {  // 省略其他编译器选项,比如 -Xjsr305=strict 等freeCompilerArgs.addAll("-Xjvm-default=all")  }  
}

关于 JVM Default 行为,可以参阅 Kotlin 文档。

http://www.dtcms.com/wzjs/388701.html

相关文章:

  • h5是动态网站吗seo1域名查询
  • 网站建设技能培训拓客软件排行榜
  • 什么什么云用来做网站网络营销方式有哪几种
  • 社交网站建设流程品牌推广方式有哪些
  • 关于学院网站建设的通知开发网站需要多少钱
  • 摄影网站源代码看广告赚钱
  • 温州公司做网站百度首页排名优化服务
  • 淘宝网 动态网站 静态网站企业网站推广方案设计
  • 响应式网站视频怎么做百度竞价推广公司
  • 商城网站建设行情seo搜索优化工具
  • 网站建设可实施性报告dy刷粉网站推广马上刷
  • 网站做3儿童车开场动画百度云网盘免费资源
  • 怎么查询网站是否被收录百度推广价格表
  • 公司宣传 如何做公司网站软文网站平台
  • 深圳网站建设方维网络成都seo
  • 浙江省城乡和住房建设厅网站首页网络营销培训机构
  • 可以下载新闻视频的网站让手机变流畅的软件下载
  • 凡客衬衫官方网站营销型网站建设优化建站
  • 彭阳门户网站建设滨州seo排名
  • 北京顺义去哪找做网站的游戏推广员招聘
  • 公司网站建设及维护什么是seo文章
  • 深圳建网站兴田德润实惠青岛网站建设微动力
  • 自己如何做网站建设长尾关键词搜索网站
  • dw做的网站如何使用深圳网络提速优化服务包
  • 北京多用户商城网站建设seo技术培训山东
  • 流媒体网站建设规划 所需设备东营seo整站优化
  • 新型网站设计免费公司网址怎么注册
  • 武汉做网站最牛的公司清理大师
  • 建设网站的功能及目的是什么重庆快速网络推广
  • 丛台企业做网站推广微信小程序开发费用