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

网站制作2019趋势宁德市旅游景点大全

网站制作2019趋势,宁德市旅游景点大全,做哪些网站流量大,海南网站建设fwlitSpring 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/510630.html

相关文章:

  • 企业网站优化怎么提高关键词排名seo网络推广教程
  • 深圳网站建设公司联系百度推广如何获取精准的客户
  • 一个人做b2b2c网站网站优化排名方案
  • wordpress如何设置内容页搜索引擎关键词优化
  • 登建设厅锁子的是哪个网站国内最近的新闻大事
  • 网站编程学习泰安短视频seo
  • 新公司做网站怎么弄今日头条收录入口
  • 秦皇岛高端网站设计收录网站查询
  • 政府网站管建设情况汇报百度推广怎么做免费
  • 企业网站建设杭州公司佛山seo关键词排名
  • 做宣传网站买什么云服务器百度游戏客服在线咨询
  • 徐州便民信息网优化seo教程技术
  • 如何再网站上做免费广告厦门网站关键词推广
  • 济宁做网站哪家比较好seo少女
  • 域名商的网站每日军事新闻
  • 还有哪些免费的网站可以做H5信息流优化师
  • 如何用模板做公司网站seo薪酬水平
  • wordpress主题point谷歌seo网站建设
  • 网站建设广告词品牌推广营销
  • wordpress网站模板仿站工具百度搜索排行榜前十名
  • 网站架构图怎么做今天的国际新闻
  • 番禺人才网最新招聘信息seo优化技术是什么
  • 青岛网站开发招聘下载谷歌浏览器
  • 新品牌推广策略厦门seo搜索排名
  • 陇城科技网站建设seo网站优化软件
  • 樟木头仿做网站互联网营销行业前景
  • 自动发卡网站怎么做广州专业网络推广公司
  • 温州在线课堂seo短视频
  • 网站logo图怎么做的长沙网络营销公司
  • 网站规划与建设大作业答案天津债务优化公司