4.4 Model高级应用
所谓Model的高级应用,言外之意操作较为复杂,通常也不常用的应用。使用Model文件对数据库进行操作,你会发现单表操作时,超爽,多表操作时,巨烦。好多PHP框架在数据库操作上支持ActiveRecord功能,即只要在Model文件里定义好多个数据表之间的关联关系(如:一对多,一对一、或多对多),对一个数据表操作时,程序会自动进行关联数据表的数据操作。看似很有用(对于JAVA有优势),可对于PHP这种弱类型的编程语言,ActiveRecord则没有优势,运行效率大大折扣。最主要的是操作很不灵活,初学者入门学习成本太大。权衡利弊之后,DoitPHP框架没有支持ActiveRecord。所以在没有找到DoitPHP的ActiveRecord功能时,不必大惊小怪。
SQL查询语句组装:
前面文档Model应用中,已经提及SQL语句组装这个概念,现在就介绍完整的SQL查询语句组装的类方法,通常用于多个数据表的联合查询。在DoitPHP框架中对于多表操作,SQL语句是最简单直接的。例子仍然以前面讲到的postModel为例,在使用SQL查询语句组装之始先调用Model的类方法: createSql(),获取DbCommand Class的实例化对象。
$postModel = $this->model('posts');
$sqlObj = $postModel->createSql();
$selectSql = $sqlObj->from('users')->where('user_name=?', 'tommy')->getSql();
echo $selectSql;
注:上面的where()类方法非同于前面文档Model应用中类方法where(), 虽然用法一样,但两个类方法所属不同的类。这里讲的SQL查询语句组装的类方法是DbCommand Class的。下将此类文件提供的类方法详细说明一下。
1、from($tableName, $fields = null)
组装SQL语句中的FROM语句。 用于处理 SELECT fieldsName FROM tableName之类的SQL语句部分。
参数说明:
$tableName : 所要查询的数据表名。注:本参数支持数组
$fields : 所要查询的数据表字段。默认数据表全部字段
2、where($where, $value = null)
组装SQL语句的WHERE语句。 用于处理 WHERE id=3721 诸如此类的SQL语句部分。
参数说明:
$where : WHERE的条件内容
$value : 待转义的数值
3、orwhere($where, $value = null)
组装SQL语句的ORWHERE语句。 用于处理 ORWHERE id=2011 诸如此类的SQL语句部分。
参数说明:
$where : WHERE的条件内容
$value : 待转义的数值
4、order($orderDesc)
组装SQL语句排序(ORDER BY)语句。 用于处理 ORDER BY post_id ASC 诸如之类的SQL语句部分。
参数说明:
$orderDesc : 排序条件
5、group($fieldsName)
组装SQL的GROUP BY语句。 用于处理SQL语句中GROUP BY语句部分。
参数说明:
$fieldsName : 所要排序的数据表字段名称
6、having($where, $value = null)
组装SQL的HAVING语句。 用于处理 having id=2011 诸如此类的SQL语句部分。
参数说明:
$value : 数据表某字段的数据值
7、orhaving($where, $value = null)
组装SQL的ORHAVING语句。 用于处理or having id=2011 诸如此类的SQL语句部分。
参数说明:
$value : 数据表某字段的数据值
8、join($tableName, $where)
组装SQL语句中LEFT JOIN语句。 jion('表名2', '关系语句')相当于SQL语句中LEFT JOIN 表2 ON 关系SQL语句部分。
参数说明:
$tableName : 数据表名
$where : join条件。注:不支持数组
9、 limit($offset, $listCount)
组装SQL语句LIMIT语句。 limit(10,20)用于处理LIMIT 10, 20之类的SQL语句部分。参数说明:
$offset : 启始id
$listCount : 显示的行数
10、pageLimit($page, $listCount)
组装SQL语句的LIMIT语句。 注:本方法与limit()功能相类,区别在于:本方法便于分页,参数不同。
参数说明:
$page : 当前页数
$listCount : 显示的行数
11、getSql()
获取完整的SQL查询语句。
参数说明:
参数为空
12、distinct($tableName, $fields)
组装SQL语句中的FROM语句(查询函数:DISTINCT)。 用于处理 SELECT fieldsName FROM tableName之类的SQL语句部分。
参数说明:
$tableName : 所要查询的数据表名。注:本参数支持数组
$fields : 所要查询的数据表字段。默认数据表全部字段
SQL查询语句使用举例:
例一、获取组装的SQL语句
$sqlObj = $postModel->createSql();
$selectSql = $sqlObj->from('users', 'user_id')->where('user_id>2016')
->limit(0, 20)->getSql();
echo $selectSql;
例二、获取单行数据
$sqlObj = $postModel->createSql();
$selectSql = $sqlObj->from('users', array('user_id', 'user_name', 'user_type'))
->where('user_id>2016')->getSql();
$data = $postModel->query($selectSql)->fetchRow();
$this->dump($data);
例三、获取多行数据
$sqlObj = $postModel->createSql();
$selectSql = $sqlObj->from('users', array('user_id', 'user_name', 'user_type'))
->where('user_id>2016')->getSql();
$data = $postModel->query($selectSql)->fetchAll();
$this->dump($data);
例四、使用distinct数据库函数
$sqlObj = $postModel->createSql();
$selectSql = $sqlObj->distinct('users', 'user_id')
->where('user_id>2016')->getSql();
$data = $postModel->query($selectSql)->fetchAll();
$this->dump($data);
自定义数据库连接:
项目开发,通常都是所有的Model文件连接同一个数据库,数据库连接参数在项目主配置中。如果项目开发需要一个Model文件绑定的数据表不在当前的数据库里,而是在别的数据库里,这时,这个Model文件如何设置数据库连接参数?答案:重定义Model的类方法:_setConfig()。
举例如下:
在主配置文件中设置另一个数据库的连接参数。
$config['db'] = array(
'dsn' => 'mysql:host=localhost;dbname=项目数据库名',
'username' => 'root',
'password' => '123qwe',
'prefix' => '',
'charset' => 'utf8',
);
$config['test'] = array(
'dsn' => 'mysql:host=localhost;dbname=另外的数据库名',
'username' => 'root',
'password' => '123qwe',
'prefix' => '',
'charset' => 'utf8',
);
注:DoitPHP框架默认的数据库连接参数配置文件key为:db, 另一个数据库连接参数配置文件key姑且为:test。在主配置文件设置好数据库连接参数后,则在Model文件中重定义类方法:_setConfig()即可。代码如下:
/**
* 设置数据库连接
*
* @access protected
* @return array
*/
protected function _setConfig() {
return Configure::get('test');
}
使用数据库驱动层操作:
在项目开发中,如果有这样一个需求:在Controller文件中直接跳过Model层,直接使用数据库驱动层操作数据库。虽然这种需求很是蛋疼,不过这样操作可以提高程序运行效率(略过的Model层,减少的大片的代码执行)。
例一、
$db = DbPdo::getInstance(Configure::get('db'));
$sql = "select * from users where user_name=?";
$data = $db->query($sql, 'doitphp')->fetchRow();
$this->dump($data );
对于DbPdo Classr提供的类方法如下,如果这块项目开发有需求,请阅读,若没有业务需求的,可以直接跳过这些类方法说明了。
1、query($sql, $params = array())
执行SQL语句。 注:用于执行查询性的SQL语句(需要数据返回的情况)。
参数说明:
$sql : SQL语句
$params : 待转义的参数值
2、execute($sql, $params = array())
执行SQL语句。 注:本方法用于无需返回信息的操作。如:更改、删除、添加数据信息(即:用于执行非查询SQL语句)。
参数说明:
$sql : 所要执行的SQL语句
$params : 待转义的数据。注:本参数支持字符串及数组,如果待转义的数据量在两个或两个以上请使用数组。
3、fetchRow($model = PDO::FETCH_ASSOC)
获取一行查询信息。
参数说明:
$model : 返回数据的索引类型:字段型/数据型 等。默认:字段型
4、fetchAll($model = PDO::FETCH_ASSOC)
获取全部查询信息。
参数说明:
$model : 返回数据的索引类型:字段型/数据型 等。默认:字段型
5、getOne($sql, $params = array())
通过一个SQL语句获取一行信息(字段型)。
参数说明:
$sql : SQL语句内容
$params : 待转义的参数值
6、getAll($sql, $params = array())
通过一个SQL语句获取全部信息(字段型)。
参数说明:
$sql : SQL语句
$params : 待转义的参数值
7、startTrans()
开启事务处理。
参数说明:
参数为空
8、commit()
提交事务处理。
参数说明:
参数为空
9、rollback()
事务回滚。
参数说明:
参数为空
10、escape($value)
对字符串进行转义,提高数据库操作安全。
参数说明:
$value : 待转义的字符串内容
11、insert($tableName, $data, $isReturnId = false)
数据表写入操作。
参数说明:
$tableName : 所要操作的数据表名称
$data : 所要写入的数据内容。注:数据必须为数组
$isReturnId : 是否返回数据为:last insert id
12、replace($tableName, $data)
数据表数据替换操作。
参数说明:
$tableName : 所要操作的数据表名称
$data : 所要替换的数据内容。注:数据必须为数组
13、update($tableName, $data, $where = null, $value = array())
数据表更新操作。
参数说明:
$tableName : 所要操作的数据表名称
$data : 所要更改的数据内容
$where : 更改数据所须的条件
$value : 待转义的参数值
14、delete($tableName, $where = null, $value = array())
数据表删除操作。
参数说明:
$tableName : 所要操作的数据表名称
$where : 删除数据所需的SQL条件
$value : 待转义的参数值
15、getTableInfo(tableName, $extItem = false)
根据数据表名获取该数据表的字段信息。
参数说明:
$tableName : 数据表名
$extItem : 数据返回类型选项,即是否返回完成的信息(包含扩展信息)。true:含扩展信息/false:不含扩展信息
16、getTableList()
获取当前数据库中的所有的数据表名的列表。
参数说明:
参数为空
17、throwException()
抛出异常提示信息处理。 用于执行SQL语句时,程序出现异常时的异常信息抛出。
参数说明:
参数为空
18、getLastError(PDOStatement $query = null)
获取数据库错误描述信息。
参数说明:
$query : 所执行的SQL语句
19、getLastInsertId()
获取最新的insert_id。
参数说明:
参数为空
20、getDbConnection()
获取数据库连接的实例化对象。
参数说明:
参数为空
21、getInstance($params = array())
单例模式。 用于本类的单例模式(singleton)实例化。
参数说明:
$params : 数据库连接参数,如数据库服务器名,用户名,密码等