Java 8 Friday:Java 8将彻底改变数据库访问

在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 对于Java 8系列 ,我们很荣幸主持Iu Ming-Yee Iu博士发表的非常相关的嘉宾帖子。

Iu Ming-Yee博士在EPFL获得了Java数据库查询博士学位。 他创建了开源项目Jinq,以演示一些支持Java中数据库查询的新技术。

我们的社论注释:

自从Erik Meijer将LINQ引入.NET生态系统以来,我们Java的人们一直在想是否可以拥有相同的东西。 之前,我们已经写过几次有关此主题的博客:

  • Java 8仍然需要LINQ吗? 还是比LINQ更好?
  • LINQ和Java
  • Java Streams Preview与.Net LINQ
  • Java是否将LINQ添加到JSR-341中的EL 3.0?
  • 什么时候用Java编写LINQ?

尽管Java生态系统中的大多数LINQesque API都以内部特定于域的语言(如jOOQ)运行 ,但有些人却尝试在字节码级别上解决集成问题,例如JaQu 。

JINQ通过Iu Ming-Yee Iu博士所说的符号执行来形式化运行时字节码转换。 我们发现这一点非常有趣,以至于我们不知道是否应该开始构建JINQ到jOOQ的JINQ提供程序,在该提供程序中Java 8 Streams API的表达能力可以与我们强大的SQL标准化和转换功能结合起来吗?

说服自己:

Java 8 Goodie:Java 8将彻底改变数据库访问

