orm java_Java 8 Friday:不再需要ORM

orm java

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

Java 8星期五

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

不再需要ORM

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

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

orm java

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

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

相关文章

工业交换机的端口号结构特征

假如按工业交换机的端口号构造来分&#xff0c;工业交换机大概可分成&#xff1a;固定不动端口号工业交换机和模块化设计工业交换机二种不一样的构造。实际上也有一种是二者兼具&#xff0c;那便是在出示基础固定不动端口号的基本以上再配置一定的拓展扩展槽或控制模块。今天&a…

工业以太网的冗余功能有哪些?

由于工业环境对工业控制网络可靠性能的超高要求&#xff0c;工业以太网的冗余功能应运而生。从快速生成树冗余(RSTP)、环网冗余&#xff08;RapidRing&#xff09;到主干冗余&#xff08;Trunking&#xff09;&#xff0c;都有各自不同的优势和特点&#xff0c;控制工程师们可以…

input发送a.jax_JAX-RS 2.0:自定义内容处理

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

工业以太网交换机出现温度过高如何处理?

工业交换机由于其良好的通信性能、超强的抗磁抗干扰性被应用在工业环境下。我们都知道工业环境是很恶劣的&#xff0c;加上工业交换机要连续不间断的工作&#xff0c;很容易造成工业交换机过热的现象&#xff01;因此除了产品本身采用宽温度范围的元器件之外&#xff0c;我们更…

如何将Java应用程序置于Apache HTTP服务器之后

在过去 &#xff0c;将Apache HTTP服务器置于Java应用程序服务器或Java应用程序本身的前面是很常见的事情。 其背后的原因非常简单&#xff0c;可以以简单的方式添加缓存&#xff0c;还可以添加负载平衡&#xff0c;并且在此静态内容之上可以由Apache HTTP提供服务&#xff0c…

工业以太网交换机的概念及其主要功能介绍

随着互联网技术的快速发展&#xff0c;工业以太网在工业的通信领域也在大展身手&#xff0c;工业以太网交换机作为重要的通信设备&#xff0c;在整个工业通信行业中有着极其重要的功能&#xff01;下面&#xff0c;飞畅科技的小编就来为大家详细介绍一下什么是工业以太网交换机…

Zigbee 电动智能窗帘系统 解决方案

随着社会经济结构、家庭人口结构以及信息技术的发展变化以及人类对家居环境的安全性、舒适性、效率性要求的提高&#xff0c;造成家居智能化的需求大大增加&#xff0c; 同时越来越多的家庭要求智能家居产品不仅要满足一些基本的需求&#xff0c;更要求智能家居系统在功能扩展、…

oracle utf8 varchar,Oracle中字符集的类型决定varchar2的字符长度

1.前几天往数据库表里面插入数据的报了一个这样的错误如下&#xff1a;SQL> insert into student values(中华人民共和,60);insert into student values(中华人民共和,60)*第 1 行出现错误:ORA-12899: 列 "SYSTEM"."STUDENT"."NAME" 的值太大…

为什么BAT这些大企业都喜欢用LoRa技术?

相信对于很多朋友来说LORA通讯协议还是比较陌生的&#xff0c;因为LORA这种通讯技术是在2016年开始才正式传入中国的。现在阿里、Google、腾讯等互联网巨头都已经加入了LORA联盟&#xff0c;最有意思的是亚马逊&#xff0c;它在今年西雅图举行的硬件大会上&#xff0c;发布了一…

蓝牙的原理,蓝牙耳机怎么连接手机

蓝牙技术是一种无线数据和语音通信的通信协议&#xff0c;它是一种基于低成本的近距离的无线连接&#xff0c;为固定和移动设备监理通信环境的一种近距离无线连接技术。 蓝牙的作用 蓝牙使今天的一些便携式移动设备和计算机是被能够不需要线路就能相互链接&#xff0c;并且可以…

物联网中的无线通信模块到底是什么

