Moodle插件开发笔记12: Database操作(二)

五、Moodle Database API      这些api在/lib/dmllib.php file里 1、Read操作 有3类rea…

五、Moodle Database API
     这些api在/lib/dmllib.php file里

1、Read操作
有3类read操作,每类有3个函数
第一类:Query by parameters
·get_field($table, $return, $field1, $value1, $field2=”, $value2=”, $field3=”, $value3=”)

该函数只返回一个single field,它是第2个参数所指向的field的值。如果该field没找到,就return false。该函数要求是只找到一个匹配,如果有多个匹配,是只返回第1个还是出错?
该函数第1个参数是table name,第2个参数是要返回的值所属的field,再后面的参数就是key/value成对出现(至少要有一对),这些key/value会转化成where语句里的key=value,而且各个key=value之间的连接是“and”。
例如:
$username = get_field(‘user’, ‘username’, ‘firstname’, ‘bob’, ‘lastname’, ‘roberts’);
返回user table里firstname=bob and lastname=roberts的record的username field的值。
· get_record($table, $field1, $value1, $field2=”, $value2=”, $field3=”, $value3=”, $fields=’*’)
     该函数只返回一个single record。如果没有record match,就return false。如果有多于一个match,就会报错。
    该函数第1个参数是table name,紧接着的参数就是key/value成对出现(至少要有一对),这些key/value会转化成where语句里的key=value,而且各个key=value之间的连接是“and”,最后一个参数是指定要返回的field,如果设置最后一个参数的值为”*”,或不设置这个参数,那么就会返回该record的所有fields。
例如:
$userrec = get_record(‘user’, ‘fname’, ‘bob’, ‘lname’, ‘roberts’, ‘username,fname,lname’);
if ($userrec) {
print_r($userrec);
}
返回user table里fname=bob and lname=roberts的record的username, fname, lname field的值。
返回的结果类似于:
stdClass Object
(
[username] => bobroberts
[fname] => Bob
[lname] => Roberts
)

·get_records($table, $field=”, $value=”, $sort=”, $fields=’*’, $limitfrom=”, $limitnum=”)
    该函数返回an array of data records as objects。该array的indexed by第5个参数$field里的第1个field。如果$field没有设置或者设置为”*”,那么则indexed by “id”field。(“indexed by”指以其作为array element的key,例如indexed by “id” field,表示该record array是以“id”作为key,record object作为value,见下面的例子)
如果no records are found,return false.
第2、3个参数是一对key/value,用于where。如果没有设置这对key/value(即第2、3个参数为empty string),则返回该table的所有records。
$sort参数是设置a field by which the returned array will be ordered。
$fields参数如果没有设置则返回所有的fields,如果要设置则field之间用逗号隔开
$limitfrom参数是设置starting record

$limitnum参数是设置the maximum number of records

例如:
$userrecs = get_records(‘user’, ‘firstname’, ‘bob’, ‘lastname’, ‘id,firstname,lastname’);
返回user table里firstname=bob的sort by lastname的record array(只有id, firstname and lastname fields),并indexed by “id”field。
返回的结果类似于:
Array
(
[34] => stdClass Object
(
[id] => 34
[firstname] => Bob
[lastname] => Roberts
)
[123] => stdClass Object
(
[id] => 123
[firstname] => Bob
[lastname] => Williams
)
)

可见上面的返回结果的array element是以id为array element的key,以record object为array element的value。

第二类:Query by “where” string
    这一类和上一类非常类似,唯一的区别在于它只需要用一个参数来设置where part of the query,使query更为灵活。上一类的函数只能使用”fieldname=fieldvalue”作为where的语句,而且各个条件之间设死为“and”。而本类的函数则可以使用“or”或其他连接符,同时不局限于”fieldname=fieldvalue”,例如”fieldname>=fieldvalue”.
本类的三个函数(具体参考上类)

get_field_select($table, $return, $select)
get_record_select($table, $select=”, $fields=’*’)
get_records_select($table, $select=”, $sort=”, $fields=’*’, $limitfrom=”, $limitnum=”)

