溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java嵌入數(shù)據(jù)引擎從SQLite到SPL的應(yīng)用方法是什么

發(fā)布時(shí)間:2023-05-09 10:39:46 來(lái)源:億速云 閱讀:152 作者:iii 欄目:編程語(yǔ)言

今天小編給大家分享一下Java嵌入數(shù)據(jù)引擎從SQLite到SPL的應(yīng)用方法是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

SQLite適應(yīng)常規(guī)基本應(yīng)用場(chǎng)景

SQLite架構(gòu)簡(jiǎn)單,其核心雖然是C語(yǔ)言開(kāi)發(fā)的,但封裝得比較好,對(duì)外呈現(xiàn)為一個(gè)小巧的Jar包,能方便地集成在Java應(yīng)用中。SQLite提供了JDBC接口,可以被Java調(diào)用:

Connection connection = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement st = connection.createStatement();
st.execute("restore from d:/ex1");
ResultSet rs = st.executeQuery("SELECT * FROM orders");

SQLite提供了標(biāo)準(zhǔn)的SQL語(yǔ)法,常規(guī)的數(shù)據(jù)處理和計(jì)算都沒(méi)有問(wèn)題。特別地,SQLite已經(jīng)能支持窗口函數(shù),可以方便地實(shí)現(xiàn)很多組內(nèi)運(yùn)算,計(jì)算能力比其他內(nèi)嵌數(shù)據(jù)庫(kù)更強(qiáng)。

SELECT x, y, row_number() OVER (ORDER BY y) AS row_number FROM t0 ORDER BY x;
SELECT a, b, group_concat(b, '.') OVER ( ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS group_concat FROM t1;

SQLite面對(duì)復(fù)雜場(chǎng)景尚有不足

SQLite的優(yōu)點(diǎn)亮眼,但對(duì)于復(fù)雜應(yīng)用場(chǎng)景時(shí)還是有些缺點(diǎn)。

Java應(yīng)用可能處理的數(shù)據(jù)源多種多樣,比如csv文件、RDB、Excel、Restful,但SQLite只處理了簡(jiǎn)單情況,即對(duì)csv等文本文件提供了直接可用的命令行加載程序:

.import --csv --skip 1 --schema temp /Users/scudata/somedata.csv tab1

對(duì)于其他大部分?jǐn)?shù)據(jù)源,SQLite都沒(méi)有提供方便的接口,只能硬寫(xiě)代碼加載數(shù)據(jù),需要多次調(diào)用命令行,整個(gè)過(guò)程很繁瑣,時(shí)效性也差。

以加載RDB數(shù)據(jù)源為例,一般的做法是先用Java執(zhí)行命令行,把RDB庫(kù)表轉(zhuǎn)為csv;再用JDBC訪問(wèn)SQLite,創(chuàng)建表結(jié)構(gòu);之后用Java執(zhí)行命令行,將csv文件導(dǎo)入SQLite;最后為新表建索引,以提高性能。這個(gè)方法比較死板,如果想靈活定義表結(jié)構(gòu)和表名,或通過(guò)計(jì)算確定加載的數(shù)據(jù),代碼就更難寫(xiě)了。

類(lèi)似地,對(duì)于其他數(shù)據(jù)源,SQLite也不能直接加載,同樣要通過(guò)繁瑣地轉(zhuǎn)換過(guò)程才可以。

SQL接近自然語(yǔ)言,學(xué)習(xí)門(mén)檻低,容易實(shí)現(xiàn)簡(jiǎn)單的計(jì)算,但不擅長(zhǎng)復(fù)雜的計(jì)算,比如復(fù)雜的集合計(jì)算、有序計(jì)算、關(guān)聯(lián)計(jì)算、多步驟計(jì)算。SQLite采用SQL語(yǔ)句做計(jì)算,SQL優(yōu)點(diǎn)和缺點(diǎn)都會(huì)繼承下來(lái),勉強(qiáng)實(shí)現(xiàn)這些復(fù)雜計(jì)算的話,代碼會(huì)顯得繁瑣難懂。

比如,某只股票最長(zhǎng)的上漲天數(shù),SQL要這樣寫(xiě):

select max(continuousDays)-1
from (select count(*) continuousDays
from (select sum(changeSign) over(order by tradeDate) unRiseDays
from (select tradeDate,
case when price>lag(price) over(order by tradeDate) then 0 else 1 end changeSign from AAPL) )
group by unRiseDays)

這也不單是SQLite的難題,事實(shí)上,由于集合化不徹底、缺乏序號(hào)、缺乏對(duì)象引用等原因,其他SQL數(shù)據(jù)庫(kù)也不擅長(zhǎng)這些運(yùn)算。

業(yè)務(wù)邏輯由結(jié)構(gòu)化數(shù)據(jù)計(jì)算和流程控制組成,SQLite支持SQL,具有結(jié)構(gòu)化數(shù)據(jù)計(jì)算能力,但SQLite沒(méi)有提供存儲(chǔ)過(guò)程,不具備獨(dú)立的流程控制能力,也就不能實(shí)現(xiàn)一般的業(yè)務(wù)邏輯,通常要利用Java主程序的判斷和循環(huán)語(yǔ)句。由于Java沒(méi)有專(zhuān)業(yè)的結(jié)構(gòu)化數(shù)據(jù)對(duì)象來(lái)承載SQLite數(shù)據(jù)表和記錄,轉(zhuǎn)換過(guò)程麻煩,處理過(guò)程不暢,開(kāi)發(fā)效率不高。

前面提過(guò),SQLite內(nèi)核是C程序,雖然可以被集成到Java應(yīng)用中,但并不能和Java無(wú)縫集成,和Java主程序交換數(shù)據(jù)時(shí)要經(jīng)過(guò)耗時(shí)的轉(zhuǎn)換才能完成,在涉及數(shù)據(jù)量較大或交互頻繁時(shí)性能就會(huì)明顯不足。同樣因?yàn)閮?nèi)核是C程序,SQLite會(huì)在一定程度上破壞Java架構(gòu)的一致性和健壯性。

對(duì)于Java應(yīng)用來(lái)講,原生在JVM上的esProc SPL是更好的選擇。

SPL全面支持各種數(shù)據(jù)源

esProc SPL是JVM下開(kāi)源的嵌入數(shù)據(jù)引擎,架構(gòu)簡(jiǎn)單,可直接加載數(shù)據(jù)源,可以通過(guò)JDBC接口被Java集成調(diào)用,并方便地進(jìn)行后續(xù)計(jì)算。

SPL架構(gòu)簡(jiǎn)單,無(wú)須獨(dú)立服務(wù),只要引入SPL的Jar包,就可以部署在Java環(huán)境中。

直接加載數(shù)據(jù)源,代碼簡(jiǎn)短,過(guò)程簡(jiǎn)單,時(shí)效性強(qiáng)。比如加載Oracle:

A
1=connect("orcl")
2=A1.query@x("select OrderID,Client,SellerID,OrderDate,Amount from orders order by OrderID")
3>env(orders,A2)

對(duì)于SQLite擅長(zhǎng)加載的csv文件,SPL也可以直接加載,使用內(nèi)置函數(shù)而不是外部命令行,穩(wěn)定且效率高,代碼更簡(jiǎn)短:

=T("/Users/scudata/somedata.csv")

多種外部數(shù)據(jù)源。除了RDB和csv,SPL還直接支持txt\xls等文件,MongoDB、Hadoop、redis、ElasticSearch、Kafka、Cassandra等NoSQL,以及WebService XML、Restful Json等多層數(shù)據(jù)。比如,將HDSF里的文件加載到內(nèi)存:

A
1=hdfs_open(;"hdfs://192.168.0.8:9000")
2=hdfs_file(A1,"/user/Orders.csv":"GBK")
3=A2.cursor@t()
4=hdfs_close(A1)
5>env(orders,A4)

JDBC接口可以方便地集成。加載的數(shù)據(jù)量一般比較大,通常在應(yīng)用的初始階段運(yùn)行一次,只須將上面的加載過(guò)程存為SPL腳本文件,在Java中以存儲(chǔ)過(guò)程的形式引用腳本文件名:

Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn =DriverManager.getConnection("jdbc:esproc:local://");
CallableStatement statement = conn.prepareCall("{call init()}");
statement.execute();

SPL的計(jì)算能力更強(qiáng)大

SPL提供了豐富的計(jì)算函數(shù),可以輕松實(shí)現(xiàn)日常計(jì)算。SPL支持多種高級(jí)語(yǔ)法,大量的日期函數(shù)和字符串函數(shù),很多用SQL難以表達(dá)的計(jì)算,用SPL都可以輕松實(shí)現(xiàn),包括復(fù)雜的有序計(jì)算、集合計(jì)算、分步計(jì)算、關(guān)聯(lián)計(jì)算,以及帶流程控制的業(yè)務(wù)邏輯。

豐富的計(jì)算函數(shù)。SPL可以輕松實(shí)現(xiàn)各類(lèi)日常計(jì)算:


AB
1=Orders.find(arg_OrderIDList)//多鍵值查找
2=Orders.select(Amount>1000 && like(Client,\"*S*\"))//模糊查詢(xún)
3= Orders.sort(Client,-Amount)//排序
4= Orders.id(Client)//去重
5=join(Orders:O,SellerId; Employees:E,EId).new(O.OrderID, O.Client,O.Amount,E.Name,E.Gender,E.Dept)//關(guān)聯(lián)

標(biāo)準(zhǔn)SQL語(yǔ)法。SPL也提供了SQL-92標(biāo)準(zhǔn)的語(yǔ)法,比如分組匯總:

$select year(OrderDate) y,month(OrderDate) m, sum(Amount) s,count(1) c
from {Orders}
Where Amount>=? and Amount<? ;arg1,arg2

函數(shù)選項(xiàng)、層次參數(shù)等方便的語(yǔ)法。功能相似的函數(shù)可以共用一個(gè)函數(shù)名,只用函數(shù)選項(xiàng)區(qū)分差別,比SQL更加靈活方便。比如select函數(shù)的基本功能是過(guò)濾,如果只過(guò)濾出符合條件的第1條記錄,可使用選項(xiàng)@1:

T.select@1(Amount>1000)

二分法排序,即對(duì)有序數(shù)據(jù)用二分法進(jìn)行快速過(guò)濾,使用@b:

T.select@b(Amount>1000)

有序分組,即對(duì)分組字段有序的數(shù)據(jù),將相鄰且字段值相同的記錄分為一組,使用@b:

T.groups@b(Client;sum(Amount))

函數(shù)選項(xiàng)還可以組合搭配,比如:

Orders.select@1b(Amount>1000)

結(jié)構(gòu)化運(yùn)算函數(shù)的參數(shù)有些很復(fù)雜,比如SQL就需要用各種關(guān)鍵字把一條語(yǔ)句的參數(shù)分隔成多個(gè)組,但這會(huì)動(dòng)用很多關(guān)鍵字,也使語(yǔ)句結(jié)構(gòu)不統(tǒng)一。SPL使用層次參數(shù)簡(jiǎn)化了復(fù)雜參數(shù)的表達(dá),即通過(guò)分號(hào)、逗號(hào)、冒號(hào)自高而低將參數(shù)分為三層:

join(Orders:o,SellerId ; Employees:e,EId)

更豐富的日期和字符串函數(shù)。除了常見(jiàn)函數(shù),比如日期增減、截取字符串,SPL還提供了更豐富的日期和字符串函數(shù),在數(shù)量和功能上遠(yuǎn)遠(yuǎn)超過(guò)了SQL,同樣運(yùn)算時(shí)代碼更短。比如:

季度增減:elapse@q(“2020-02-27”,-3) //返回2019-05-27

N個(gè)工作日之后的日期:workday(date(“2022-01-01”),25) //返回2022-02-04

字符串類(lèi)函數(shù),判斷是否全為數(shù)字:isdigit(“12345”) //返回true

取子串前面的字符串:substr@l(“abCDcdef”,“cd”) //返回abCD

按豎線拆成字符串?dāng)?shù)組:“aa|bb|cc”.split(“|”) //返回[“aa”,“bb”,“cc”]

SPL還支持年份增減、求季度、按正則表達(dá)式拆分字符串、拆出SQL的where或select部分、拆出單詞、按標(biāo)記拆HTML等大量函數(shù)。

簡(jiǎn)化有序運(yùn)算。涉及跨行的有序運(yùn)算,通常都有一定的難度,比如比上期和同期比。SPL使用"字段[相對(duì)位置]"引用跨行的數(shù)據(jù),可顯著簡(jiǎn)化代碼,還可以自動(dòng)處理數(shù)組越界等特殊情況,比SQL窗口函數(shù)更加方便。比如,追加一個(gè)計(jì)算列rate,計(jì)算每條訂單的金額增長(zhǎng)率:

=T.derive(AMOUNT/AMOUNT[-1]-1: rate)

綜合運(yùn)用位置表達(dá)式和有序函數(shù),很多SQL難以實(shí)現(xiàn)的有序運(yùn)算,都可以用SPL輕松解決。比如,根據(jù)考勤表,找出連續(xù) 4 周每天均出勤達(dá) 7 小時(shí)的學(xué)生:


A
1=Student.select(DURATION>=7).derive(pdate@w(ATTDATE):w)
2=A1.group@o(SID;~.groups@o(W;count(~):CNT).select(CNT==7).group@i(W-W[-1]!=7).max(~.len()):weeks)
3=A2.select(weeks>=4).(SID)

簡(jiǎn)化集合運(yùn)算,SPL的集合化更加徹底,配合靈活的語(yǔ)法和強(qiáng)大的集合函數(shù),可大幅簡(jiǎn)化復(fù)雜的集合計(jì)算。比如,在各部門(mén)找出比本部門(mén)平均年齡小的員工:

A
1=Employees.group(DEPT; (a=~.avg(age(BIRTHDAY)),~.select(age(BIRTHDAY)<a)):YOUNG)
2=A1.conj(YOUNG)

計(jì)算某支股票最長(zhǎng)的連續(xù)上漲天數(shù):


A
1=a=0,AAPL.max(a=if(price>price[-1],a+1,0))

簡(jiǎn)化關(guān)聯(lián)計(jì)算。SPL支持對(duì)象引用的形式表達(dá)關(guān)聯(lián),可以通過(guò)點(diǎn)號(hào)直觀地訪問(wèn)關(guān)聯(lián)表,避免使用JOIN導(dǎo)致的混亂繁瑣,尤其適合復(fù)雜的多層關(guān)聯(lián)和自關(guān)聯(lián)。比如,根據(jù)員工表計(jì)算女經(jīng)理的男員工:

=employees.select(gender:"male",dept.manager.gender:"female")

方便的分步計(jì)算,SPL集合化更加徹底,可以用變量方便地表達(dá)集合,適合多步驟計(jì)算,SQL要用嵌套表達(dá)的運(yùn)算,用SPL可以更輕松實(shí)現(xiàn)。比如,找出銷(xiāo)售額累計(jì)占到一半的前n個(gè)大客戶,并按銷(xiāo)售額從大到小排序:

AB
2=sales.sort(amount:-1)/銷(xiāo)售額逆序排序,可在SQL中完成
3=A2.cumulate(amount)/計(jì)算累計(jì)序列
4=A3.m(-1)/2/最后的累計(jì)即總額
5=A3.pselect(~>=A4)/超過(guò)一半的位置
6=A2(to(A5))/按位置取值

流程控制語(yǔ)法。SPL提供了流程控制語(yǔ)句,配合內(nèi)置的結(jié)構(gòu)化數(shù)據(jù)對(duì)象,可以方便地實(shí)現(xiàn)各類(lèi)業(yè)務(wù)邏輯。

分支判斷語(yǔ)句:


AB
2&hellip;
3if T.AMOUNT>10000=T.BONUS=T.AMOUNT*0.05
4else if T.AMOUNT>=5000 && T.AMOUNT<10000=T.BONUS=T.AMOUNT*0.03
5else if T.AMOUNT>=2000 && T.AMOUNT<5000=T.BONUS=T.AMOUNT*0.02

循環(huán)語(yǔ)句:


AB
1=db=connect("db")
2=T=db.query@x("select * from sales where SellerID=? order by OrderDate",9)
3for T=A3.BONUS=A3.BONUS+A3.AMOUNT*0.01
4
=A3.CLIENT=CONCAT(LEFT(A3.CLIENT,4), " co.,ltd.")
5
 &hellip;

與Java的循環(huán)類(lèi)似,SPL還可用break關(guān)鍵字跳出(中斷)當(dāng)前循環(huán)體,或用next關(guān)鍵字跳過(guò)(忽略)本輪循環(huán),不展開(kāi)說(shuō)了。

計(jì)算性能更好。在內(nèi)存計(jì)算方面,除了常規(guī)的主鍵和索引外,SPL還提供了很多高性能的數(shù)據(jù)結(jié)構(gòu)和算法支持,比大多數(shù)使用SQL的內(nèi)存數(shù)據(jù)庫(kù)性能好得多,且占用內(nèi)存更少,比如預(yù)關(guān)聯(lián)技術(shù)、并行計(jì)算、指針式復(fù)用。

優(yōu)化體系結(jié)構(gòu)

SPL支持JDBC接口,代碼可外置于Java,耦合性更低,也可內(nèi)置于Java,調(diào)用更簡(jiǎn)單。SPL支持解釋執(zhí)行和熱切換,代碼方便移植和管理運(yùn)營(yíng),支持內(nèi)外存混合計(jì)算。

外置代碼耦合性低。SPL代碼可外置于Java,通過(guò)文件名被調(diào)用,既不依賴(lài)數(shù)據(jù)庫(kù),也不依賴(lài)Java,業(yè)務(wù)邏輯和前端代碼天然解耦。

對(duì)于較短的計(jì)算,也可以像SQLite那樣合并成一句,寫(xiě)在Java代碼中:

Class.forName("com.esproc.jdbc.InternalDriver");
Connection conn =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = conn.createStatement();
String arg1="1000";
String arg2="2000"
ResultSet result = statement.executeQuery(=Orders.select(Amount>="+arg1+" && Amount<"+arg2+"). groups(year(OrderDate):y,month(OrderDate):m; sum(Amount):s,count(1):c)");

解釋執(zhí)行和熱切換。業(yè)務(wù)邏輯數(shù)量多,復(fù)雜度高,變化是常態(tài)。良好的系統(tǒng)構(gòu)架,應(yīng)該有能力應(yīng)對(duì)變化的業(yè)務(wù)邏輯。SPL是基于Java的解釋型語(yǔ)言,無(wú)須編譯就能執(zhí)行,腳本修改后立即生效,支持不停機(jī)的熱切換,適合應(yīng)對(duì)變化的業(yè)務(wù)邏輯。

方便代碼移植。SPL通過(guò)數(shù)據(jù)源名從數(shù)據(jù)庫(kù)取數(shù),如果需要移植,只要改動(dòng)配置文件中的數(shù)據(jù)源配置信息,而不必修改SPL代碼。SPL支持動(dòng)態(tài)數(shù)據(jù)源,可通過(guò)參數(shù)或宏切換不同的數(shù)據(jù)庫(kù),從而進(jìn)行更方便的移植。為了進(jìn)一步增強(qiáng)可移植性,SPL還提供了與具體數(shù)據(jù)庫(kù)無(wú)關(guān)的標(biāo)準(zhǔn)SQL語(yǔ)法,使用sqltranslate函數(shù)可將標(biāo)準(zhǔn)SQL轉(zhuǎn)為主流方言SQL,仍然通過(guò)query函數(shù)執(zhí)行。

方便管理運(yùn)營(yíng)。由于支持庫(kù)外計(jì)算,代碼可被第三方工具管理,方便團(tuán)隊(duì)協(xié)作;SPL腳本可以按文件目錄進(jìn)行存放,方便靈活,管理成本低;SPL對(duì)數(shù)據(jù)庫(kù)的權(quán)限要求類(lèi)似Java,不影響數(shù)據(jù)安全。

內(nèi)外存混合計(jì)算。有些數(shù)據(jù)太大,無(wú)法放入內(nèi)存,但又要與內(nèi)存表共同計(jì)算,這種情況可利用SPL實(shí)現(xiàn)內(nèi)外存混合計(jì)算。比如,主表orders已加載到內(nèi)存,大明細(xì)表orderdetail是文本文件,下面進(jìn)行主表和明細(xì)表的關(guān)聯(lián)計(jì)算:


A
1=file("orderdetail.txt").cursor@t()
2=orders.cursor()
3=join(A1:detail,orderid ; A2:main,orderid)
4=A3.groups(year(main.orderdate):y; sum(detail.amount):s)

SQLite使用簡(jiǎn)單方便,但數(shù)據(jù)源加載繁瑣,計(jì)算能力不足。SPL架構(gòu)也非常簡(jiǎn)單,并直接支持更多數(shù)據(jù)源。SPL計(jì)算能力強(qiáng)大,提供了豐富的計(jì)算函數(shù),可以輕松實(shí)現(xiàn)SQL不擅長(zhǎng)的復(fù)雜計(jì)算。SPL還提供多種優(yōu)化體系結(jié)構(gòu)的手段,代碼既可外置也可內(nèi)置于Java,支持解釋執(zhí)行和熱切換,方便移植和管理運(yùn)營(yíng),并支持內(nèi)外存混合計(jì)算。

以上就是“Java嵌入數(shù)據(jù)引擎從SQLite到SPL的應(yīng)用方法是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI