jxORM提供了豐富的數據查詢功能。在jxORM中,有兩種數據查詢方式:
- 通過數據類執行查詢
- 直接使用SQL的select語句查詢
數據類查詢
數據類查詢的優勢:
- 可以根據數據類的定義,自動完成查詢條件中的條件值和查詢到的數據的類型轉換
- 直接獲取到數據對象,如果有修改可以直接update到數據庫中
- 最大優勢就是可以通過數據類間的繼承,提供可靠的數據擴展能力。
數據類查詢的核心函數是:searchBy類函數。其函數簽名為:
@classmethod
searchBy(cls, db, expression, offset:int=0, limit:int=100)
使用示例:
#查詢test用戶的數據
users = User.searchBy(db, "Name == 'test' & age > 18")
查詢表達式expression是一個字符串,用于指定查詢條件。查詢條件的語法如下:
字段名1 比較運算符1 值1 & 字段名2 比較運算符2 值2 & ...
# & 符合代表的是條件表達式之間是與連接【AND】
其中,字段名是數據類中定義的字段名,比較運算符是以下之一:
==:等于
>:大于
<:小于
>=:大于等于
<=:小于等于
<>:不等于
like:字符串模糊查詢
注1:比較運算符兩邊必須有空格,否則會報錯
注2:字段名如果不是本類的屬性則忽略相應的查詢條件
searchBy的執行結果是一個list,其中的元素是dict,每個dict對應一條符合查詢條件的User數據。
注:如果數據類是繼承自其他數據類,則查詢結果會自動合并所繼承的所有父表中的數據。
事務中查詢
jxORM的所有操作都是在事務中進行的,查詢也不例外。
只是,數據查詢只不需要考慮事務的提交與回滾,只將db作為數據庫連接使用而已;而insert、update等需要修改數據庫中內容的操作就必須在歸還db時提交事務。
讀取唯一性結果
searchBy返回的是一個list。如果我們明確知道結果只有一條,則可以使用get類函數來直接獲取到dict型的結果,即searchBy(…)[0]。
@classmethod
getBy(cls, db, expression)
當然,唯一性結果中返回dict數據意義不大,重要的是返回數據所對應的該數據類型的數據對象,這才是ORM的意義所在。
#根據條件獲取數據對象,可以修改后直接update到數據庫中
@classmethod
Get(cls, db, expression)#還有比較常用的在數據庫事務中獲取數據對象的兩個類函數
#根據ID獲取數據對象
@classmethod
GetByID(cls, db, id)#根據Name獲取數據對象
@classmethod
GetByName(cls, db, name)
注1:GetByName是根據【Name == name】來查詢的【Name,第一個字母大寫】,如果該數據類中沒有定義Name字段,則可能會出現邏輯錯誤【相當于未設置查詢條件來查詢所有行,既有可能返回多條數據從而觸發多行異常,也有可能在只有一條數據時工作正常】
注2:get類函數如果查詢結果為零行則返回None,如果超過一行則擲出異常
sql語句直接查詢
對于比較復雜的數據庫查詢,可以直接使用sql語句來查詢數據:
from jxORM import select
#其簽名為:
select(db, sql, need_trans=True)
查詢結果是一個list,其中的元素是dict,每個dict對應一條符合查詢條件的結果數據。
注1:只支持select查詢語句,不支持插入、修改、刪除操作
注2:需要開發者根據數據表中的字段類型來完成查詢條件中的數據的類型轉換,典型的如使用int類型來代表bool,則【Noused == False】,應寫做:Noused=0
select函數會盡可能的識別查詢語句中FROM子句中的數據表名,以及SELECT子句中的字段名,然后將識別到的字段名和識別到的數據類中的字段名進行匹配,如果匹配成功則自動用匹配到的字段的數據類型進行轉換。
如果SELECT子句使用了別名等無法滿足上述匹配條件,則設置need_trans=False來取消自動轉換,以避免混亂。
啟用自動轉換的好處是如果數據庫中的數據類型和python中的數據類型不一致,jxORM會自動將數據庫中的數據類型轉換為python中的數據類型。否則就需要用戶自行轉換。
如,我們一般用整數來代表bool,那么不轉換的話我們得到的就是1或0,而轉換的話則會得到True或False。
或者我們為了節省存儲空間,在sqlite中用Integer來代表日期時間數據類型,那么不轉換的話我們得到的就是一個整數,而轉換的話則會得到一個datetime對象。
注:對于sqlite這樣的數據庫,need_trans=False導致讀取到的行數據不再是【dict】,而是只包含列值的【tuple】