物联网市场的爆发式增长速度&#xff0c;离不开无线通信模块产品的强有力的拉动&#xff0c;无线通信模块也是物联网的核心&#xff0c;但是很多人只知道物联网却对于组成物联网的无线通信模块知之甚少&#xff0c;所以下面就让我们一起来了解一下&#xff0c;物联网中的无线通…

基于NB-IOT的智能烟感应用方案

据国家有关部门发布的2018年火灾数据统计&#xff0c;全国共发生火灾23.7万起&#xff0c;造成1407人死亡&#xff0c;伤798人。直接财产损失36.75亿元&#xff0c;其中居民住宅火灾10.7万起&#xff0c;超过全年火灾总数的45%&#xff0c;其原因与我国当前火灾预防基础设施建设…

带网管工业交换机跟不带网管交换机的差别

交换机是局域网的一种核心设备&#xff0c;可以自主工作的多个计算机系统连接在一起&#xff0c;实现局部的软硬件共享的网络。通常的交换机是利用第二层的MAC地址的进行工作的&#xff0c;所以一般的家庭交换机基本上都是二层交换机。交换机有带网管的也有不带网管的&#xff…

通讯模块板载天线设计方法

注&#xff1a;本文来自 成都亿佰特 蛇形板载天线是无线通讯模块应用最广泛的一种天线类型&#xff0c;应用在蓝牙、WiFi、ZigBee等对性能要求不高、但对空间要求比较高的领域。今天就让成都亿佰特小编给大家普及一下蛇形板载天线的相关知识吧~ 作为天线工程师&#xff0c;每…

物联网在水位监测中的应用

注&#xff1a;本文来自 成都亿佰特 基于E820-DTU(2I2-433L)和E90-DTU(433C30)的水位监测应用 水位资料与人类社会生活和生产关系密切。水利工程的规划、设计、施工和管理需要水位资料。桥梁、港口、航道、给排水等工程建设也需水位资料。防汛抗旱中&#xff0c;水位资料更为…

接入层工业交换机、汇聚层工业交换机与核心层工业交换机区别

了解工业交换机的人都知道&#xff0c;工业交换机被划分为接入层工业交换机、汇聚层工业交换机和核心层工业交换机&#xff0c;今天&#xff0c;飞畅科技的小编就来为大家详细说下这三种工业交换机&#xff0c;感兴趣的朋友就一起来看看吧&#xff01; 首先&#xff0c;核心层工…

E820-DTU与昆仑通态组态软件联机

随着工业自动化水平的迅速提高&#xff0c;计算机在工业领域的广泛应用&#xff0c;人们对工业自动化的要求越来越高&#xff0c;种类繁多的控制设备和过程监控装置在工业领域的应用&#xff0c;使得传统的工业控制软件已无法满足用户的各种需求。 在开发传统的工业控制软件时&…

BLE蓝牙和传统蓝牙的区别

在移动设备上使用的蓝牙协议大多都是4.0&#xff0c;而蓝牙的4.0又有两个分支&#xff0c;经典4.0蓝牙和BLE4.0蓝牙&#xff0c;经典4.0就是传统的3.0蓝牙升级而成&#xff0c;向下兼容。而BLE4.0蓝牙是一个新的分支&#xff0c;不向下兼容。相较于传统的蓝牙&#xff0c;BLE蓝…

什么是核心交换机?如何选择核心交换机?

在系统组网中&#xff0c;经常会提到接入交换机、汇聚交换机、核心交换机。通常&#xff0c;我们将网络中直接面向用户连接或访问网络的部分称为接入层&#xff0c;将位于接入层和核心层之间的部分称为分布层或汇聚层&#xff0c;而将网络主干部分称为核心层。那么什么是核心交…

5W-Lora电台的远距离传输优势

本文来自 成都亿佰特 无线数传电台作为一种通讯媒介&#xff0c;与光纤、微波、明线一样&#xff0c;有一定的适用范围&#xff1a;它提供某些特殊条件下专网中监控信号的实时、可靠的数据传输&#xff0c;具有成本低、安装维护方便、绕射能力强、组网结构灵活、覆盖范围远的特…