使用Java流查询数据库

在本文中,您将学习如何编写纯Java应用程序,这些应用程序能够处理现有数据库中的数据,而无需编写单行SQL(或类似的语言,例如HQL),也无需花费数小时将所有内容放在一起。 准备好应用程序之后,您将通过仅添加两行代码来学习如何使用JVM内加速将延迟性能提高1000倍以上。

在本文中,我们将使用Speedment,它是一个Java流ORM,可以直接从数据库模式生成代码,并且可以自动将Java Streams直接呈现为SQL,从而使您可以用纯Java编写代码。

您还将发现,通过直接在RAM中运行流的JVM内存技术可以显着提高数据访问性能。

示例数据库

我们将使用来自MySQL的示例数据库Sakila。 它具有称为电影,演员,类别等的表格,可以在此处免费下载。

步骤1:连接到数据库

我们将开始使用可以在此处找到的Speedment Initializer配置pom.xml文件。 按“下载”,您将获得带有自动生成的Main.java文件的项目文件夹。

查询数据库

接下来,解压缩项目文件夹的zip文件,打开命令行,转到解压缩的文件夹(pom.xml文件所在的文件夹)

查询数据库

然后,输入以下命令:

mvn speedment:tool

这将启动Speedment工具并提示您输入许可证密钥。 选择“开始免费”,您将自动免费获得许可证。 现在,您可以连接到数据库并开始使用:

查询数据库

步骤2:产生程式码

一旦从数据库中加载了模式数据,就可以通过按下“ Generate”按钮来生成完整的Java域模型。

查询数据库

这只需要一两秒钟。

步骤3:编写应用程序代码

与步骤2中的域模型一起,自动生成了Speedment实例的构建器。 打开Main.java文件,并使用以下代码段替换main()方法中的代码:

SakilaApplication app = new SakilaApplicationBuilder().withPassword("sakila-password") // Replace with your own password.build();

接下来,我们将编写一个可以打印所有电影的应用程序。 诚然,这是一个很小的应用程序,但是我们将在本文中对其进行改进。

// Obtains a FilmManager that allows us to
// work with the "film" table
FilmManager films = app.getOrThrow(FilmManager.class);// Create a stream of all films and print
// each and every film
films.stream().forEach(System.out::println);

这不是很简单吗?

运行时,Java流将在后台自动呈现为SQL。 为了真正看到呈现的SQL代码,请修改我们的应用程序构建器并启用使用
STREAM日志类型:

SakilaApplication app = new SakilaApplicationBuilder().withPassword("sakila-password").withLogging(ApplicationBuilder.LogType.STREAM).build();

这是运行应用程序时SQL代码的外观:

SELECT `film_id`,`title`,`description`,`release_year`, `language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update`FROM`sakila`.`film`, 
values:[]

根据您选择的数据库类型(例如MySQL,MariaDB,PostgreSQL,Oracle,MS SQL Server,DB2,AS400等),呈现的SQL代码可能有所不同。 这些变化是自动的。

上面的代码将产生以下输出(为简洁起见,以下简称):

FilmImpl { filmId = 1, title = ACADEMY DINOSAUR, …, length = 86, ... }
FilmImpl { filmId = 2, title = ACE GOLDFINGER, ..., length = 48, ...}
FilmImpl { filmId = 3, title = ADAPTATION HOLES, ..., length = 50, ...}
...

步骤4:使用筛选器

Speedment流支持所有Stream操作,包括过滤器。 假设我们只想过滤那些长于60分钟的电影。 这可以通过将以下代码行添加到我们的应用程序中来完成:

films.stream().filter(Film.LENGTH.greaterThan(60)) .forEach(System.out::println);

呈现的SQL:

SELECT `film_id`,`title`,`description`,`release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update` 
FROM `sakila`.`film` 
WHERE (`length` > ?),values:[60]

产生的输出:

FilmImpl { filmId = 1, title = ACADEMY DINOSAUR, ..., length = 86, ... }
FilmImpl { filmId = 4, title = AFFAIR PREJUDICE, ..., length = 117, ...}
FilmImpl { filmId = 5, title = AFRICAN EGG, ... length = 130, ...}

过滤器可以组合以创建更复杂的表达式,如下所示:

films.stream().filter(Film.LENGTH.greaterThan(60).or(Film.LENGTH.lessThan(30))).forEach(System.out::println);

