写点什么

通过 Jinq 简化数据库查询

  • 2016-03-23
  • 本文字数:1402 字

    阅读完需:约 5 分钟

Jinq 库为数据库查询提供了一个 DSL,可以用于Java 和Scala 。这个项目的灵感来源于.NET 的LINQ,致力于提供易于编写的查询,同时支持类型安全。据这个工具的创建者Ming-Yee Iu 介绍, Jinq 起步于 2006 年,当时的名称为 Queryll,但是直到采用了 Java 8 的 lambdas,才完全发挥出了它的潜力。

跟其他已有的库不同,Jinq 并无意提供完整的数据访问功能:Jinq 只是一个查询工具,因此用于从数据库中获取数据。数据操作,不管是插入、修改还是删除,都依然需要开发人员采用其他的机制。基于这个原因,Jinq 提供了与其他最流行的数据库访问库联合使用的支持,包括所有兼容JPA 的模式(如Hibernate 或EclipseLink)与 jOOQ

鉴于它不能作为已有库的替代品,有些用户可能就会怀疑 Jinq 所带来的附加价值是什么。为了尝试并展现它的价值何在,我们用不同的工具来对比一个相同的查询。

我们考虑一个由世界各个国家和城市所组成的数据库。假设我们需要获取首都人口在 300 万以上的国家列表。对应的 SQL 查询会如下所示:

SELECT country.name FROM country JOIN city ON country.capital_id = city.id WHERE city.population > 3000000假设采用典型的映射和配置,同等功能的查询使用 Hibernate 会如下所示:

List = session.createQuery("SELECT country.name " + "FROM country JOIN city " + "WHERE city.population > 3000000") .list();
我们可以看到,HQL 能够消除掉一些查询中的复杂性,但它依然还是在一个字符串之中,这意味着它可能会包含一些潜在的错误,而这些错误只能在运行期才能发现。接下来看一下,如果使用 jOOQ 的话,该怎样编写这个查询:

Result result = create.select(COUNTRY.NAME) .from(COUNTRY) .join(CITY).on(COUNTRY.CAPITAL_ID.equal(CITY.ID)) .where(CITY.POPULATION.gt(3000000)) .fetch(); 这给程序员提供了一种更高级别的类型安全性,引用错误的域、表或操作将会导致编译错误。但是,这个代码依然不够流畅。最后,我们来看一下使用 Jinq 的函数式方法该如何编写这个查询:

List = streams.streamAll(em, City.class) .where(c -> c.getCountry().getCapital().equals(c) && c.getPopulation() > 3000000) .select(c -> c.getCountry().getName()) .toList();
这个代码非常类似于开发人员使用流数据时所创建的典型结构,这允许他们在编码的时候,保持一种函数式的编程风格。在内部,尽管它看起来像是使用流,但 Jinq 会使用一种名为“符号执行(symbolic execution)”的技术,将上述的代码转换为实际的 SQL 查询,而这些 SQL 查询,数据库是能够进行优化的。

在字节码级别,当到达这块代码的时候,Jinq 并不会直接执行。Jinq 将会检查不同的步骤,并计算这些步骤会给传入数据所带来的副作用,这就是所谓的符号执行。一旦这些组合的副作用计算完毕,它就会转换为同等作用的 SQL 查询。如果所计算的副作用对于 Jinq 来说过于复杂,无法转换为 SQL,那么它会作为正常的 Java 代码来执行,这意味着会得到相同的结果,但是性能可能会稍差一些。

在 Java 开发社区,一直想要有一个能够与.NET 的 LINQ 功能对等的 Java 实现。由于语言设计的限制,这可能永远无法完全实现:像 C#这样的.NET 语言实现,在定义级别进行了修正,以便于让 LINQ 集成到语言之中,在这方面,Java 的架构师是一直反对的。基于该原因,Jinq 可能是最为接近的类似方案了。

查看英文原文: Simplifying Database Queries with Jinq

2016-03-23 19:009002

评论

发布
暂无评论
发现更多内容

linux安装oracle XE,详解Java架构进阶面试题

Java 程序员 后端

Maven相关知识点整理,java基础语法的格式

Java 程序员 后端

Mybatis一二级缓存实现原理与使用指南,java后端技术梳理

Java 程序员 后端

mybatis开发要点-insert主键ID获取和多参数传递,mybatis原理详解

Java 程序员 后端

MyBatis详解(一),实战java高并发程序设计

Java 程序员 后端

kubernetes下的jenkins如何设置maven,java异步请求原理

Java 程序员 后端

Kubernetes教程之新手安装必看(快速浏览少走弯路),java集合详解和集合面试题目

Java 程序员 后端

mybatis-plus代码生成器,一键生成代码,springcloud教程百度云

Java 程序员 后端

mybatis-plus使用教程,java面试题基础篇

Java 程序员 后端

Kubernetes 常用命令大全,linux入门经典书籍

Java 程序员 后端

Kubernetes 稳定性保障手册 -- 可观测性专题,今晚我们通宵学习SpringCloud

Java 程序员 后端

Kubernetes官方java客户端之七:patch操作,深入浅出Java

Java 程序员 后端

Linux内核结构组成之进程调度,java开发直播系统相关教程

Java 程序员 后端

Mybatis学习笔记--Mybatis实现CRUD,springboot注解面试题

Java 程序员 后端

Kubernetes官方java客户端之八:fluent style,mysql入门视频教程

Java 程序员 后端

markdown编辑器的使用教程,Java成长路线图

Java 程序员 后端

MyBatis(四):参数处理器,linux运维架构师

Java 程序员 后端

mybatis常用注解(绝对经典),java程序设计教程张延军课后答案

Java 程序员 后端

Linux云服务器搭建SFTP服务器图片服务器,java线程原理

Java 程序员 后端

Log4j使用指南,java入门视频教程

Java 程序员 后端

Mybatis Generator最完整配置详解,Java面试

Java 程序员 后端

kubebuilder实战之八:知识点小记,java面试具体场景的解决方案

Java 程序员 后端

Linux系统:第十一章:常用命令,华为java面试面经

Java 程序员 后端

Maven的核心概念,java面试高频知识点

Java 程序员 后端

Mybatis 传参的各种姿势,看这一篇就足够,java使用教程下载

Java 程序员 后端

Linux系统:第十章:服务器环境搭建,附Java面经

Java 程序员 后端

Myabtis源码分析六-代理对象Mapper的创建流程分析,死锁全详解,一文带你搞定

Java 程序员 后端

MyBatis的jdbcType和javaType详解,spring框架入门教程

Java 程序员 后端

KubeVela + KEDA:为应用带来,kafka入门

Java 程序员 后端

Linux上安装Mycat和配置连接MySQL 8,三年经验月薪50k我是怎么做到的

Java 程序员 后端

MongoDB :第六章:Java程序操作MongoDB,mysql复合索引面试题

Java 程序员 后端

通过Jinq简化数据库查询_Java_Abraham Marín Pérez_InfoQ精选文章