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字符串編寫上一條語句。
整個方法鏈可以是一個單一的流利數據轉換鏈,如下所示:
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
總結
以上是生活随笔為你收集整理的orm java_Java 8 Friday:不再需要ORM的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 12123您提交的申请信息不符合备案(符
- 下一篇: 备案办税人员信息填谁(备案办)