日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Java8徹底改變數(shù)據(jù)庫(kù)訪問(wèn)

Java 8終于到來(lái)了! 經(jīng)過(guò)幾年的等待, java程序員終于能在java中得到函數(shù)式編程的支持了. 函數(shù)式編程的支持能流程化現(xiàn)有的代碼并且為java提供強(qiáng)大的能力.在這些新特性中最矚目的是java程序員對(duì)數(shù)據(jù)庫(kù)的操作方式.函數(shù)式編程帶來(lái)了令人激動(dòng)的簡(jiǎn)便高效的數(shù)據(jù)庫(kù)API. Java 8 將會(huì)支持可與C#, LINQ等語(yǔ)言競(jìng)爭(zhēng)的新的數(shù)據(jù)庫(kù)訪問(wèn)方式.

創(chuàng)新互聯(lián)專(zhuān)注于南部企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),購(gòu)物商城網(wǎng)站建設(shè)。南部網(wǎng)站建設(shè)公司,為南部等地區(qū)提供建站服務(wù)。全流程按需規(guī)劃網(wǎng)站,專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)

處理數(shù)據(jù)的函數(shù)式方式

Java 8 不僅僅添加了函數(shù)式支持,它也通過(guò)新的函數(shù)式處理數(shù)據(jù)的方式擴(kuò)展了集合(Collection)類(lèi). 而通常情況下java處理大量數(shù)據(jù)時(shí)需要大量的循環(huán)和迭代器.

例如, 假設(shè)你有一個(gè)存儲(chǔ)客戶(hù)(Customer)對(duì)象的collection:

 
 
  1. Collection customers; 

如果你只對(duì)來(lái)自Belgium的客戶(hù)感興趣, 你將不得不迭代所有的customer對(duì)象并只保存你需要的.

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

這不僅花費(fèi)了5行代碼,而且它也不怎么抽象.假使你有1千萬(wàn)個(gè)對(duì)象時(shí)會(huì)怎樣呢?你會(huì)通過(guò)兩個(gè)線程并發(fā)過(guò)濾所有對(duì)象來(lái)提速么?那你將不得不使用大量危險(xiǎn)的多線程代碼來(lái)重寫(xiě)所有代碼.

而通過(guò)Java 8,僅僅只需要一行代碼就能實(shí)現(xiàn)相同的功能.通過(guò)對(duì)函數(shù)式編程的支持, Java 8 能讓你只寫(xiě)一個(gè)函數(shù)表明你對(duì)哪些客戶(hù)(對(duì)象)感興趣然后使用那個(gè)函數(shù)對(duì)集合做過(guò)濾就可以了. Java 8 的新 Steams API 支持你這樣做:

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

上面Java 8 版本的代碼不僅更短,而且更容易理解.它幾乎沒(méi)有什么 陳詞濫調(diào)(循環(huán)或迭代器等).代碼調(diào)用了filter()方法,那很明顯這段代碼是用來(lái)過(guò)濾客戶(hù)(對(duì)象)的.你不需要再把時(shí)間浪費(fèi)在解讀循環(huán)中的代碼來(lái)理解它在對(duì)它的數(shù)據(jù)做什么.

假使你想并發(fā)執(zhí)行這段代碼該怎么辦呢?你只需使用另一個(gè)類(lèi)型的stream

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

更另人激動(dòng)的是這種函數(shù)式風(fēng)格的代碼也同樣適用于數(shù)據(jù)庫(kù)

在數(shù)據(jù)庫(kù)上使用函數(shù)式方式

傳統(tǒng)上來(lái)說(shuō), 程序員需要用特殊數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)句去訪問(wèn)數(shù)據(jù)庫(kù)的數(shù)據(jù). 例如,下面就是用 JDBC 代碼去查找來(lái)自Belgium的客戶(hù):

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

大部分這些代碼都是字符串, 這樣會(huì)使編譯器不能發(fā)現(xiàn)錯(cuò)誤而且這草率的代碼會(huì)導(dǎo)致安全問(wèn)題. 還有這些大量的樣板代碼使得寫(xiě)數(shù)據(jù)訪問(wèn)代碼變得十分冗余. 一些工具例如 jOOQ ,通過(guò)使用特殊的java庫(kù)去提供數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言可以解決錯(cuò)誤檢查和安全問(wèn)題。 或者使用對(duì)象關(guān)系映射工具可以免去大量的無(wú)趣的代碼,可它們只能用在通用訪問(wèn)查詢(xún), 如果需要復(fù)雜的查詢(xún),還是需要用特殊的數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言。

