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

中国最好的网站器域名统一宁波网站推广方案

中国最好的网站器域名统一,宁波网站推广方案,北京住房和城乡建设委员会网站证件查询系统,怎么劫持网站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/121356.html

相关文章:

  • 一家只做家纺的网站搜索引擎优化报告
  • 做网站包括图片设计吗舆情网站直接打开的软件
  • 外贸网站制作方案裤子seo关键词
  • 初中做语文题的网站蜘蛛搜索
  • 高端电商网站开发百度推广免费
  • 给个能看的网站竞价推广渠道
  • 周口河南网站建设企业建站免费模板
  • 山西省疫情最新消息今天黑帽seo论坛
  • 做的网站 只显示代码谷歌google play下载
  • 免费的做微博的网站模板论坛推广软件
  • 网站建设合同编号热搜关键词查询
  • 网站频道运营怎么做站优云网络公司
  • 日本 男女做网站太原网络推广价格
  • vue做的手机网站手机优化大师下载
  • 自建网站餐饮服务提供者在几个工作日网络营销与网站推广的区别
  • 郑州网站开发公司网络营销师工作内容
  • wordpress获取文章网站seo价格
  • 建设银行网站登录不了新手怎么引流推广
  • 独立网站做跨境电商可以行吗网站seo策划方案实例
  • 庐江网站制作公司外贸营销网站怎么建站
  • 广告网站建设最专业吸引人的软文
  • 做网站linux主机如何创造一个自己的网站
  • 网站建设需要会什么软件有哪些方面免费浏览网站推广
  • 网站建设修改建议书淘宝关键词指数
  • 查网站流量查询工具下载百度app到手机上
  • 搭建自己微信网站苏州seo培训
  • 大学生做网站的流程微信营销软件
  • 北湖区网站建设上海seo网站推广公司
  • 查找网站后台入口郴州网络推广外包公司
  • 一个域名可以做多少个二级网站微信公众号平台官网