例如
$select = “(firstname = ‘bob’ OR firstname = ‘robert’) AND lastname = ‘roberts'”;
$userrecs = get_records_select(‘user’, $select);
第三类:Query by full SQL
该类和之前的类也很类似,但更为灵活,直接使用sql语句来获取record。

本类的三个函数(具体参考上类)
get_field_sql($sql)
get_record_sql($sql)
get_records_sql($sql, $limitfrom=”, $limitnum=”)
例如
$sql = “SELECT u.id, u.firstname, u.lastname,
MAX(ul.timeaccess) as lastaccess
FROM {$CFG->prefix}user u
INNER JOIN {$CFG->prefix}user_lastaccess ul
ON ul.userid = u.id
WHERE u.username = ‘broberts'”
$userrec = get_record_sql($sql);
2、Write操作

有2类write操作的API:by field, by record。
常用的有下列4个函数
set_field
该函数用于set a specific field in a specific record。格式为:
set_field($table, $newfield, $newvalue, $field1, $value1, $field2=”, $value2=”, $field3=”, $value3=”)
详细的参数和上面的函数类似
Example
set_field(‘user’, ‘firstname’, ‘Robert’, ‘username’, ‘broberts’)
上述代码表示设置user table的 username = broberts 的record的 firstname field的值为 robert
set_field_select
和set_field类似,但where语句更为灵活。格式为:
set_field_select($table, $newfield, $newvalue, $select, $localcall = false)
insert_record
用于create a new record。By default返回值是new id。
格式为:
insert_record($table, $dataobject, $returnid=true, $primarykey=’id’)
参数$dataobject是用一个object来包含new record info,见下例。
example
$newrec = new Object();
$newrec->firstname = ‘Bill’;
$newrec->lastname = ‘Williams’;
$newrec->username = ‘bwilliams’;
$newrec->password = hash_internal_user_password(‘secret’);
$newrec->email =’bwilliams@email.com’;
$newid = insert_record(‘user’, $newrec);

update_record
update record。格式为:
update_record($table, $dataobject)
注意:和insert_record函数相比,其$dataobject的object必须包含”id” value,这是insert_record函数没有包含的!
当你开发moodle database操作的代码时,下列的规范强烈建议应该遵循:
Take only what you need
即尽量只获取你需要的东东。比如,如果你只需要某个field,那么call get_field function。 如果你只需要single record,then call get_record function。还有在参数$fields里只设置你要获取的fields。另外如果你要获取多于一个的record,那么必须fields list必须以id作为第一个field。
Limiting your returned data

合理使用$limitfrom and $limitnum参数,可以实现分页和减轻server的负担不要一次性load db data。
Example: 每次只获取100个record
$limitfrom = 0;
$limitnum = 100;
while ($records = get_records(‘user’, ‘deleted’, ‘n’, ‘id’, ‘id,firstname,lastname’, $limitfrom, $limitnum) {
foreach ($records as $uid => $userrec) {
/// Do some processing ///
}
$limitfrom += $limitnum;
}

Using recordsets
如果你处理large recordsets,使用get_recordset函数比get_records函数更为方便。
get_recordset函数的格式和get_records函数的一样。
get_recordset($table, $field=”, $value=”, $sort=”, $fields=’*’, $limitfrom=”, $limitnum=”)
不过get_recordset函数需要手动控制memory use,即你要写代码来close recordset
example
//Creating a recordset and saving it in a variable
$rs = get_recordset(‘course’, ”, ”, ”, ‘id’);
//Fetching the next record from the set
while ($course = rs_fetch_next_record($rs)) {
$subcontext = get_context_instance(CONTEXT_COURSE, $course->id);
forum_add_user_default_subscriptions($userid, $subcontext);
}
//Closing the recordset when completed
rs_close($rs);

Optimizing carefully with joins
如果要获取的data来自多个table,由于没有api来获取多个table的data,所以要使用join sql语句。
Testing on more than one database engine
要在多个数据库上进行测试。

作者: admin

为您推荐

联系我们

联系我们

邮箱:

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部