数据库模块模块 小扳手
来源:互联网 发布:拆分源码 编辑:程序博客网 时间:2024/04/29 13:50
- 背景
- 独立方式
- 方法抽取
- 增
- 删
- 改
- 查
- 整体方式
- 字符串切割
- 匹配模式
- 完整 小扳手
- 总结
背景
放假在家的日子过得真是飞快,一晃这么多天了没碰代码,想来还真是有点汗颜。为了扩充我的代码小仓库,就写了个简单的轮子,这样以后就省事了。
这次的轮子,借鉴了Apache的db-utils框架(然而我这个简易的不能更简易了吧)。大致的功能就是CRUD的操作。实现的时候分别以独立和整体的方式表现。
接下来我将一点点的写出来
独立方式
独立方式就是指简单的对于select, update, delete, insert等语句进行专门处理,一种SQL语句对应一种处理方式。其实底层原理都是一样的。
方法抽取
在进行独立语句处理之前,我们还需要明白的就是在PDO模块中的prepare语句,既可以在一定的程度上提升程序的运行效率,还能提高程序的安全性。(类似于Java中JDBC常用的PreparedStatement)。
在PHP中实现类似的处理有两种方式,这里介绍一下使用?
的吧。因为我觉得使用:variable
的方式虽然对于程序的可读性上来讲比较好,但是在灵活度以及程序的维护层面上就不是那么的美妙了。所以我这里使用了第一种。至于怎么实现,还是先来看个小例子吧。
$arr = array( "name", 1);for($index=0; $index<count($arr); $index++) { echo "<mark>{$arr[$index]}</mark><br />";}
运行的效果为:
通过这种方式,就可以取得数组中我们预置好的变量值了,配合PHP中的bindParam方法,就可以啦。
接下来/** * 补全SQL语句,并处理附加参数。 * @param $sql * @param $params * @return PDOStatement */ public function prepareAndExecute($sql = "", $params = array()) { try{ $sqlRunner = $this->conn->prepare($sql); for ($index = 0; $index < count($params); $index++) { $sqlRunner->bindParam($index + 1, $params[$index]); } $sqlRunner->execute(); return $sqlRunner; }catch (Exception $e){ throw new RuntimeException($e->getMessage()); } }
增
下面针对向数据库中插入数据实现特定方法。
/** * 数据插入,返回值表示是否成功执行。 * @param $sql * @param $params * @return bool */ public function insert($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; }
删
/** * 支持单条记录删除以及批量删除操作。 * @param $sql * @param $params * @return bool */ public function delete($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; }
改
/** * 支持单条记录更新以及批量更新操作。 * @param $sql * @param $params * @return bool */ public function update($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; }
查
/** * 根据SQL语句获取到查询结果,防止SQL注入并处理附加参数。 * @param $sql * @param $params * @return array|bool */ public function select($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); $resultSet = $sqlRunner->fetchAll(PDO::FETCH_ASSOC); if (count($resultSet) == 0 || $resultSet == false) { return false; } else { return $resultSet; } }
获取到查询结果集之后进行返回,至于要怎么对数据进行处理,就不适合在这一个方法内实现了,具体的业务逻辑还是要进行具体分析。
按照约定俗成的理念,一个方法只完成一个功能就够了,一个方法实现多个功能很多时候不符合“低耦合,高内聚”的理念。
整体方式
对于整体方式,我觉得和上面的处理逻辑并没有什么很大的区别,唯一不同的就是对上面的代码进行了重构。
精简了代码处理,以及优化了代码的结构,其他的还真的没什么不同的。但是这里有一个小小的技巧。
来观看“select, update, delete, insert”这几个关键字,不知有没有发现有什么共通之处?
哈哈,都是6个字母呗。是的,就是这么个特征,而且针对于SQL语句而言,这几个关键字通常是放置在最前面的(这里没有讨论关于复杂SQL语句书写的情况),因此简单的SQL语句就可以利用这一个特点,书写的更加简洁。
字符串切割
先来看个小例子。
echo "<br />对于substr函数的测试!";$types = array('select', 'update', 'delete', 'insert');for($index=0; $index<count($types); $index++) { $type = substr("{$types[$index]} sql statement", 0, 6); echo "<br /><mark>{$type}</mark>";}
运行的效果就是:
匹配模式
于是,独立方式的那么多的代码,接下来就可以被写成下面的这样。
/** * 全方位实现所有SQL语句的执行。<br /> * 自动区分SQL语句CRUD类型,并实现$SQL语句的附加参数处理。 * @param $sql * @param $params */ public function exec($sql = "", $params = array()) { $sqlType = substr($sql, 0, 6); $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlType == "select") { $resultSet = $sqlRunner->fetchAll(PDO::FETCH_ASSOC); if ($resultSet != false && count($resultSet) != 0) { return $resultSet; } else { return false; } } else if ($sqlType == 'delete' or $sqlType == 'update' or $sqlType == 'insert') { if ($sqlRunner) { return true; } else { return false; } } else { // 实际上,即使是非CURD语句,这里也是能够成功得到执行的,prepareAndExecute方法内部完成了对此的处理。但是为了业务逻辑更加清晰,此处故意以抛出异常的形式处理。 throw new RuntimeException('您输入的SQL语句不是业务语句!如必须执行,请使用prepareAndExecute()方法代替!'); }
完整 小扳手
接下来,贴上整体这个小扳手的代码,比较简单,就不做过多的注释了。
<?php/** * Created by PhpStorm. * User: ${郭璞} * Date: 2017/1/22 * Time: 22:24 * Description: DB相关 * <br>在DbUtils中配置所需数据库连接信息。 * <br>然后只需要实例化QueryRunner即可完成自定义的CRUD语句了。 *//** * Class DbUtils * 数据库配置信息必备。只需要修改db_config 数组中的数据即可。 */class DbUtils{ private $dbConfig; private $conn; public function getConn() { return $this->conn; } public function __construct($encoding = "utf8") { /** * 数据库配置信息 */ $db_config = array( "host" => "localhost", "user" => "root", "password" => "mysql", "dbname" => "test", ); $this->dbConfig = $db_config; $this->conn = new PDO("mysql:host={$this->dbConfig['host']};dbname={$this->dbConfig['dbname']}", $this->dbConfig['user'], $this->dbConfig['password']); if ($encoding !== "utf8") { $this->conn->query("set names {$encoding}"); } else { $this->conn->query("set names utf8"); } } public function __destruct() { // TODO: Implement __destruct() method. // 关闭数据库连接对象 $this->conn = null; }}/** * Class QueryRunner * 模拟Apache db-utils实现的数据库常用操作支持类。最简易版本。 */class QueryRunner{ private $conn; public function __construct($encoding = 'utf8') { $dbutils = new DbUtils($encoding); $this->conn = $dbutils->getConn(); } /** * 根据SQL语句获取到查询结果,防止SQL注入并处理附加参数。 * @param $sql * @param $params * @return array|bool */ public function select($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); $resultSet = $sqlRunner->fetchAll(PDO::FETCH_ASSOC); if (count($resultSet) == 0 || $resultSet == false) { return false; } else { return $resultSet; } } /** * 数据插入,返回值表示是否成功执行。 * @param $sql * @param $params * @return bool */ public function insert($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; } /** * 支持单条记录更新以及批量更新操作。 * @param $sql * @param $params * @return bool */ public function update($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; } /** * 支持单条记录删除以及批量删除操作。 * @param $sql * @param $params * @return bool */ public function delete($sql = "", $params = array()) { $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlRunner) return true; else return false; } /** * 补全SQL语句,并处理附加参数。 * @param $sql * @param $params * @return PDOStatement */ public function prepareAndExecute($sql = "", $params = array()) { try{ $sqlRunner = $this->conn->prepare($sql); for ($index = 0; $index < count($params); $index++) { $sqlRunner->bindParam($index + 1, $params[$index]); } $sqlRunner->execute(); return $sqlRunner; }catch (Exception $e){ throw new RuntimeException($e->getMessage()); } } /** * 全方位实现所有SQL语句的执行。<br /> * 自动区分SQL语句CRUD类型,并实现$SQL语句的附加参数处理。 * @param $sql * @param $params */ public function exec($sql = "", $params = array()) { $sqlType = substr($sql, 0, 6); $sqlRunner = $this->prepareAndExecute($sql, $params); if ($sqlType == "select") { $resultSet = $sqlRunner->fetchAll(PDO::FETCH_ASSOC); if ($resultSet != false && count($resultSet) != 0) { return $resultSet; } else { return false; } } else if ($sqlType == 'delete' or $sqlType == 'update' or $sqlType == 'insert') { if ($sqlRunner) { return true; } else { return false; } } else { // 实际上,即使是非CURD语句,这里也是能够成功得到执行的,prepareAndExecute方法内部完成了对此的处理。但是为了业务逻辑更加清晰,此处故意以抛出异常的形式处理。 throw new RuntimeException('您输入的SQL语句不是业务语句!如必须执行,请使用prepareAndExecute()方法代替!'); } }}
总结
回顾一下,本次主要学习了一下小扳手的整体的实现流程,没什么技术难度。对自己而言也是一个拿不出手的实用性小工具罢了。
还有就是,过年在家写代码的效率真的是太低了。好想安安静静的写会代码,安安静静的思考。
这个寒假,貌似,有点长,还有一个月呢。。。
- 数据库模块模块 小扳手
- python小模块-----copy 模块
- Ajax 通用小模块
- HTML之小模块
- YII 小模块功能
- inspect模块小技巧
- 小模块(待续)
- python 小模块
- python小模块---zipfile
- python小模块----cookie
- python (小)模块简介
- nodejs模块小例子
- 模块
- 模块
- 模块
- 模块
- 模块
- 模块
- 【iOS沉思录】KVC与KVO,NSNotification通知
- 学习GO第一天,自我感觉可麻利的开干了-GO语言配置、开发、服务器部署
- 制作整个网站镜像的shell脚本
- 练习
- Android学习笔记(7)-读取系统联系人
- 数据库模块模块 小扳手
- 嵌入式linux系统中添加FTP和SSH服务过程记录
- HDU 1248 寒冰王座(完全背包)
- Hadoop2.5.2学习03--设置本地服务器模式出现的问题
- Hdu 6011 Lotus and Characters【贪心+暴力】
- Linux 命令行小技巧-持续更新
- CoordubatirLayout简单使用2,移动自定义布局改变动画
- No typehandler found for property creationDate
- 第12天(就业班) 课程回顾、session案例、通讯录、jsp入门、指令