26
2019.2
连贯操作
作者: POPASP
POPASP模型基础类提供的连贯操作方法,可以有效的提高数据存取的代码清晰度和开发效率,并且支持所有的CURD操作。使用也比较简单, 假如我们现在要查询一个User表的满足状态为1的前10条记录,并希望按照用户的创建时间排序 ,代码如下:
```brush:vb
set rs = B_("user").where("status= true").order("addtime").top(10).select()
```
这里的where、order和top方法T就被称之为连贯操作方法,除了select方法必须放到最后一个外(因为select方法并不是连贯操作方法),连贯操作T的方法调用顺序没有先后,例如,下面的代码和上面的等效:
```brush:vb
set rs = B_("user").order("addtime").top(10).where("status= true").select()
```
可能有些人还不太习惯使用连贯操作,但是连贯操作的好处还是显而易的。
连贯操作通常只有一个参数,并且仅在当此查询或者操作有效,完成后会自动清空连贯操作的所有传值(有个别特殊的连贯操作有多个参数,并且会记录当前的传值)。简而言之,连贯操作的结果不会带入以后的查询。
系统支持的连贯操作方法有:
| 连贯操作 | 作用 | 支持的参数类型 |
| -------- | ----- | ---- |
| where | 用于查询、更新或者删除等条件的定义 | Integer、Long、String、Dictionary、Array(数组) |
| onlySql | 是否只输出sql语句 | Number |
| from | 用于定义要操作的from后面连接字符串 | String |
| table | 用于定义要操作的数据表名称 | String |
| data | 用于新增或者更新数据之前的数据对象赋值 | Dictionary |
| field | 用于定义要查询的字段 | String、Array |
| fieldRev | 用于定义要查询的排除字段 | String、Array |
| order | 用于对结果排序 | String、Dictionary |
| top | 用于限制查询结果数量 | Integer |
| page | 用于查询分页 | Integer、Long、String、Array |
| group | 用于对查询的group支持 | String |
| having | 用于对查询的having支持 | String、Dictionary、Array |
| leftJoin | 用于对查询的join支持 | String、Array |
| union * | 用于对查询的union支持 | String |
| unionAll * | 用于对查询的union all支持 | String |
所有的连贯操作都返回当前的数据库类(如POPASP_ACCESS)实例对象(Me),其中带 * 标识的表示支持多次调用。
### onlySql
onlySql 是否只输出sql语句
| 项目 | 说明 |
| -------- | ----- |
| 用法 | onlySql(bool) |
| 参数 | 是否只要sql语句 :1或true则输出sql语句,0或false则输出查询结果 |
| 返回值 | 当前实例对象 |
| 备注 | 该方法只在当前调用有效,如果想查看每次查询的sql语句,则需每次调用调方法 |
用法示例:
```brush:vb
dim sql,dict
set dict = D_
dict("username") = "admin"
dict("password") = md5("123123")
sql = B_("user").onlySql(1).table("user").where(dict).find()
var_export sql'var_export为sub过程,用于变量输出
'将输出sql语句 SELECT TOP 1 * FROM `user` WHERE ( username = 'admin' AND password = '4297f44b13955235245b2497399d7a93' )
```
### where
用于查询、更新或者删除等条件的定义
| 项目 | 说明 |
| -------- | ----- |
| 用法 | where(where) |
| 参数 | where(必须):查询或者操作条件,Integer、String、Dictionary、Array |
| 返回值 | 当前实例对象 |
Where方法是使用最多的连贯操作方法,更详细的用法请参考后面的6.8 CURD操作和6.9查询语言部分。
### table
table 定义要操作的数据表名称,动态改变当前操作的数据表名称,需要写数据表的全名
| 项目 | 说明 |
| -------- | ----- |
| 用法 | table(tableName) |
| 参数 | tableName(必须):数据表名称,String |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用table方法,会自动获取模型对应或者定义的数据表 |
用法示例:
```brush:vb
dim rs
set rs = B_("user").table("content").find()
```
一般情况下,无需调用table方法,默认会自动获取当前模型对应或者定义的数据表。
### from
POPASP定义了leftjoin方法,没有定义inner join、right join,甚至嵌套的复杂方法,而是定义了"select * from [from]"中的from后面连接字符串的from方法。
| 项目 | 说明 |
| -------- | ----- |
| 用法 | from(str) |
| 参数 | str(必须):数据表名称,String |
| 返回值 | 当前实例对象 |
| 备注 | 如果同时调用table与from,那么忽略前者,而采用from |
用法示例:
```brush:vb
dim rs
set rs = B_("user").from("content").find()
```
### data
data 可以用于新增或者保存数据之前的数据对象赋值
| 项目 | 说明 |
| -------- | ----- |
| 用法 | data(dict) |
| 参数 | dict(必须):数据,Dictionary |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用data方法,则会取当前的Request.form数据对象或者传入add和save的数据 |
使用示例:
```brush:vb
'这个示例用来添加一条记录
dim dict,id
set dict = D_ '创建一个Dictionary对象
dict("meta") = "email"
dict("content") = "iaspcms@163.com"
dict("add_time") = now()
id = B_("contact").data(dict).add '5
```
```brush:vb
'在上面示例的基础上,修改一条记录
dim dict,result
set dict = D__ '创建一个Dictionary对象
dict("content") = "iaspcms@163.com"
dict("username") = "iaspcms"
result = B_("contact").where(5).data(dict).save()
```
### field
field 用于定义要查询的字段
| 项目 | 说明 |
| -------- | ----- |
| 用法 |field(field) |
| 参数 | 字段名(必须):数据支持 String、Array |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用field方法,则默认返回所有字段,和field(" ' ")等效 |
使用示例:
```brush:vb
<%
Class TestAction
sub field
dim rs1,rs2
set rs1 = B_("contact").field("meta,content as cont").find()
var_export rs1
set rs2 = B_("contact").field( array("meta","content as cont") ).find()
var_export rs2
end Sub
End Class
%>
```
如果不调用field方法或者field方法传入参数为空的话,和使用field(" * ")是等效的。但是我们更建议只获取需要显式的字段名。
### fieldRev
fieldRev 用于定义要查询的排除字段
| 项目 | 说明 |
| -------- | ----- |
| 用法 |fieldRev(field) |
| 参数 | 字段名(必须):数据支持 String、Array |
| 返回值 | 当前实例对象 |
| 备注 | 如果同时调用field与fieldRev,则采用后者 |
使用示例:
```brush:vb
<%
Class Test
sub field
dim rs1,rs2
set rs1 = B_("contact").field("meta,content").find()
var_export rs1
set rs2 = B_("contact").field( array("meta","content") ).find()
var_export rs2
end Sub
End Class
%>
```
### order
order 用于对操作结果排序
| 项目 | 说明 |
| -------- | ----- |
| 用法 | order(order) |
| 参数 | 排序的字段名:数据支持 String、Dictionary |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用order方法,按照数据库的默认规则 |
使用示例:
```brush:vb
order("id desc")
order("status desc,id asc")
```
order方法的参数支持Dictionary对象,此时常用于ajax,如下:
```brush:vb
<%
class TestAction
sub order
dim rs,dict
set dict = D_
dict("is_top") = "DESC"
dict("post_id") = "ASC"
set rs = B_("post").field("post_id,title").order(dict).select()
var_export rs
end sub
End Class
%>
```
### top
用于定义要查询的结果限制(支持所有的数据库类型)
| 项目 | 说明 |
| -------- | ----- |
| 用法 | top(top) |
| 参数 | 限制数量:数据支持 Integer |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用top方法,则表示没有限制,top语句适用于access、excel、mssql(sql server)数据库,如果在sqlite3中调用该方法,相当于调用了limit |
我们知道不同的数据库类型的limit用法是不尽相同的,在Access与mssql中无limit,但是有top。
使用示例:
```brush:vb
top(5)
top("5") '如果字符串是数字值的也可以
set rs = B_("post").field("post_id,title").top("5").select()
```
### limit
用于定义要查询的结果限制(支持所有的数据库类型)
| 项目 | 说明 |
| -------- | ----- |
| 用法 | limit(limit) |
| 参数 | 限制数量:数据支持 Integer,String |
| 返回值 | 当前实例对象 |
| 备注 | 如果不调用limit方法,则表示没有限制,limit语句适用于sqlite3、mysql数据库,如果要在access、excel、mssql(sql server)数据库中调用了该方法,相当于调用了top,而且此时参数类型只能是Integer |
使用示例:
```brush:vb
sql = B_(Array("user","sqlite3","sqlite.db")).onlySql(1).field("id,username").limit("10,10").select()
'sql为 SELECT id,username FROM `User` LIMIT 10 , 10
```
### PAGE
page 用于定义要查询的数据分页
| 项目 | 说明 |
| -------- | ----- |
| 用法 | page(page) |
| 参数 | page(必须):数据支持 Integer、Long、String、Array |
| 返回值 | 当前实例对象 |
Page操作方法可以更加快速的进行分页查询。
Page方法的用法格式为:
```brush:vb
Page("page[,listRows]")
```
Page表示当前的页数,listRows表示每页显示的记录数。例如:
```brush:vb
Page("2,10")
```
表示每页显示10条记录的情况下面,获取第2页的数据。
listRow如果不写的话,默认取10条。
在使用分页后,如果取当前页,只需将页数设置为null即可,如
```brush:vb
Page("null,10")
```
### GROUP
group 用于数据库的group查询支持
| 项目 | 说明 |
| -------- | ----- |
| 用法 | group(group) |
| 参数 | 限制数量:数据支持 String |
| 返回值 | 当前实例对象 |
使用示例
```brush:vb
group("is_top")
```
Group方法的参数只支持字符串
### HAVING
having 用于数据库的having查询支持
| 项目 | 说明 |
| -------- | ----- |
| 用法 | having(having) |
| 参数 | having(必须):String |
| 返回值 | 当前实例对象 |
使用示例:
```brush:vb
having('user_id>0')
```
### leftJoin
leftJoin 用于数据库的left join查询支持
| 项目 | 说明 |
| -------- | ----- |
| 用法 | leftJoin(leftJoin) |
| 参数 | leftJoin(必须):String |
| 返回值 | 当前实例对象 |
使用示例:
```brush:vb
class Test
sub join
dim rs
set rs = B_("post").field("post_id,title").leftJoin("[user] on post.user_id = user.id").select()
var_export B_("post").getLastSql()
var_export rs
end sub
end Class
```
### UNION
union 用于数据库的union查询支持
| 项目 | 说明 |
| -------- | ----- |
| 用法 | union(union) |
| 参数 | union(必须):union操作,String |
| 返回值 | 当前实例对象 |
| 备注 | Union方法支持多次调用 |
### UNIONAll
unionAll 用于数据库的union all查询支持
| 项目 | 说明 |
| -------- | ----- |
| 用法 | unionAll(unionAll) |
| 参数 | unionAll(必须):String |
| 返回值 | 当前实例对象 |
| 备注 | UnionAll方法支持多次调用 |