Java 8 Friday:不再需要ORM

在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。

Java 8星期五

每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他好东西。 您可以在GitHub上找到源代码 。

不再需要ORM

在过去的十年中,关于ORM(对象关系映射)的有用性的争论一直在进行。 尽管许多人会同意Hibernate和JPA很好地解决了许多问题(大多数情况是复杂对象图的持久性),但其他人可能会认为, 映射复杂性对于以数据为中心的应用程序来说大多数是过分的 。

JPA通过在接收目标类型上使用硬连线的注释建立标准化的声明性映射规则来解决映射问题。 我们声称,许多以数据为中心的问题不应仅受这些注释的狭窄范围的限制,而应以更加实用的方式解决。 Java 8和新的Streams API最终使我们能够以非常简洁的方式执行此操作!

让我们从一个简单的示例开始,在该示例中,我们使用H2的INFORMATION_SCHEMA收集所有表及其列。 我们将要生成一个Map<String, List<String>>类型的临时数据结构来包含此信息。 为了简化SQL交互,我们将使用jOOQ (与往常一样,此博客上的内容令人震惊)。 这是我们准备的方法:

public static void main(String[] args)
throws Exception {Class.forName("org.h2.Driver");try (Connection c = getConnection("jdbc:h2:~/sql-goodies-with-mapping", "sa", "")) {// This SQL statement produces all table// names and column names in the H2 schemaString sql ="select table_name, column_name " +"from information_schema.columns " +"order by " +"table_catalog, " +"table_schema, " +"table_name, " +"ordinal_position";// This is jOOQ's way of executing the above// statement. Result implements List, which// makes subsequent steps much easierResult<Record> result =DSL.using(c).fetch(sql)}
}

现在我们已经设置了该查询,让我们看看如何从jOOQ Result中生成Map<String, List<String>>

DSL.using(c).fetch(sql).stream().collect(groupingBy(r -> r.getValue("TABLE_NAME"),mapping(r -> r.getValue("COLUMN_NAME"),toList()))).forEach((table, columns) -> System.out.println(table + ": " + columns));

上面的示例产生以下输出:

FUNCTION_COLUMNS: [ALIAS_CATALOG, ALIAS_SCHEMA, ...]
CONSTANTS: [CONSTANT_CATALOG, CONSTANT_SCHEMA, ...]
SEQUENCES: [SEQUENCE_CATALOG, SEQUENCE_SCHEMA, ...]

它是如何工作的? 让我们逐步进行

DSL.using(c).fetch(sql)// Here, we transform a List into a Stream.stream()// We're collecting Stream elements into a new
// collection type.collect(// The Collector is a grouping operation, producing
// a MapgroupingBy(// The grouping operation's group key is defined by
// the jOOQ Record's TABLE_NAME valuer -> r.getValue("TABLE_NAME"),// The grouping operation's group value is generated
// by this mapping expression...mapping(// ... which is essentially mapping each grouped
// jOOQ Record to the Record's COLUMN_NAME valuer -> r.getValue("COLUMN_NAME"),// ... and then collecting all those values into a
// java.util.List. WhewtoList())))// Once we have this List<String, List<String>> we
// can simply consume it with the following Consumer
// lambda expression.forEach((table, columns) -> System.out.println(table + ": " + columns));

得到它了? 第一次玩这些东西时,肯定有些棘手。 起初,新类​​型,泛型泛型,lambda表达式的组合可能会有些混乱。 最好的办法就是简单地练习这些东西,直到您掌握了它。 毕竟,与以前的Java Collections API相比,整个Streams API确实是一场革命。

好消息是:此API是最终的,并将保留。 练习每一分钟都是对自己未来的投资。

请注意,以上程序使用了以下静态导入:

import static java.util.stream.Collectors.*;

还要注意,不再像数据库中那样对输出进行排序。 这是因为groupingBy收集器返回java.util.HashMap 。 在我们的例子中,我们可能更喜欢将东西收集到java.util.LinkedHashMap ,该对象保留插入/收集的顺序:

DSL.using(c).fetch(sql).stream().collect(groupingBy(r -> r.getValue("TABLE_NAME"),// Add this Supplier to the groupingBy// method callLinkedHashMap::new,mapping(r -> r.getValue("COLUMN_NAME"),toList()))).forEach(...);

我们可以继续使用其他转换结果的方法。 想象一下,我们想根据上述模式生成简单的DDL。 非常简单 首先,我们需要选择列的数据类型。 我们将其简单地添加到我们的SQL查询中:

String sql ="select " +"table_name, " +"column_name, " +"type_name " + // Add the column type"from information_schema.columns " +"order by " +"table_catalog, " +"table_schema, " +"table_name, " +"ordinal_position";

我还为示例引入了一个新的本地类,以包装名称和类型属性:

class Column {final String name;final String type;Column(String name, String type) {this.name = name;this.type = type;}
}

现在,让我们看看如何更改Streams API方法调用:

result.stream().collect(groupingBy(r -> r.getValue("TABLE_NAME"),LinkedHashMap::new,mapping(// We now collect this new wrapper type// instead of just the COLUMN_NAMEr -> new Column(r.getValue("COLUMN_NAME", String.class),r.getValue("TYPE_NAME", String.class)),toList()))).forEach((table, columns) -> {// Just emit a CREATE TABLE statementSystem.out.println("CREATE TABLE " + table + " (");// Map each "Column" type into a String// containing the column specification,// and join them using comma and// newline. Done!System.out.println(columns.stream().map(col -> "  " + col.name +" " + col.type).collect(Collectors.joining(",\n")));System.out.println(");");});

输出再好不过了!

CREATE TABLE CATALOGS(CATALOG_NAME VARCHAR
);
CREATE TABLE COLLATIONS(NAME VARCHAR,KEY VARCHAR
);
CREATE TABLE COLUMNS(TABLE_CATALOG VARCHAR,TABLE_SCHEMA VARCHAR,TABLE_NAME VARCHAR,COLUMN_NAME VARCHAR,ORDINAL_POSITION INTEGER,COLUMN_DEFAULT VARCHAR,IS_NULLABLE VARCHAR,DATA_TYPE INTEGER,CHARACTER_MAXIMUM_LENGTH INTEGER,CHARACTER_OCTET_LENGTH INTEGER,NUMERIC_PRECISION INTEGER,NUMERIC_PRECISION_RADIX INTEGER,NUMERIC_SCALE INTEGER,CHARACTER_SET_NAME VARCHAR,COLLATION_NAME VARCHAR,TYPE_NAME VARCHAR,NULLABLE INTEGER,IS_COMPUTED BOOLEAN,SELECTIVITY INTEGER,CHECK_CONSTRAINT VARCHAR,SEQUENCE_NAME VARCHAR,REMARKS VARCHAR,SOURCE_DATA_TYPE SMALLINT
);

ORM时代可能刚刚结束

这是一个强有力的声明。 ORM时代可能已经结束。 为什么? 因为使用函数表达式转换数据集是软件工程中最强大的概念之一。 函数式编程非常有表现力,也非常通用。 它是数据和数据流处理的核心。 我们的Java开发人员已经知道现有的功能语言。 例如,每个人以前都使用过SQL。 想一想。 使用SQL,您可以声明表源,将它们投影/转换为新的元组流,并将它们作为派生表提供给其他更高级的SQL语句或Java程序。

如果使用XML,则可以使用XSLT声明XML转换,并使用XProc pipelining将结果馈送到其他XML处理实体,例如另一个XSL样式表。

Java 8的Streams没什么。 使用SQL和Streams API是最强大的数据处理概念之一。 如果将jOOQ添加到堆栈,则可以从对数据库记录和查询API的类型安全访问中受益。 想象一下使用jOOQ的流畅API而不是使用SQL字符串编写上一条语句。

jooq-在Java中编写SQL的最佳方法

整个方法链可以是一个单一的流利数据转换链,如下所示:

DSL.using(c).select(COLUMNS.TABLE_NAME,COLUMNS.COLUMN_NAME,COLUMNS.TYPE_NAME).from(COLUMNS).orderBy(COLUMNS.TABLE_CATALOG,COLUMNS.TABLE_SCHEMA,COLUMNS.TABLE_NAME,COLUMNS.ORDINAL_POSITION).fetch()  // jOOQ ends here.stream() // Streams start here.collect(groupingBy(r -> r.getValue(COLUMNS.TABLE_NAME),LinkedHashMap::new,mapping(r -> new Column(r.getValue(COLUMNS.COLUMN_NAME),r.getValue(COLUMNS.TYPE_NAME)),toList()))).forEach((table, columns) -> {// Just emit a CREATE TABLE statementSystem.out.println("CREATE TABLE " + table + " (");// Map each "Column" type into a String// containing the column specification,// and join them using comma and// newline. Done!System.out.println(columns.stream().map(col -> "  " + col.name +" " + col.type).collect(Collectors.joining(",\n")));System.out.println(");");});

Java 8是未来,借助jOOQ,Java 8和Streams API,您可以编写功能强大的数据转换API。 希望我们让您像我们一样兴奋! 请继续关注此博客上更多精彩的Java 8内容。

翻译自: https://www.javacodegeeks.com/2014/04/java-8-friday-no-more-need-for-orms.html

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

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

相关文章

c 语言输出指针的值,C 语言指针

C 语言指针在本教程中&#xff0c;您将学习指针。什么是指针&#xff0c;如何使用它们以及在示例的帮助下使用它们时可能遇到的常见错误。指针是 C和C 编程的强大功能。在学习指针之前&#xff0c;让我们学习一下C语言编程中的地址。C 语言地址如果程序中有变量var&#xff0c…

Java EE CDI限定词:快速浏览

在上下文和依赖注入&#xff08;CDI&#xff09;中&#xff0c; 限定符是类型安全和松散耦合的主体。 为什么&#xff1f; 没有CDI&#xff0c;我们将以类似于下面的方式注入Java EE组件 注意&#xff1a;这实际上不会编译&#xff0c;只是假设的代码片段 例子1 例子2 上述…

Windows 系统光盘刻录教程-光盘怎样刻录?刻录数据光盘用轨道一次写入还是光盘一次写入?...

刻录光盘需要 DVD-RW 的光驱&#xff0c;并且光盘需要 DVD-R 的光盘用于刻录。刻录工具可以使用 https://cn.ultraiso.net/ 来进行刻录。选择软件目录 中 工具 &#xff0c;选择 刻录光盘映像 即可进行配置&#xff1a; 此时涉及到了光盘写入的方式的选择问题&#xff0c;在网上…

NTC3950-10K温度传感器

一、计算公式 补充&#xff1a; B3950 R10K T225度 查RT表&#xff0c;25度对应的是10K 电路&#xff1a;   热敏电阻与上拉电阻R813分压&#xff0c;获取温度与Vo电压的关系&#xff0c;在根据Vo折算出与MCU ADC的数值。 再将ADC代出Rt&#xff0c;即得到ADC与T的关系公式。…

二分搜索树的基本实现

基本操作的动画演示 插入&#xff08;略&#xff09; 搜索&#xff08;略&#xff09; 删除节点 代码 package com.yunche.datastructure;import java.util.LinkedList; import java.util.Queue;/*** ClassName: BST* Description: 二叉搜索树&#xff1a;每个节点的左子树的值…

d9900 修改ip 思科dcm_思科设备SSH登陆详细配置过程

思科设备SSH登陆详细配置过程我们用GNS3进行拓扑搭建。实验拓扑图如下&#xff1a;进行完基本配置之后开始配置SSH服务器(R2)1.首先验证设备是否支持SSHR2#show ip ssh能够识别这条命令就说明支持。2.配置IP域名。使用config# ip domain-name domain-name全局配置模式命令配置网…

java 把string转为keyevent_盘点现在Java强大第三方库(字符串操作),程序员都该知道!...

1.字符串与集合间的转化引用第三方库 Apache Commons Lang jre连接值得一提的自JDK1.8以后字符串集合转为字符串可以使用String类下的join()方法,但别的数据类型还是要依靠第三方库--对比JDK和第三库代码如下我自己是一名从事了多年开发的java老程序员&#xff0c;这段时间整理…

Redis安装文档

1.前置条件 前置条件&#xff1a;linux已经可以上网&#xff0c;参考&#xff1a;https://www.cnblogs.com/ZenoLiang/p/10201875.html 2.安装redis 2.1依赖包检查 1. yum install cpp -y 2. yum install binutils -y 3. yum install glibc-kernheaders -y 4. yum install…

我用Mono(1)

我在Mono 0.1就开始关注和试用Mono了。我印象最深的一次是&#xff0c;我在FreeBSD里编译好了Mono&#xff08;FreeBSD装在VPC里&#xff09;。我用了同样的算法写了一个CS文件和JAVA文件。然后在虚拟机的FreeBSD的Mono下编译运行&#xff0c;把Java文件在真实机器的Windows XP…

Java基本数据类型的传值

传递值&#xff1a; 说明&#xff1a;标题其实说法是错误的。Java中只有值传递&#xff0c;没有引用传递。 ... ... //定义了一个改变参数值的函数 public static void changeValue(int x) { x x *2; } ... ... //调用该函数 int num 5; System.out.println(num); change…

红楼梦人物分析系统c语言,Gephi分析红楼梦

前言上一周赶了好久的社会网络计算&#xff0c;貌似是第四周还是第五周的时候&#xff0c;那时候我们就把题目定下来了吧&#xff0c;然后一直拖着没有做。其中的原因多种多样 &#xff0c;其实也可以说没有什么原因&#xff0c;就是不想做而已&#xff0c;然后就假装忘记23333…

二、MyBatis-HelloWorld

环境准备 1.创建数据库表 create table tbl_employee (id int(11) primary key AUTO_INCREMENT comment "ID",last_name varchar(20) default null comment "姓名",email varchar(20) default null comment "邮件",gender varchar(1) default nu…

洪水同频率放大的方法_我们应该怎么选择放大器配件?

在市面上&#xff0c;手机信号放大器高达百种型号与品牌&#xff0c;每种手机信号放大器所需的配件也不相同&#xff0c;我们需要选择合适的配件&#xff0c;才能让手机信号放大器更稳定的运行。下面佛山红岸谷通讯教大家怎么选适合自己的手机信号放大器配件。主要有以下几点。…

斑能不能彻底去掉_用茶树精油祛痘时,千万不能做这5件事!!!

祛痘注意事项~用茶树精油祛痘时&#xff0c;千万不能做这5件事&#xff01;&#xff01;&#xff01;长痘痘虽然是令人很头疼的事&#xff0c;但是茶树精油祛痘、去痘印功效可谓是无敌的&#xff01;茶树精油是自然界中的抗菌大师&#xff0c;能净化皮肤、平衡皮肤油脂分泌&…

JAX-RS 2.0:自定义内容处理

我试图想到一个更好的标题&#xff0c;但未能拿出一个&#xff01; 请多多包涵……。 JAX-RS 2.0规范允许我们无缝地将JAXB对象编组到HTTP请求/响应主体/从HTTP请求/响应主体中解组。 简而言之&#xff0c;我们可以使用域对象&#xff0c;而不必担心基于JAX-RS的解决方案中的低…

Waymo在美国推出自动驾驶汽车共享服务

导读经过数月的测试和数百万英里的无人驾驶汽车技术开发&#xff0c;Waymo 正式在美国推出了具有商业性质的自动驾驶汽车的共享服务。该公司的 Waymo One 项目将为客户提供 24 小时自动驾驶汽车服务。最初&#xff0c;这项服务将仅限于菲尼克斯周边城市&#xff0c;包括坦佩 (T…

2019春第一次课程设计实验报告

一、实验项目名称&#xff1a; 飞机游戏简化的编写 二、实验项目功能描述&#xff1a; 这个实验主要是实现游戏的正常运行&#xff0c;实现控制飞机的移动功能&#xff0c;增加其实用度&#xff0c; 同时还实现发射子弹和出现敌机的操作&#xff0c;利用函数封装重构飞机游戏&a…

区别和联系_动机与主题的区别与联系

今天我算是彻底弄明白了动机与主题的区别与联系&#xff08;暴论&#xff09;。当前些天我开始尝试写简单的奏鸣曲时&#xff0c;主题是什么&#xff0c;这个问题卡住了我&#xff0c;因为之前写的练习曲都是基于简单动机的。所以我求助于维基百科。主题是什么&#xff1f;参考…

巴顿又吃回头草

巴顿是一名好车手&#xff0c;一个会给shumi以及kimi造成威胁的家伙&#xff0c;我并不在意他在哪个车队&#xff0c;只希望他跑得比kimi慢才好。from新浪&#xff1a;宛如平地一声雷&#xff0c;巴顿重返威廉姆斯的消息不仅让车迷感到错愕&#xff0c;英美车队的老板理查兹更是…

尝试将WCF映射到Java术语

通过写这篇文章&#xff0c;我冒着被.NET和Java社区拒绝的巨大风险。 试图解释Java术语WCF &#xff08;代表Windows Communication Foundation&#xff09;是什么。 从WCF到Java的映射并不是很简单。 我缺乏对WFC使用者应该了解的与服务通信类型的了解&#xff1a;请求/响应或…