基于pdo-mysql实现的简单orm

来源:互联网 发布:淘宝买家真实姓名隐藏 编辑:程序博客网 时间:2024/06/03 09:56

通过pdo-mysql实现了一个简单的orm数据库操作实现类。

具体的代码如下:

    /**     * 基于pdo-mysql的ORM实现类     * @author lyt     *     */    abstract class Base_Sql {        /**         * 简单封装pdo-mysql的数据库操作对象         * @var Base_Db         */        protected static $_db = null;                /**         * 表名         * @var string         */        protected $_table = null;                /**         * 链式sql操作的结果集         * @var array         */        protected $_rs = [];                /**         * 是否开启自动执行及链式操作         * @var boolean         */        protected $_auto = false;                      protected final function __construct() {           $this->initTable();        }                /**         * 子类实现单例模式         */        public abstract static function getInstance();        /**         * 子类实现方法,初始化表名         */        protected abstract function initTable();               /**         * 开启自动执行sql语句,并支持链式调用         * @return Base_Sql         */        public function auto() {            if (is_null(self::$_db)) {                self::$_db = new Base_Db();            }            if (!$this->_auto) {                $this->_auto = true;                $this->_rs = [];            }            return $this;        }                /**         * 关闭自动执行,关闭链式调用模式,以数组的形式返回多次执行的结果         * @return array 链式执行sql语句的结果集         */        public function exec() {            $this->_auto = false;            return $this->_rs;        }                /**         * 拼装sql查询语句,如果自动执行开启,则立即执行当前sql,保存查询结果,并返回当前实例以支持链式调用;           * 直到exec()方法执行,返回所有操作的结果集。         * @param array $where_params where查询条件,仅支持 “=” 条件,键名为字段名称         * @param array $limit_params limit条件         * @param array $order_params order by条件,键名为字段名称,值为'desc' 或 'asc',不限制大小写,否则忽略该排序字段         * @param array $column_name 要显示的字段(列)列表         * @return Base_Sql|array 如果没有开启自动执行,返回sql语句和相应的参数列表         */        public function buildQuery(array $where_params, array $limit_params = [], array $order_params = [], array $column_name = ['*']) {            $where_condition = $this->whereCondition($where_params);                $order_condition = $this->orderCondition($order_params);            $limit_condition = $this->limitCondition($limit_params);            $sql = "select " . implode(', ', $column_name) . " from {$this->_table} " . $where_condition . $order_condition . $limit_condition;                        $build = [                'sql' => $sql,                'params' => array_merge(array_values($where_params), array_values($limit_params))            ];            if ($this->_auto) {                $this->_rs[] = self::$_db->query($build['sql'], $build['params']);                return $this;            }            return $build;        }                /**         * 拼装sql插入语句,如果自动执行开启,则立即执行当前sql,保存插入操作影响的行数,并返回当前实例以支持链式调用;         * @param array $model 要保存的对象,键名对应字段名         * @return Base_Sql|array 如果没有开启自动执行,返回sql语句和相应的参数列表         */        public function bulidSave(array $model) {            $keys = array_keys($model);            $sql = "insert into {$this->_table}(" . implode(', ', $keys) . " ) values(:"                 . implode(', :', $keys) . " )";                        $build = [                'sql' => $sql,                'params' => $model            ];            if ($this->_auto) {                $this->_rs[] = self::$_db->execute($build['sql'], $build['params']);                return $this;            }            return $build;                    }                /**         * 拼装sql删除语句,如果自动执行开启,则立即执行当前sql,保存删除操作影响的行数,并返回当前实例以支持链式调用;         * @param array $where_params where查询条件,仅支持 “=” 条件,键名为字段名称         * @return Base_Sql|array 如果没有开启自动执行,返回sql语句和相应的参数列表         */        public function bulidDelete(array $where_params) {            $where_condition = $this->whereCondition($where_params);            $sql = "delete from {$this->_table} " . $where_condition;                        $build = [                'sql' => $sql,                'params' => $where_params            ];            if ($this->_auto) {                $this->_rs[] = self::$_db->execute($build['sql'], $build['params']);                return $this;            }            return $build;                    }                /**         * 拼装sql修改语句,如果自动执行开启,则立即执行当前sql,保存修改操作影响的行数,并返回当前实例以支持链式调用;         * @param array $model 要修改的相应字段         * @param array $where_params where查询条件,仅支持 “=” 条件,键名为字段名称         * @return Base_Sql|array 如果没有开启自动执行,返回sql语句和相应的参数列表         */        public function buildUpdate(array $model, array $where_params) {            $where_condition = $this->whereCondition($where_params);            $sql = "update {$this->_table} set " . implode(' = ? , ', array_keys($model)) . " = ? ". $where_condition;                       $build = [                'sql' => $sql,                'params' => array_merge(array_values($model), array_values($where_params))            ];            if ($this->_auto) {                $this->_rs[] = self::$_db->execute($build['sql'], $build['params']);                return $this;            }            return $build;                    }               /**         * 拼装where条件查询子句         * @param array $where_params         * @return string         */        private function whereCondition(array $where_params) {            if (empty($where_params)) {                return null;            }            return "where " . implode(' = ? and ', array_keys($where_params)) . " = ? ";        }                /**         * 拼装order by条件查询子句         * @param array $order_params         * @return string         */        private function orderCondition(array &$order_params) {            if (empty($order_params)) {                return null;            }            $order = [];            array_walk($order_params, function($value, $key) use (&$order){                if(is_string($key) && in_array($value, ['desc', 'asc'])) {                    $order[] = $key . " " . $value;                }            });            return "order by " . implode(', ', $order) . " ";        }                /**         * 拼装limit条件查询子句         * @param array $limit_params         * @return string          */        private function limitCondition(array $limit_params) {            if (empty($limit_params) || count($limit_params) != 2) {                return null;            }            return "limit ?, ? ";        }                public function __destruct() {                   }    }
    /**     * 数据库操作类,封装pdo-mysql     * @author lyt     *     */    class Base_Db {        private $_pdo = null;        private $_stmt = null;                public function __construct() {            $this->_pdo = new PDO('mysql:dbname=db_app;host=127.0.0.1:3306', 'root', '123456');            $this->_pdo->query('set names utf8');        }                /**         * 执行数据库查询操作         * @param string $sql         * @param array $params         * @return array 查询的结果集,以关联数组的形式返回         */        public function query($sql, array $params = []) {            $this->basic($sql, $params);            return $this->getQueryList();        }                /**         * 执行数据库增、删、改操作         * @param string $sql         * @param array $params         * @return number|false 影响的行数,操作失败返回false         */        public function execute($sql, array $params = []) {            $this->basic($sql, $params);            return $this->affectedRows();        }                /**         * 获得上一次插入操作生成的id(当表中有自增字段时使用)         * @param string $sql         * @param array $params         */        public function getId($sql, array $params = []) {            $this->basic($sql, $params);            return $this->_pdo->lastInsertId();        }                /**         * 对查询的结果集逐行操作         * @param string $sql         * @param callable $func 执行操作的回调函数         * @param array $params         * @return array 经过处理后的结果集         */        public function packData($sql, callable $func, $params = []) {            $this->basic($sql, $params);            return $this->pack($func);        }                private function setPreparedStatement($sql) {            $this->_stmt = $this->_pdo->prepare($sql);        }                /**         * 动态参数绑定         * @param array $params         * @param PDOStatement $stmt         */        private function setParams(array $params, PDOStatement &$stmt = null) {            is_null($stmt) && $stmt = $this->_stmt;            if (!empty($params)) {                array_walk($params, function($value, $key) use(&$stmt){                    $data_type = PDO::PARAM_STR;                     if (is_int($value)) {                        $data_type = PDO::PARAM_INT;                    } elseif (is_bool($value)) {                        $data_type = PDO::PARAM_BOOL;                    }                    $key = is_int($key)? $key + 1: ':' . $key;                    $stmt->bindParam($key, $value, $data_type);                });            }        }                private function executeStatement() {            $this->_stmt->execute();        }                private function affectedRows() {            if ($this->_stmt->errorCode() != PDO::ERR_NONE) {                //var_dump($this->_stmt->errorInfo());                return false;            }            return $this->_stmt->rowCount();        }                private function getQueryList($fetch_type = PDO::FETCH_ASSOC) {            !is_int($fetch_type) && $fetch_type = PDO::FETCH_ASSOC;            return $this->_stmt->fetchAll($fetch_type);        }                private function pack(callable $func, PDOStatement &$stmt = null) {            is_null($stmt) && $stmt = $this->_stmt;            $rs = [];            while (($row = $stmt->fetch(PDO::FETCH_ASSOC)) != null) {                $func($row);                $rs[] = $row;            }            return $rs;        }                private function basic($sql, array $params = []) {            $this->setPreparedStatement($sql);            $this->setParams($params);            $this->executeStatement();        }                public function __destruct() {            if(!is_null($this->_stmt) && $this->_stmt instanceof PDOStatement) {                $this->_stmt->closeCursor();                unset($this->_stmt);            }            unset($this->_pdo);        }    }
现在有一个子类Impl_User继承了BaseSql这个基类,对应的是一张user表,我们通过下面这段代码进行测试,观察执行的结果。
        public function sqlAction() {            $user_sql = Impl_User::getInstance();            $rs_user = $user_sql->auto()->buildQuery([], [0, 1])->buildQuery(['userId' => '100749365'])                ->buildQuery([], [0, 1], ['userCredit' => 'desc'], ['userId'])->exec();            var_dump($rs_user);             }

运行的结果如下图,符合预期的效果!

     

0 0