程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 在Java法式中應用數據庫的新辦法

在Java法式中應用數據庫的新辦法

編輯:關於JAVA

在Java法式中應用數據庫的新辦法。本站提示廣大學習愛好者:(在Java法式中應用數據庫的新辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是在Java法式中應用數據庫的新辦法正文


 Java 8終究到來了! 經由幾年的期待, java法式員終究能在java中獲得函數式編程的支撐了. 函數式編程的支撐能流程化現有的代碼而且為java供給壯大的才能.在這些新特征中最注視的是java法式員對數據庫的操作方法.函數式編程帶來了使人沖動的輕便高效的數據庫API. Java 8 將會支撐可與像C#的LINQ等說話競爭的新的數據庫拜訪方法.
處置數據的函數式方法

Java 8 不只僅添加了函數式支撐,它也經由過程新的函數式處置數據的方法擴大了聚集(Collection)類. 而平日情形下java處置年夜量數據時須要年夜量的輪回和迭代器.


例如, 假定你有一個存儲客戶(Customer)對象的collection:
 

Collection<Customer> customers;

假如你只對來自Belgium的客戶感興致, 你將不能不迭代一切的customer對象並只保留你須要的.
 

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

這不只消費了5行代碼,並且它也不怎樣籠統.借使你有1萬萬個對象時會如何呢?你會經由過程兩個線程並發過濾一切對象來提速麼?那你將不能不應用年夜量風險的多線程代碼來重寫一切代碼.

而經由過程Java 8,僅僅只須要一行代碼就可以完成雷同的功效.經由過程對函數式編程的支撐, Java 8 能讓你只寫一個函數注解你對哪些客戶(對象)感興致然後應用誰人函數對聚集做過濾便可以了. Java 8 的新 Steams API 支撐你如許做:
 

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

下面Java 8 版本的代碼不只更短,並且更輕易懂得.它簡直沒有甚麼 老生常談(輪回或迭代器等).代碼挪用了filter()辦法,那很顯著這段代碼是用來過濾客戶(對象)的.你不須要再把時光糟蹋在解讀輪回中的代碼來懂得它在對它的數據做甚麼.

借使你想並發履行這段代碼該怎樣辦呢?你只需應用另外一個類型的stream
 

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

更另人沖動的是這類函數式作風的代碼也異樣實用於數據庫

在數據庫上應用函數式方法

傳統下去說, 法式員須要用特別數據庫查詢語句去拜訪數據庫的數據. 例如,上面就是用 JDBC 代碼去查找來自Belgium的客戶:
 

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

年夜部門這些代碼都是字符串, 如許會使編譯器不克不及發明毛病並且這輕率的代碼會招致平安成績. 還有這些年夜量的樣板代碼使得寫數據拜訪代碼變得非常冗余. 一些對象例如 jOOQ ,經由過程應用特別的java庫去供給數據庫查詢說話可以處理毛病檢討和平安成績。 或許應用對象關系映照對象可以避免去年夜量的無趣的代碼,可它們只能用在通用拜訪查詢, 假如須要龐雜的查詢,照樣須要用特別的數據庫查詢說話。

應用Java 8,借助流式API便可以用函數式方法去查詢數據庫了。例如, Jinq 是一個開源的項目,它摸索如何的將來數據庫API可以令函數式編程成為能夠。這裡就是一個應用Jinq的數據庫查詢:
 

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

這代碼簡直跟跟應用流式API的代碼一樣. 現實上,將來的Jinq版本可讓你用流式API直接寫數據庫查詢。 現代碼運轉的時刻,Jinq將主動翻譯成數據庫查詢代碼,正如之前JDBC查詢一樣。


如許的話,就算沒有學過一些新的數據庫查詢說話,你也能夠寫出有用率的數據庫查詢。你可以用異樣款式的代碼用在java聚集上。你也不須要特別的java編譯器或許虛擬機。一切的代碼編譯和運轉在通俗的java 8 JDK上。假如你的代碼有毛病,編譯器將找出它們而且申報給你,就像通俗的java代碼。

Jinq 支撐跟SQL92一樣的龐雜查詢. Selection(選擇), projection(投影), joins(銜接), 和子查詢 它都支撐。翻譯java代碼成數據庫查詢的算法是非常靈巧的,只需是它能接收的,都能翻譯。例如,Jinq可以或許翻譯上面的數據庫查詢,雖然它很龐雜。
 

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

正如你看到的,java 8 的函數式編程異常合適數據庫查詢。並且查詢緊湊,乃至龐雜的查詢也可以或許勝任。

外部運作

但這都是若何任務的呢?怎樣能讓通俗的Java編譯器將Java代碼轉換成數據庫查詢?Java 8 有甚麼特殊的地方使這個成為能夠?

支撐這些函數性作風的新的數據庫PI的症結是一種叫做“意味性履行”的字節碼剖析手腕。固然你的代碼是被一個通俗的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 文件,獲得這個函數被編譯成的字節碼停止剖析。在這個例子中,不應用真實的字節碼,讓我們用一些簡略的指令來代表這個函數的字節碼:

  d = c.getCountry()

  e = “Belgium”

  e = d.equals(e)

  return e

在這裡,我們假定函數已被Java編譯器編譯成這四條指令。當挪用 where() 辦法時,Jinq 看到的就是這些。若何能力使Jinq懂得這些代碼呢?

Jinq 經由過程履行代碼來剖析。但 Jinq 不直接運轉代碼。它是“籠統”地運轉代碼:不應用真實的變量和真實的值,Jinq 應用符號來表現履行代碼時的一切值。這就是這個剖析為何被稱為“意味性履行”。

Jinq 履行每條指令,並跟蹤一切的反作用或代碼在法式狀況時轉變的一切器械。上面是一個圖表,顯示出 Jinq 用意味性履行方法履行這四行代碼時發明的一切反作用。

意味性履行的例子

在圖中,你可以看到第一條指令運轉後,Jinq 發明了兩個反作用:變量d曾經產生了變更,辦法 Customer.getCountry() 被挪用。因為是意味性履行,變量d沒有給出一個真實的好比是“USA”或“Denmark”的值,它被分派為 c.getCountry() 的意味性的值。

在一切這些指令被意味性履行以後,Jinq 對反作用作精簡。因為變量 d 和 e 是部分變量,它們的任何變更在函數加入後都邑被拋棄,所以這些反作用可以疏忽不計。Jinq也曉得 Customer.getCountry() and String.equals() 辦法沒修正任何變量或顯示任何輸入,是以這些辦法挪用也能夠被疏忽。由此,Jinq 可以得出如許的結論:履行這個函數只會發生一個感化,它會前往 c.getCountry().equals("Belgium")。

一旦Jinq已明確在 where()辦法中傳遞給它的函數,它可以混雜數據庫查詢方面的常識,優先於 customers 聚集來創立一個新的數據庫查詢。

生成數據庫查詢


這就是 Jinq 若何從你的代碼生成數據庫查詢的。意味性履行的應用意味著,這類辦法關於分歧的Java編譯器輸入的分歧的代碼形式都是相當壯大的。假如 Jinq 碰到的代碼有不克不及轉化為數據庫查詢的反作用,Jinq 將堅持你的這些代碼不變。由於一切都是用正常的Java代碼寫的,Jinq 可以直接運轉那些代碼,您的代碼將發生預期的成果。

這個簡略的翻譯實例應當讓你明確了如何查詢翻譯作品。你可以確信,這些算法可以准確地從你的代碼生成數據庫查詢。
美妙遠景

我願望我曾經讓你品味到了Java 8帶來的在Java中停止數據庫任務的新方法。Java 8 支撐的函數式編程許可你用和為Java聚集編寫代碼異樣的方法來為數據庫寫代碼。願望不久現有的數據庫API都能被擴大以支撐這些類型的查詢。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved