開源SPL,ORM的終結(jié)者?
來源丨Java知音
SPL用統(tǒng)一數(shù)據(jù)結(jié)構(gòu)和語法風(fēng)格實現(xiàn)業(yè)務(wù)邏輯
| A | B | C | |
| 1 | =db=connect@e("dbName") | /連接數(shù)據(jù)庫,開啟事務(wù) | |
| 2 | =db.query@1("select sum(Amount) from sales where sellerID=? and year(OrderDate)=? and month(OrderDate)=?", p_SellerID,year(now()),month(now())) | /查詢當(dāng)月銷售額 | |
| 3 | =if(A2>=10000 :200, A2<10000 && A2>=2000 :100, 0) | /本月累計獎金 | |
| 4 | =p_Amount*0.05 | /本單固定獎金 | |
| 5 | =BONUS=A3+A4 | /總獎金 | |
| 6 | =create(ORDERID,CLIENT,SELLERID,AMOUNT,BONUS,ORDERDATE) | /創(chuàng)建訂單的數(shù)據(jù)結(jié)構(gòu) | |
| 7 | =A6.record([p_OrderID,p_Client,p_SellerID,p_Amount,BONUS, date(now())]) | /生成一條訂單記錄 | |
| 8 | >db.update@ik(A7,sales;ORDERID) | /嘗試寫入庫表 | |
| 9 | =db.error() | /入庫結(jié)果 | |
| 10 | if A9==0 | >A1.commit() | /成功,則提交事務(wù) |
| 11 | Else | >A1.rollback() | /失敗,則回滾事務(wù) |
| 12 | >db.close() | /關(guān)閉數(shù)據(jù)庫連接 | |
| 13 | return A9 | /返回入庫結(jié)果 |
上面的SPL代碼使用統(tǒng)一的數(shù)據(jù)結(jié)構(gòu)、語法、函數(shù),就可以完成整個業(yè)務(wù)邏輯的開發(fā),包括數(shù)據(jù)庫讀寫、事務(wù)處理、流程處理、數(shù)據(jù)計算。
…//省略參數(shù)的獲取過程Class.forName("com.esproc.jdbc.InternalDriver");Connection conn =DriverManager.getConnection("jdbc:esproc:local://");CallableStatement statement = conn.prepareCall("{call InsertSales(?, ?,?,?)}");statement.setObject(1, d_OrderID);statement.setObject(2, d_Client);statement.setObject(3, d_SellerID);statement.setObject(4, d_Amount);statement.execute();...
JAVA調(diào)用SPL的形式與調(diào)用存儲過程相同,且無須數(shù)據(jù)庫管理員授權(quán),不影響數(shù)據(jù)庫安全,便于遷移,方便調(diào)試,處理能力更強(qiáng),代碼更簡單。
結(jié)構(gòu)化數(shù)據(jù)對象
內(nèi)外數(shù)據(jù)交換能力
取單條記錄:
取序表(記錄集合):
比如,原序表為 T,經(jīng)過增刪改之后的序表為 NT, 將變化結(jié)果持久化到數(shù)據(jù)庫:
流程控制能力
| A | B | |
| 2 | … | |
| 3 | if T.AMOUNT>10000 | =T.BONUS=T.AMOUNT*0.05 |
| 4 | else if T.AMOUNT>=5000 && T.AMOUNT<10000 | =T.BONUS=T.AMOUNT*0.03 |
| 5 | else if T.AMOUNT>=2000 && T.AMOUNT<5000 | =T.BONUS=T.AMOUNT*0.02 |
循環(huán)語句:
| A | B | |
| 1 | =db=connect("db") | |
| 2 | =T=db.query@x("select * from sales where SellerID=? order by OrderDate",9) | |
| 3 | for T | =A3.BONUS=A3.BONUS+A3.AMOUNT*0.01 |
| 4 | =A3.CLIENT=CONCAT(LEFT(A3.CLIENT,4), "co.,ltd.") | |
| 5 | … | |
與Java的循環(huán)類似,SPL還可用break關(guān)鍵字跳出(中斷)當(dāng)前循環(huán)體,或用next關(guān)鍵字跳過(忽略)本輪循環(huán),不展開說了。
SPL超越ORM獲得更高的開發(fā)效率
更多計算函數(shù)
比如,時間類函數(shù),日期增減:elapse("2020-02-27",5) //返回2020-03-03
星期幾:day@w("2020-02-27") //返回5,即星期6
N個工作日之后的日期:workday(date("2022-01-01"),25) //返回2022-02-04
字符串類函數(shù),判斷是否全為數(shù)字:isdigit("12345") //返回true
取子串前面的字符串:substr@l("abCDcdef","cd") //返回abCD
更方便的集合運(yùn)算
比如,批量修改記錄:T.run(BONUS+AMOUNT*0.01: AMOUNT, concat(left(CLIENT,4), "co.,ltd."): CLIENT)
過濾:T.select(Amount>1000 && Amount<=3000)
對有序序表按二分法進(jìn)行過濾:T.select@b(Amount>1000 && Amount<=3000)
分組匯總:T.groups(Client;sum(Amount))
涉及跨行的集合運(yùn)算,通常都有一定的難度,比如比上期和同期比。ORM沒有為跨行運(yùn)算做優(yōu)化,代碼通常很繁瑣。SPL使用"字段[相對位置]"引用跨行的數(shù)據(jù),可顯著簡化代碼,還可以自動處理數(shù)組越界等特殊情況。比如,追加一個計算列rate,計算每條訂單的金額增長率:
| A | |
| 1 | …//省略序表Employees的生成過程 |
| 2 | =Employees.group(DEPT; (a=~.avg(age(BIRTHDAY)),~.select(age(BIRTHDAY)<a)):YOUNG) |
| 3 | =A2.conj(YOUNG) |
計算某支股票最長的連續(xù)上漲天數(shù):
| A | |
| 1 | …//省略序表AAPL的生成過程 |
| 2 | =a=0,AAPL.max(a=if(price>price[-1],a+1,0)) |
更專業(yè)的結(jié)構(gòu)化數(shù)據(jù)類型
比如,在序表T的基礎(chǔ)上,按字段名取一列,返回簡單集合:T.(AMOUNT)。
取幾列,返回集合的集合:T.([CLIENT,AMOUNT])
取幾列,返回新序表:T.new(CLIENT,AMOUNT)
按序號訪問通常難度較大,序表天然有序,很容易處理此類問題。比如,按列號取幾列,返回新序表:T.new(#2,#4)
按序號倒數(shù)取記錄:T.m(-2)
按序號取某幾條記錄形成序表:T([3,4,5])
按范圍取記錄形成序表:T(to(3,5))
解釋執(zhí)行和熱部署
更方便的數(shù)據(jù)庫讀寫方法
| A | B | |
| 1 | … | |
| 2 | =T=db.query("select * from salesR where SellerID=?",10) | /批量查詢,序表 T |
| 3 | =NT=T.derive() | /復(fù)制出新序表 NT |
| 4 | =NT.field("SELLERID",9) | /批量修改 |
| 5 | =db.update(NT:T,sales;ORDERID) | /持久化到數(shù)據(jù)庫 |
上面代碼中,函數(shù)update實現(xiàn)批量修改,無須繁瑣的循環(huán)語句。函數(shù)update經(jīng)過精心設(shè)計,可以統(tǒng)一處理多種批量寫庫方法,遇到既有新增,又有修改和刪除的批量寫庫的情況,SPL的優(yōu)勢更加明顯。
| A | B | |
| 1 | … | |
| 2 | =T=db.query("select * from salesR where SellerID=?",10) | /查出一批記錄 |
| 3 | =NT=T.derive() | /復(fù)制出新序表 |
| 4 | =NT.delete(NT.select(ORDERID==209 || ORDERID==208)) | /批量刪除 |
| 5 | =NT.field("SELLERID",9) | /批量修改 |
| 6 | =NT.record([220,"BTCH",9,5200,100,date("2022-01-02"), 221,"BTCH",9,4700,200,date("2022-01-03")]) | /批量追加 |
| 7 | =db.update(NT:T,salesR;ORDERID) | /持久化到數(shù)據(jù)庫 |
與ORM相比,SPL是專業(yè)的結(jié)構(gòu)化數(shù)據(jù)處理語言,數(shù)據(jù)對象更強(qiáng)大,語法更靈活,函數(shù)更豐富,可以更容易地進(jìn)行數(shù)據(jù)庫讀寫,可以簡化復(fù)雜的流程處理和數(shù)據(jù)計算,可以真正提高業(yè)務(wù)邏輯的開發(fā)效率。
-End-
最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

面試題】即可獲取