基于pdo-mysql实现的简单orm

2 篇文章 0 订阅

通过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);     
        }

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

     

自主封装的PHP ORM框架,面向对象的PDO数据库操作,API框架,支持Get/Post/Put/Delete多种请求方式。 代码示例: <?php use Models\User; require '../application.php'; require '../loader-api.php'; //适合查询,如:获取用户列表或者单个用户信息 execute_request(HttpRequestMethod::Get, function() { $action = request_action(); //判断是否存在 if ($action == 1) { list($type, $value) = filter_request(array( request_int('type', 1, 2, 3), //1.用户名 2.邮箱 3.手机号 request_string('value'))); $type_field_map = array( 1 => User::$field_username, 2 => User::$field_email, 3 => User::$field_phone ); if ($type == 2 && !is_email($value) || $type == 3 && !is_mobilephone($value)) { die_error(USER_ERROR, $type_field_map[$type]['name'] . '格式无效'); } $user = new User(); $user->set_where_and($type_field_map[$type], SqlOperator::Equals, $value); $result = $user->exists(create_pdo()); echo_result($result ? 1 : 0); //存在返回1,不存在返回0 } //查询单条信息 if ($action == 2) { list($userid) = filter_request(array( request_userid())); //查询单条数据 $user = new User($userid); //set_query_fields可以指定查询字段,下面两种写法均可 //$user->set_query_fields('userid, username, email'); //$user->set_query_fields(array(User::$field_userid, User::$field_username, User::$field_email)); //还可设置where条件进行查询 //$user->set_where_and(User::$field_status, SqlOperator::Equals, 3); //$user->set_where_and(User::$field_truename, SqlOperator::IsNullOrEmpty); //$user->set_where_and(User::$field_age, SqlOperator::In, array(27, 29)); //$user->set_where_and(User::$field_regtime, SqlOperator::LessThan, '-6 month'); //创建数据库连接 $db = create_pdo(); $result = $user->load($db, $user); //也可以用Model类的静态方法 //$result = Model::load_model($db, $user, $user); if (!$result[0]) die_error(PDO_ERROR_CODE, '获取用户信息时数据库错误'); if (!$user) di
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值