jxORM--查询数据
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】