这将返回所有短于30分钟或长于1小时的电影。 检查您的日志文件,您还将看到此Stream也呈现为SQL。

步骤5:定义元素的顺序

默认情况下,元素在流中出现的顺序是不确定的。 要定义特定的订单,您可以应用
对这样的流sorted()操作:

films.stream().filter(Film.LENGTH.greaterThan(60)).sorted(Film.TITLE).forEach(System.out::println);

呈现的SQL:

SELECT `film_id`,`title`,`description`,`release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update` 
FROM `sakila`.`film` 
WHERE (`length` > ?) 
ORDER BY `length` ASC,
values:[60]

产生的输出:

FilmImpl { filmId = 77, title = BIRDS PERDITION,..., length = 61,...}
FilmImpl { filmId = 106, title = BULWORTH COMMANDMENTS,..., length = 61,}
FilmImpl { filmId = 114, title = CAMELOT VACATION,..., length = 61,..}
...

您还可以组成多个排序器来定义主要顺序,次要顺序等。

films.stream().filter(Film.LENGTH.greaterThan(60)).sorted(Film.LENGTH.thenComparing(Film.TITLE.reversed())).forEach(System.out::println);

这将按LENGTH顺序(升序)然后按TITLE顺序(降序)对影片元素进行排序。 您可以组成任意数量的字段。

注意:如果要按升序组成两个或多个字段,则应使用该字段的方法
.comparator() 。 即
sorted(Film.LENGTH.thenComparing(Film.TITLE.comparator()))而不是 sorted(Film.LENGTH.thenComparing(Film.TITLE))

步骤6:分页并避免大对象块

通常,人们希望分页结果以避免使用不必要的大对象块。 假设我们希望每页看到50个元素,我们可以编写以下通用方法:

private static final int PAGE_SIZE = 50;public static <T> Stream<T> page(Manager<T> manager,Predicate<? super T> predicate,Comparator<? super T> comparator,int pageNo
) {return manager.stream().filter(predicate).sorted(comparator).skip(pageNo * PAGE_SIZE).limit(PAGE_SIZE);
}

此实用程序方法可以使用ANY过滤器来分页ANY表,并按ANY顺序对其进行排序。

例如,调用:

page(films, Film.LENGTH.greaterThan(60), Film.TITLE, 3)

将返回长度超过60分钟的电影流,并按标题显示第三页(即跳过150部电影并显示以下50部电影)。

呈现的SQL:

SELECT `film_id`,`title`,`description`,`release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update` 
FROM `sakila`.`film` 
WHERE(`length` > ?) 
ORDER BY`title` ASC 
LIMIT ? OFFSET ?,
values:[60, 50, 150]

产生的输出:

FilmImpl { filmId = 165, title = COLDBLOODED DARLING, ... length = 70,...}
FilmImpl { filmId = 166, title = COLOR PHILADELPHIA, ..., length = 149... }
FilmImpl { filmId = 167, title = COMA HEAD, ... length = 109,...}
...

同样,如果我们使用其他数据库类型,则SQL代码将略有不同。

步骤7:JVM中的内存加速

由于在初始化程序中使用了标准配置,因此在pom.xml文件中启用了In-JVM内存加速。 要在应用程序中激活加速,只需修改初始化代码,如下所示:

SakilaApplication app = new SakilaApplicationBuilder().withPassword("sakila-password").withBundle(InMemoryBundle.class).build();// Load data from the database into an in-memory snapshotapp.getOrThrow(DataStoreComponent.class).load();

现在,表流将直接从RAM提供,而不是呈现SQL查询。 内存索引也将加快筛选,排序和跳过。 内存中表和索引都存储在堆外,因此它们不会增加垃圾回收的复杂性。

在我的笔记本电脑(Mac Book Pro,15英寸,2015年中,16 GB,i7 2.2 GHz)上,对于我计算与过滤器匹配的电影和经过分类的电影流,与对在本地计算机上运行的MySQL数据库(版本5.7.16)的标准安装。

摘要

在本文中,您了解了使用纯Java流查询现有数据库有多么容易。 您还了解了如何使用JVM内存流技术加快对数据的访问。 Sakila数据库和Speedment均可免费下载和使用,请自己尝试。

翻译自: https://www.javacodegeeks.com/2018/09/query-databases-using-java-streams.html

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

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

相关文章

2017计算机信息技术,2017年一级计算机信息技术及应用考试试题级答案[权威资料]...

2017年一级计算机信息技术及应用考试试题级答案 本文档格式为WORD,感谢你的阅读。最新最全的 学术论文 期刊文献 年终总结 年终报告 工作总结 个人总结 述职报告 实习报告 单位总结 演讲稿2017年一级计算机信息技术及应用考试试题级答案一、基础知识题(共45分&#xff0c;每题1…

恐鬼症不显示服务器区域,恐鬼症 steam版【简体中文】【4.34GB】

游戏介绍《恐鬼症(Phasmophobia)》是一款玩法十分精彩的冒险解谜类游戏&#xff0c;这款游戏支持4人联机对战&#xff0c;共同寻找隐藏的秘密&#xff0c;游戏的过程比较惊悚&#xff0c;需要玩家拥有强大的心里承受能力&#xff0c;气氛和渲染都十分的优质&#xff0c;游戏由K…

ajax默认什么方法,ajax设置默认值ajaxSetup()方法

$(function(){//设置全局 jQuery Ajax全局参数$.ajaxSetup({type:"POST",async:false,cache:false,dataType:"JSON",error:function(jqXHR,textStatus,errorThrown){switch(jqXHR.status){case(500):alert(服务器系统内部错误);break;case(401):alert(未登…

android实现评论列表_【Android视图效果】分组列表实现吸顶效果

效果图效果图分析先来分析一下&#xff0c;可以看到这是一个按月份分组的2行图片列表&#xff0c;列表顶部一个悬浮栏&#xff0c;会随着列表滑动而刷新&#xff0c;点击顶部栏&#xff0c;弹出了一个筛选框。思路1.列表部分可以用RecyclerViewGridLayoutManager&#xff0c;月…

用ajax写无限循环,ajax无限循环

// 猜你喜欢的无限加载(function(){var content document.getElementsByClassName("content")[0];var footer document.getElementsByTagName("footer")[0];var winh window.innerHeight - footer.offsetHeight;var ul document.getElementById("…

lr监控虚拟服务器,lr监控服务器 教程

lr监控服务器 教程 内容精选换一换本教程旨在演示使用GDS(General Data Service)工具将远端服务器上的数据导入GaussDB(DWS)中的办法&#xff0c;帮助您学习如何通过GDS进行数据导入的方法。在本教程中&#xff0c;您将&#xff1a;生成本教程需要使用的CSV格式的数据源文件。将…

vc mysql 图片_VC连接MySQL

一、MySQL的安装可以考虑安装mysql-5.0.41-win32(可到http://www.newhua.com/soft/3573.htm处下载)&#xff0c;当然你有更新的版本更好&#xff0c;注意选择“完全安装”(只有这样才会安装VC编译时需要的头文件等)。安装后期会进行服务器配置&#xff0c;你可以设置你的服务器…

魔兽巨龙追猎者服务器微信群,魔兽世界:难怪现在“龙脊”价格低,掉落率提升,群里一天出几个...

祥子哥最近几天一直在练猎人号&#xff0c;目前已经67级了&#xff0c;再过两三天差不多就能满级了。知道祥子哥为什么练猎人吗&#xff1f;不全是因为猎人伤害高玩着爽&#xff0c;还有另一个原因&#xff0c;那就是“龙脊奖章”现在价格很便宜&#xff0c;祥子哥使把劲应该能…

mysql group原理_MySQL Group By 实现原理分析

【IT168 专稿】由于 GROUP BY 实际上也同样会进行排序操作&#xff0c;而且与 ORDER BY 相比&#xff0c;GROUP BY 主要只是多了排序之后的分组操作。当然&#xff0c;如果在分组的时候还使用了其他的一些聚合函数&#xff0c;那么还需要一些聚合函数的计算。所以&#xff0c;在…

使用AWS Lambda的CloudWatch事件通知

CloudWatchEvents的主要用例是跟踪整个AWS基础架构中的更改。 当前&#xff0c;它支持在Auto Scaling组&#xff0c;EC2&#xff0c;EBS和其他各种事件中发出的事件。 为了对这些事件进行有意义的处理&#xff0c;我们需要一种消耗它们的方法。 AWS使用术语“ targets来指代任何…

r语言 中断r的输入_R语言_004数据输入

现实的情况是&#xff0c;我们大部分遇到的都是表格数据&#xff0c;在R语言里面叫数据框&#xff0c;数据来源一般不可能我们自己在程序开始前手动录入&#xff0c;正常的逻辑是从外面读取现成的数据&#xff0c;再预处理、建模什么的。根据经验&#xff0c;现在的数据来源主要…

我的机器人现在无处可去。 无家可归。 无服务器。

我通常会关注各种网站-有关最新出版物&#xff0c;热门新优惠&#xff0c;限时游戏和竞赛等。 其中大多数不提供“干净”的通知系统&#xff0c;例如RSS feed。 因此&#xff0c;我经常不得不刮擦他们HTML才能达到我所需要的。 这意味着我经常需要运行一些自定义的字符串操作…

dubbo 消费者也要暴露端口吗_一文详细解读 Dubbo 中的 http 协议

(给ImportNew加星标&#xff0c;提高Java技能)转自&#xff1a;Kirito的技术分享&#xff0c;作者&#xff1a;kiritomoe太阳红彤彤&#xff0c;花儿五颜六色&#xff0c;各位读者朋友好&#xff0c;又来到了分享 Dubbo 知识点的时候了。说到 Dubbo 框架支持的协议&#xff0c;…

非一致性访存系统_Hibernate事实:访存策略的重要性

非一致性访存系统在使用ORM工具时&#xff0c;每个人都承认数据库设计和实体到表映射的重要性。 这些方面引起了很多关注&#xff0c;而诸如获取策略之类的事情可能只是推迟了。 我认为&#xff0c;不应将实体获取策略与实体映射设计分开&#xff0c;因为除非经过适当设计&…

应用新的JDK 11字符串方法

在“ 使用JDK 11的Java字符串上的新方法 ”和“ String&#xff03;repeat即将加入Java&#xff1f; ”&#xff0c;我讨论了JDK 11引入Java String的六个新方法。 可用的早期访问JDK 11构建已经包含了这些新方法&#xff0c;在这篇文章中&#xff0c;我将使用其中的一种早期访…

为什么需要切换到在线签署文档和合同

嘿&#xff0c;怪胎&#xff0c; 今天&#xff0c;我们为您带来一些不同。 无论您是开发人员&#xff0c;经理还是设计师&#xff0c;这都会提高您的生产力和效率。 对于公司和个人而言&#xff0c;良好地管理文书工作是强大基础的最重要部分之一。 将工作流程从纸质转移到数…

github怎么自动更新被人更新过的项目_GitHub 的这 8 个实用技巧,95%的人不知道...

知道的越多&#xff0c;不知道的就越多&#xff0c;业余的像一棵小草&#xff01;编辑&#xff1a;业余草来源&#xff1a;https://www.xttblog.com/?p49881、一秒钟把Github项目变成前端网站GitHub Pages大家可能都知道&#xff0c;常用的做法&#xff0c;是建立一个gh-pages…

java 注解 属性 类型_收藏!你一定要知道的Java8中的注解

全文共3002字&#xff0c;预计学习时长6分钟海中有大量的注解!JavaSE 1.5中首次引入了注解。Java注解的目的是允许程序员编写关于其程序的元数据。在OracleDocs中&#xff0c;注解的定义是:“注解是元数据的一种形式&#xff0c;它提供的数据与程序本身无关。”注解可以在代码的…

camel 多个 to_具有多个查询参数的Camel CXF服务

camel 多个 to出色的Apache Camel团队忙于解决查询中多个参数的处理问题&#xff0c;这是一种解决方法。 希望本文将在下一版本的Camel中不再使用。 &#xff08;目前&#xff0c;我使用2.7.5&#xff09; 问题 大于1的查询参数作为null值传递给Camel-CXF服务。 假设网址中有四…

select * from where 三个条件_VBA学习笔记70: Select语句基础

学习资源:《Excel VBA从入门到进阶》第72集 by兰色幻想 这节课来详细讲解Select语句。 Select 字段 from 表 where 条件 例:从sheet1中筛选全部数据。 * 表示全部字符,无条件可以省略where。 Select * from [sheet1$] 如果是对表中特定单元格区域进行查找,可以在[sheet1$]的…