使用Java 8,借助流式API就可以用函數(shù)式方式去查詢(xún)數(shù)據(jù)庫(kù)了。例如, Jinq 是一個(gè)開(kāi)源的項(xiàng)目,它探索怎樣的未來(lái)數(shù)據(jù)庫(kù)API可以令函數(shù)式編程成為可能。這里就是一個(gè)使用Jinq的數(shù)據(jù)庫(kù)查詢(xún):

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

這代碼幾乎跟跟使用流式API的代碼一樣. 事實(shí)上,未來(lái)的Jinq版本可以讓你用流式API直接寫(xiě)數(shù)據(jù)庫(kù)查詢(xún)。 當(dāng)代碼運(yùn)行的時(shí)候,Jinq將自動(dòng)翻譯成數(shù)據(jù)庫(kù)查詢(xún)代碼,正如之前JDBC查詢(xún)一樣。

這樣的話,就算沒(méi)有學(xué)過(guò)一些新的數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)言,你也可以寫(xiě)出有效率的數(shù)據(jù)庫(kù)查詢(xún)。你可以用同樣樣式的代碼用在java集合上。你也不需要特殊的java編譯器或者虛擬機(jī)。所有的代碼編譯和運(yùn)行在普通的java 8 JDK上。如果你的代碼有錯(cuò)誤,編譯器將找出它們并且報(bào)告給你,就像普通的java代碼。

Jinq 支持跟SQL92一樣的復(fù)雜查詢(xún). Selection(選擇), projection(投影), joins(連接), 和子查詢(xún) 它都支持。翻譯java代碼成數(shù)據(jù)庫(kù)查詢(xún)的算法是十分靈活的,只要是它能接受的,都能翻譯。例如,Jinq能夠翻譯下面的數(shù)據(jù)庫(kù)查詢(xún),盡管它很復(fù)雜。

 
 
  1. customers  
  2.     .where( c -> c.getCountry().equals("Belgium") )  
  3.     .where( c -> {  
  4.         if (c.getSalary() < 100000)  
  5.             return c.getSalary() < c.getDebt();  
  6.         else 
  7.             return c.getSalary() < 2 * c.getDebt();  
  8.         } );  

正如你看到的,java 8 的函數(shù)式編程非常適合數(shù)據(jù)庫(kù)查詢(xún)。而且查詢(xún)緊湊,甚至復(fù)雜的查詢(xún)也能夠勝任。

內(nèi)部運(yùn)作

但這都是如何工作的呢?怎么能讓普通的Java編譯器將Java代碼轉(zhuǎn)換成數(shù)據(jù)庫(kù)查詢(xún)?Java 8 有什么特別之處使這個(gè)成為可能?

支持這些函數(shù)性風(fēng)格的新的數(shù)據(jù)庫(kù)PI的關(guān)鍵是一種叫做“象征性執(zhí)行”的字節(jié)碼分析手段。雖然你的代碼是被一個(gè)普通的Java編譯器編譯的并運(yùn)行在一個(gè)普通的Java虛擬機(jī)中,但 Jinq 能夠在你被編譯的Java代碼運(yùn)行時(shí)進(jìn)行分析并從中構(gòu)建數(shù)據(jù)庫(kù)查詢(xún)。使用 Java 8 Streams API 時(shí),常會(huì)發(fā)現(xiàn)分析短小的函數(shù)時(shí),象征性執(zhí)行的工作效果***。

要了解這個(gè)象征性執(zhí)行是如何工作的,最簡(jiǎn)單的方法是用一個(gè)例子。讓我們檢查一下下面的查詢(xún)是如何被 Jinq 轉(zhuǎn)換為SQL查詢(xún)語(yǔ)言的:

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

初始時(shí), 變量 customers 是一個(gè)集合,其對(duì)應(yīng)的數(shù)據(jù)庫(kù)查詢(xún)是:

 
 
  1. SELECT *  
  2.   FROM Customers C  

然后,where() 方法被調(diào)用,一個(gè)函數(shù)被傳遞給它。在 where() 方法中,Jinq 打開(kāi)這個(gè)函數(shù)的 .class 文件,得到這個(gè)函數(shù)被編譯成的字節(jié)碼進(jìn)行分析。在這個(gè)例子中,不使用真正的字節(jié)碼,讓我們用一些簡(jiǎn)單的指令來(lái)代表這個(gè)函數(shù)的字節(jié)碼:

  1. d = c.getCountry()

  2. e = “Belgium”

  3. e = d.equals(e)

  4. return e

在這里,我們假設(shè)函數(shù)已被Java編譯器編譯成這四條指令。當(dāng)調(diào)用 where() 方法時(shí),Jinq 看到的就是這些。如何才能使Jinq理解這些代碼呢?

Jinq 通過(guò)執(zhí)行代碼來(lái)分析。但 Jinq 不直接運(yùn)行代碼。它是“抽象”地運(yùn)行代碼:不使用真實(shí)的變量和真實(shí)的值,Jinq 使用符號(hào)來(lái)表示執(zhí)行代碼時(shí)的所有值。這就是這個(gè)分析為什么被稱(chēng)為“象征性執(zhí)行”。

Jinq 執(zhí)行每條指令,并跟蹤所有的副作用或代碼在程序狀態(tài)時(shí)改變的所有東西。下面是一個(gè)圖表,顯示出 Jinq 用象征性執(zhí)行方式執(zhí)行這四行代碼時(shí)發(fā)現(xiàn)的所有副作用。

象征性執(zhí)行的例子

在圖中,你可以看到***條指令運(yùn)行后,Jinq 發(fā)現(xiàn)了兩個(gè)副作用:變量d已經(jīng)發(fā)生了變化,方法 Customer.getCountry() 被調(diào)用。由于是象征性執(zhí)行,變量d沒(méi)有給出一個(gè)真正的比如是“USA”或“Denmark”的值,它被分配為 c.getCountry() 的象征性的值。

在所有這些指令被象征性執(zhí)行之后,Jinq 對(duì)副作用作精簡(jiǎn)。由于變量 d 和 e 是局部變量,它們的任何變化在函數(shù)退出后都會(huì)被丟棄,所以這些副作用可以忽略不計(jì)。Jinq也知道 Customer.getCountry() and String.equals() 方法沒(méi)修改任何變量或顯示任何輸出,因此這些方法調(diào)用也可以被忽略。由此,Jinq 可以得出這樣的結(jié)論:執(zhí)行這個(gè)函數(shù)只會(huì)產(chǎn)生一個(gè)作用,它會(huì)返回 c.getCountry().equals("Belgium")。

一旦Jinq已明白在 where()方法中傳遞給它的函數(shù),它可以混合數(shù)據(jù)庫(kù)查詢(xún)方面的知識(shí),優(yōu)先于 customers 集合來(lái)創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)查詢(xún)。

生成數(shù)據(jù)庫(kù)查詢(xún)

這就是 Jinq 如何從你的代碼生成數(shù)據(jù)庫(kù)查詢(xún)的。象征性執(zhí)行的使用意味著,這種方法對(duì)于不同的Java編譯器輸出的不同的代碼模式都是相當(dāng)強(qiáng)大的。如果 Jinq 遇到的代碼有不能轉(zhuǎn)化為數(shù)據(jù)庫(kù)查詢(xún)的副作用,Jinq 將保持你的這些代碼不變。因?yàn)橐磺卸际怯谜5腏ava代碼寫(xiě)的,Jinq 可以直接運(yùn)行那些代碼,您的代碼將產(chǎn)生預(yù)期的結(jié)果。

這個(gè)簡(jiǎn)單的翻譯實(shí)例應(yīng)該讓你明白了怎樣查詢(xún)翻譯作品。你可以確信,這些算法可以正確地從你的代碼生成數(shù)據(jù)庫(kù)查詢(xún)。

美好前景

我希望我已經(jīng)讓你品嘗到了Java 8帶來(lái)的在Java中進(jìn)行數(shù)據(jù)庫(kù)工作的新方式。Java 8 支持的函數(shù)式編程允許你用和為Java集合編寫(xiě)代碼同樣的方式來(lái)為數(shù)據(jù)庫(kù)寫(xiě)代碼。希望不久現(xiàn)有的數(shù)據(jù)庫(kù)API都能被擴(kuò)展以支持這些類(lèi)型的查詢(xún)。

英文原文:Java 8 Friday: Java 8 Will Revolutionize Database Access

譯文鏈接:http://www.oschina.net/translate/java-8-friday-java-8-will-revolutionize-database-access


分享名稱(chēng):Java8徹底改變數(shù)據(jù)庫(kù)訪問(wèn)
轉(zhuǎn)載來(lái)于:http://m.5511xx.com/article/dheisee.html