Java 8终于来了! 经过多年的等待,Java程序员最终将获得对Java函数式编程的支持。 功能编程支持有助于简化现有代码,同时为Java语言提供强大的新功能。 这些新功能将干扰的一个方面是程序员如何使用Java处理数据库。 功能编程支持为更简单但功能更强大的数据库API开辟了令人兴奋的新可能性。 Java 8将提供新的方法来访问与其他编程语言(例如C#的LINQ)竞争的数据库。

处理数据的功能方式

Java 8不仅为Java语言增加了功能支持,而且还通过使用数据的新功能方式扩展了Java集合类。 传统上,使用Java处理大量数据需要大量循环和迭代器。

例如,假设您有一个Customer对象的集合:

Collection<Customer> customers;

如果您只对来自比利时的客户感兴趣,则必须遍历所有客户并保存所需的客户。

Collection<Customer> belgians = new ArrayList<>();
for (Customer c : customers) {if (c.getCountry().equals("Belgium"))belgians.add(c);
}

这需要五行代码。 它的抽象性也很差。 如果您有1000万客户,并且希望通过使用两个线程并行过滤代码来加快代码处理速度,会发生什么情况? 您将不得不重写所有内容以使用期货和许多冗长的多线程代码。

使用Java 8,您可以在一行中编写相同的代码。 借助对函数式编程的支持,Java 8使您可以编写函数,说出您对哪些客户感兴趣(来自比利时的客户),然后使用该函数过滤集合。 Java 8有一个新的Streams API,可让您执行此操作。

customers.stream().filter(c -> c.getCountry().equals("Belgium")
);

Java 8版本的代码不仅更短,而且代码也更易于理解。 几乎没有样板。 该代码调用方法filter() ,因此很明显,该代码用于过滤客户。 您不必花时间尝试在循环中破译代码,以了解其对数据的处理方式。

如果要并行运行代码会发生什么? 您只需要使用其他类型的流。

customers.parallelStream().filter(c -> c.getCountry().equals("Belgium")
);

更令人兴奋的是,这种功能性的代码样式也适用于数据库!

使用数据库的功能方式

传统上,程序员需要使用特殊的数据库查询语言来访问数据库中的数据。 例如,下面是一些JDBC代码,用于查找比利时的所有客户:

PreparedStatement s = con.prepareStatement("SELECT * "+ "FROM Customer C "+ "WHERE C.Country = ? ");
s.setString(1, "Belgium");
ResultSet rs = s.executeQuery();

许多代码都是字符串形式的,编译器无法检查字符串,并且由于草率的编码可能导致安全问题。 还有很多样板代码,使得编写数据库访问代码非常繁琐。 jOOQ之类的工具通过提供可以使用特殊Java库编写的数据库查询语言来解决错误检查和安全性问题。 或者,您可以使用对象关系映射器之类的工具为常见的访问模式隐藏许多无聊的数据库代码,但是如果您需要编写非平凡的数据库查询,则仍然需要再次使用特殊的数据库查询语言。

使用Java 8,可以使用与Streams API相同的功能样式编写数据库查询。 例如, Jinq是一个开源项目,探讨了未来的数据库API如何利用功能编程。 这是使用Jinq编写的数据库查询:

customers.where(c -> c.getCountry().equals("Belgium")
);

该代码与使用Streams API的代码几乎相同。 实际上,Jinq的未来版本将使您可以直接使用Streams API编写查询。 运行代码时,Jinq会自动将代码转换为数据库查询,就像前面显示的JDBC查询一样。

因此,无需学习新的数据库查询语言,就可以编写高效的数据库查询。 您可以使用与Java集合相同的代码样式。 您也不需要特殊的Java编译器或虚拟机。 所有这些代码都使用普通的Java 8 JDK进行编译和运行。 如果您的代码中有错误,则编译器会发现它们并将其报告给您,就像普通的Java代码一样。

Jinq支持与SQL92一样复杂的查询。 支持选择,投影,联接和子查询。 将Java代码转换为数据库查询的算法在接受和转换何种代码方面也非常灵活。 例如,尽管Jinq很复杂,但将下面的代码转换为数据库查询没有问题。

customers.where( c -> c.getCountry().equals("Belgium") ).where( c -> {if (c.getSalary() < 100000)return c.getSalary() < c.getDebt();elsereturn c.getSalary() < 2 * c.getDebt();} );

如您所见,Java 8中的功能编程支持非常适合编写数据库查询。 查询是紧凑的,并且支持复杂的查询。

内部工作

但是,这一切如何运作? 普通的Java编译器如何将Java代码转换为数据库查询? Java 8有什么特别之处可以实现这一点?

支持这些新的功能样式数据库API的关键是一种字节码分析,称为符号执行。 尽管您的代码是由普通的Java编译器编译并在普通的Java虚拟机中运行的,但是Jinq能够在运行时分析已编译的Java代码并从中构造数据库查询。 在分析小功能时,符号执行效果最好,这在使用Java 8 Streams API时很常见。

理解此符号执行的工作原理的最简单方法是一个示例。 让我们研究一下Jinq如何将以下查询转换为SQL查询语言:

customers.where( c -> c.getCountry().equals("Belgium") )

最初, customers变量是一个代表此数据库查询的集合

SELECT *FROM Customers C

然后,调用where()方法,并将一个函数传递给它。 在这种where()方法中,Jinq打开函数的.class文件,并获取编译后的字节码供函数分析。 在此示例中,我们不使用实际的字节码,而只是使用一些简单的指令来表示函数的字节码:

  1. d = c.getCountry()
  2. e =“比利时”
  3. e = d.equals(e)
  4. 返回e

在这里,我们假设该函数已被Java编译器编译为四个指令。 这是Jinq在调用where()方法时看到的。 Jinq如何理解此代码?

Jinq通过执行代码来分析代码。 Jinq不会直接运行代码。 它“抽象地”运行代码。 Jinq在执行代码时不使用实变量和实值,而是使用符号来表示所有值。 这就是为什么将分析称为符号执行的原因

Jinq执行每条指令,并跟踪程序状态中所有副作用或代码更改的所有事物。 下图显示了Jinq使用符号执行来执行四行代码时发现的所有副作用。

符号执行示例

符号执行示例

在该图中,您可以看到在执行第一条指令之后,Jinq如何发现两个副作用:变量d发生了变化,并且调用了Customer.getCountry()方法。 在执行符号时,不会给变量d像“美国”或“丹麦”那样的真实值。 它被分配了c.getCountry()的符号值。

在象征性地执行了所有指令之后,Jinq修剪了副作用。 由于变量de是局部变量,因此在函数退出后对它们的任何更改都将被丢弃,因此可以忽略那些副作用。 Jinq还知道, Customer.getCountry()String.equals()不会修改任何变量或显示任何输出,因此也可以忽略这些方法调用。 由此,Jinq可以得出结论,执行该函数只会产生一种效果:它返回c.getCountry().equals("Belgium")

一旦Jinq理解了where()方法中传递给它的函数的功能后,它便可以将此知识与customers集合基础的数据库查询合并,以创建新的数据库查询。

生成数据库查询

生成数据库查询

这就是Jinq从您的代码生成数据库查询的方式。 使用符号执行意味着这种方法对于不同Java编译器输出的不同代码模式非常健壮。 如果Jinq遇到带有副作用的代码,而这些副作用是使用数据库查询无法模拟的,那么Jinq将保持您的代码不变。 由于所有内容都是使用常规Java代码编写的,因此Jinq可以直接直接运行该代码,您的代码将产生预期的结果。

这个简单的翻译示例应该使您了解查询翻译的工作方式。 您应该对这些算法可以从您的代码正确生成数据库查询充满信心。

美好的未来

我希望我对Java 8如何启用Java中使用数据库的新方式有所帮助。 Java 8中的功能性编程支持使您可以类似于编写用于Java集合的代码的方式来编写数据库代码。 希望现有数据库API不久将得到扩展,以支持这些查询样式。

  • 要使用这些新型查询的原型,您可以访问http://www.jinq.org

翻译自: https://www.javacodegeeks.com/2014/03/java-8-friday-java-8-will-revolutionize-database-access.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux文件权限管理

权限管理 1、权限解读 权限&#xff1a;用户针对文件是否有读、写、执行的权利。 权限划分&#xff1a;读&#xff08;Read&#xff09;、写&#xff08;Write&#xff09;、执行&#xff08;eXecute&#xff09; 权限针对用户的划分&#xff1a;主人&#xff08;User&#xff…

Sqoop数据迁移工具的使用

文章作者&#xff1a;foochane 原文链接&#xff1a;https://foochane.cn/article/2019063001.html Sqoop数据迁移工具的使用 sqoop简单介绍 sqoop数据到HDFS/HIVE sqoop数据到MySQL 1 sqoop简单介绍 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具。用…

java中io.nio.aio_Java中网络IO的实现方式-BIO、NIO、AIO

在网络编程中&#xff0c;接触到最多的就是利用Socket进行网络通信开发。在Java中主要是以下三种实现方式BIO、NIO、AIO。关于这三个概念的辨析以前一直都是好像懂&#xff0c;但是表达的不是很清楚&#xff0c;下面做个总结完全辨析清楚。1. BIO方式首先我用一个较为通俗的语言…

C++中this指针

由类生成对象时&#xff0c;对象中只保存私有数据。 因为由一个类生成的所有对象为其数据服务的方法都是相同的&#xff0c;因此&#xff0c;一个类中的方法是大家所共用的。 而这就牵扯到当对象A调用方法时&#xff0c;如何保证该方法操作的数据是对象A的数据。 #include<i…

jfinal java搭建_Eclipse快速搭建Jfinal web应用 (一)

JFinal简介JFinal 是基于 Java 语言的极速 WEB ORM 框架&#xff0c;其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率&#xff01;为您节约更多时间&#xff0c…

PHP后台处理jQuery Ajax跨域请求问题 — xx was not called解决办法

// 前台代码 $.ajax({url: http://www.ushark.net/home/save_trial_apply,dataType: jsonp,processData: false,data: $(.layui-layer-content #trialFormInfo).serialize(), }) .done(function(data) {layer.msg(申请成功); }) .fail(function(jqXHR, textStatus, errorThrown…

如何使用VisualVM监视服务器上的多个JVM

在上一篇文章中&#xff0c;我向您展示了如何使用单个管理员服务器和多个托管服务器启动WebLogic Server。 这些启动之后&#xff0c;您如何检查它们的健康状况&#xff1f; 您可以使用管理员的/ console网络应用。 但是&#xff0c;所有默认的Oracle / Open JDK 6附带的另一个…

排序算法 JavaScript

一、冒泡排序 算法介绍&#xff1a; 1.比较相邻的两个元素,如果前一个比后一个大&#xff0c;则交换位置。 2.第一轮把最大的元素放到了最后面。 3.由于每次排序最后一个都是最大的&#xff0c;所以之后按照步骤1排序最后一个元素不用比较。 function bubble_sort(arr){var swa…

[你必须知道的.NET] 第一回:恩怨情仇:is和as

发布日期&#xff1a;2007.4.7 作者&#xff1a;Anytao ©2007 Anytao.com 转贴请注明出处&#xff0c;留此信息。 本文将介绍以下内容&#xff1a; • 类型转换 • is/as操作符小议 1. 引言 类型安全是.NET设计之初重点考虑的内容之一&#xff0c;对于程序设计者来说&…

获取当前鼠标的位置以及组件的位置

总结&#xff1a; div如果要触发鼠标事件要加上css样式cusor:pointer。 更多专业前端知识&#xff0c;请上 【猿2048】www.mk2048.com

谷歌推大语言模型VideoPoet:文本图片皆可生成视频和音频

Google Research最近发布了一款名为VideoPoet的大型语言模型&#xff08;LLM&#xff09;&#xff0c;旨在解决当前视频生成领域的挑战。该领域近年来涌现出许多视频生成模型&#xff0c;但在生成连贯的大运动时仍存在瓶颈。现有领先模型要么生成较小的运动&#xff0c;要么在生…

PyCon大会Python主题演讲摘要

PyCon 是全国际最大的以 Python 编程言语 为主题的技能大会。大会由 Python 社区组织&#xff0c;每年举行一次。在大会上&#xff0c;来自国际各地的 Python 用户与中心开发者齐聚一堂&#xff0c;共同同享 Python 国际的新鲜事、Python 言语的应用案例、运用技巧等等内容。 I…

欢迎使用Java 8之前要重温的10个JDK 7功能

Java 8发布已经快一个月了&#xff0c;我敢肯定&#xff0c;大家都在探索JDK 8的新功能。但是&#xff0c;在您完全研究Java 8之前&#xff0c;是时候重新审视Java 7上引入的一些很棒的功能了。记住&#xff0c;Java 6并没有什么功能&#xff0c;它只与JVM的更改和性能有关&…

java版本号管理_微服务项目中如何管理依赖版本号?

本文是微服务项目代码组织形式三部曲中的第三篇&#xff0c;也是最后一篇&#xff0c;通过这三篇文章&#xff0c;相信大家对于如果组织微服务中的代码已经有了一个基本认知&#xff0c;前面两篇分别是&#xff1a;第三篇相对来说要简单一些&#xff0c;本来没打算写&#xff0…

对于刚开始使用该软件,应该在熟悉基本的markdown语法的基础上,再进行快捷键的使用!...

一级标题 # 空格 编写内容 二级标题 ## 空格 编写内容 有序内容 1.Tab 无序内容 -Tab 代码块 print("hello wrold") typora快捷键 ctrl1一级标题 添加图片 表格 CtrlT 姓名年龄职业谢国宏20IT文字加粗 24期的小伙伴们你们好 文字斜体 你好 又粗又斜 粗斜* 3**2 -- 幂…

struct和byte[]相互转换(用Marshal类实现)

转自[DotNet笔记]相当于序列化与反序列化&#xff0c;但是不用借助外部文件1、struct转换为byte[] 1staticbyte[] StructToBytes(objectstructObj) 2{ 3 int size Marshal.SizeOf(structObj); 4 IntPtr buffer Marshal.AllocHGlobal(size); 5 …

Get-CrmSetting返回Unable to connect to the remote server的解决办法

摘要: 微软动态CRM专家罗勇 &#xff0c;回复302或者20190125可方便获取本文&#xff0c;同时可以在第一间得到我发布的最新博文信息&#xff0c;follow me&#xff01;我的网站是 www.luoyong.me 。 在Dynamics 365部署管理器所在的服务器上执行Get-CrmSetting&#xff0c;最近…

java 二维数组奇数金字塔_二维数组:奇数阶魔方 | 新思维:C语言程序设计

幻方&#xff0c;有时又称魔方&#xff0c;由一组排放在正方形中的整数组成&#xff0c;其每行、每列以及两条对角线上的数之和均相等。通常幻方由从到的连续整数组成。Siamese方法(Kraitchik 1942年&#xff0c;pp. 148-149)是构造奇数阶幻方的一种方法&#xff0c;说明如下&a…

拷贝构造函数与赋值函数(运算符重载)(1)

拷贝构造函数拷贝构造函数在三种情况下会被使用1.使用对象来初始化对象时2.当函数的形参是对象时3.当函数的返回值为对象时 2,3情况的本质还是1 //Test1.h #include<iostream> using namespace std; class ST { private:int a;long b; public:ST(int a0, long b0):a(a),…

GOOGLE不让我访问啦?

GOOGLE不让我访问啦? 今天上GOOGLE出现了这么一个画面,可是我就是不知道我的电脑到底中了什么毒,平常我没上什么特殊的网站,也没下载什么软件,因为这电脑我只用来做些基本的开发和看看园子里的文章而已.真不知道是怎么一回事.posted on 2007-05-05 12:46 黄尚 阅读(...) 评论(…