PHP-单例模式封装PDO,简化数据库查询、插入、更新

简化PDO方式操作数据库,封装成read和write两个常用方法,以及batchWrite批量数据操作(预处理+事物)、exec批量数据(事物),减少工作量

一、数据库相关信息
数据库名为:dian
数据表名:dian_users 有user和pass字段

二、实现代码
1.封装类文件名 db.class.php

<?php

class  PDOTool
{
    protected static $_instance = null;
    protected static $dbConfig;
    protected $dsn;
    protected $dbh;

    /**
     * 配置数据库信息
     */
    private static function setDBConfig()
    {
        $DB = array(
            "host" => "localhost",        //数据库地址
            "dbname" => "newsqxt",        //数据库名
            "user" => "root",            //数据库帐号
            "password" => "Gepoint"    //数据库密码
        );
        self::$dbConfig = $DB;
    }

    /**
     * 构造方法
     */
    private function __construct($dbHost, $dbName, $dbUser, $dbPasswd)
    {
        try {
            $this->dsn = 'mysql:host=' . $dbHost . ';dbname=' . $dbName;
            $this->dbh = new PDO($this->dsn, $dbUser, $dbPasswd, array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
            $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->dbConfig = self::setDBConfig();
        } catch (PDOException $e) {
            die(json_encode(self::result(false, $e->getMessage(), $e)));
        }
    }

    /**
     * 单例模式创建PDOTool类
     * @return PDOTool
     */
    private static function getInstance()
    {
        if (self::$_instance === null) {
            //加载数据库配置信息
            self::setDBConfig();
            self::$_instance = new self(self::$dbConfig['host'], self::$dbConfig['dbname'], self::$dbConfig['user'], self::$dbConfig['password']);
        }
        return self::$_instance;
    }

    /**
     * 开放数据库名信息,写sql语句有时候需要数据库名,具体看个人需求
     * @return  string  返回数据库名
     */
    public static function getDBName()
    {
        return self::getInstance()->dbConfig['dbname'];
    }

    /**
     * 数据读取方法
     * @param $sqlStr   string\sql查询语句
     * @param $dataArray    array\查询的参数列表
     * @return  array
     */
    public static function read($sqlStr, $dataArray)
    {
        try {
            $pdo = self::getInstance()->dbh;

            //执行预处理语句
            $stmt = $pdo->prepare($sqlStr);

            if ($dataArray != null && count($dataArray) > 0) {
                $stmt->execute($dataArray);
            } else {
                $stmt->execute();
            }

            //以数组形式返回
            $arr = $stmt->fetchAll(PDO::FETCH_ASSOC);

            //判读数组是否为空
            $isEmpty = !empty($arr);

            return self::result($isEmpty, $isEmpty ? "查询成功!" : "查询结果为空", $arr);
        } catch (PDOException $e) {
            die(json_encode(self::result(false, $e->getMessage(), $e)));
        }
    }

    /**
     * 数据插入、更新、删除方法
     * @param   $sqlStr  string\sql操作语句
     * @param   $dataArray array\数据参数列表
     * @return   array
     */
    public static function write($sqlStr, $dataArray)
    {
        try {
            $pdo = self::getInstance()->dbh;

            //执行预处理语句
            $stmt = $pdo->prepare($sqlStr);

            if ($dataArray != null && count($dataArray) > 0) {
                $stmt->execute($dataArray);
            } else {
                $stmt->execute();
            }

            //获取影响行数
            $affectRow = $stmt->rowCount();

            $isSuccess = $affectRow > 0;

            return self::result($isSuccess, $isSuccess ? "操作成功!" : "操作失败", array("affectedRows" => $affectRow));
        } catch (PDOException $e) {
            die(json_encode(self::result(false, $e->getMessage(), $e)));
        }
    }

    /**
     * 批量数据操作-事物操作
     * @param $sql string\需要执行的sql语句
     * @param $bathDataArray array\与sql语句相对应的参数列
     * @return array
     */
    public static function batchWrite($sql, $bathDataArray)
    {
        try {
            $pdo = self::getInstance()->dbh;
            //开启事物
            $pdo->beginTransaction();

            //预处理语句
            $stmt = $pdo->prepare($sql);

            $dataArrayLenth = count($bathDataArray);

            //影响行数
            $affectRow = 0;

            for ($i = 0; $i < $dataArrayLenth; $i++) {
                //执行预处理语句
                if ($stmt->execute($bathDataArray[$i])) {
                    $affectRow++;
                };
            }

            //执行事物的提交操作
            $pdo->commit();

            $isSuccess = $affectRow > 0;

            return self::result($isSuccess, $isSuccess ? "操作成功!" : "操作失败", array("affectedRows" => $affectRow));
        } catch (PDOException $e) {
            $pdo->rollBack();
            die(json_encode(self::result(false, $e->getMessage(), $e)));
        }
    }

    /**
     * 可用于执行一个完整导出的sql文件,通常用于安装导入数据库信息。
     * @param $sqlArray array\Sql语句
     * @return array
     */
    public static function exec($sqlArray)
    {
        try {
            $pdo = self::getInstance()->dbh;

            //开启事物
            $pdo->beginTransaction();

            //计算数组长度
            $sqlLength = count($sqlArray);

            //执行状态
            $statusData = array();

            //失败条数
            $errorCount = 0;

            //失败信息数组
            $errorData = array();

            //sql语句是否全部执行通过
            $isPass = true;
            for ($i = 0; $i < $sqlLength; $i++) {
                if ($sql = trim($sqlArray[$i])) {
                    $pdo->exec($sql);
                    $code = $pdo->errorCode();
                    if ($code != 00000) {
                        $errorData[$errorCount]["errorCode"] = $code;
                        $errorData[$errorCount]['errorSql'] = $sql;
                        $errorCount++;
                        $isPass = false;
                    }
                }
            }

            if (!$isPass) {
                $pdo->rollBack();
                $resultArray = array("errorRows" => $errorCount, "errorData" => $errorData);
                return self::result(false, "执行失败,事物回滚!", $resultArray);
            }

            //提交事务
            $pdo->commit();

            return self::result(true, "操作成功!", array("affectedRows" => $i));
        } catch (PDOException $e) {
            //执行事物的回滚操作
            $pdo->rollBack();
            die(json_encode(self::result(false, $e->getMessage(), $e)));
        }
    }

    /**
     * 返回执行结果
     * @param $isSuccess boolean\true成功、false失败
     * @param $msg  string\信息描述
     * @param $object   object\数据对象
     * @return array    array\操作结果
     */
    private static function result($isSuccess, $msg, $object)
    {
        return array('success' => $isSuccess, 'msg' => $msg, 'data' => $object);
    }
}

?>



2.测试文件名 sql.php

<?php
header("Content-type: text/html; charset=utf-8");
include("db.class.php");   //引入封装的数据库操作类

$dbName = PDOTool::getDBName();   //获取数据库名

//查询数据库信息-----------------------------
//查询方法1 :不带数据的数组
//$sql = "SELECT * FROM `".$dbName."`.`dian_users` "; //1.不带参数的查询
//$mData = array();				//1.不带参数查询的数组,数组传空值

//查询方法2 :带数据的数组
$sql = "SELECT * FROM `".$dbName."`.`dian_users` where `user` = ? and pass = ? "; //2.带参数的查询
$mData = array("111","aaa");	//2.带参数查询的数组,数组值与需要查询的字段名字对应,111代表user的值	,aaa表示pass的值

//用多维数组存储查询结果-注意如果没有查询到数据,返回的数组为空,但长度是1,不是0
$arrResult = PDOTool::read($sql,$mData);//调用查询方法,传入sql语句、数组参数

//输出结果
var_dump($arrResult);

//插入一个用户信息-----------------------
$sql = "INSERT INTO `".$dbName."`.`dian_users`(`user`, `pass`) VALUES (?, ?)"; 

//创建数组,存放需要传入的值,注意:数据的位置必须和数据字段的位置对应,不能错乱,有几个问号就有几个数据
$mData = array("555","fff"); //插入一个用户名为555,密码为fff的帐号

//调用方法写入数据
$ret= PDOTool::write($sql,$mData);     //传入sql语句和数据参数,返回值是bool类型

if($ret['success']==true){
    echo "写入成功";
}else{
    echo "写入失败";
}
?>

3.返回结果类型-数组
read返回值:success:成功true、失败false

{
    "success": true,
    "msg": "查询成功!",
    "data": [查询出来的数据]
}

write返回值:success:成功true、失败false

{
    "success": true,
    "msg": "操作成功!",
    "data": {
        "affectedRows": 17
    }
}

exec执行成功结果和write一致
exec执行失败返回值:

{
    "success": false,
    "msg": "执行失败,事物回滚!",
    "data": {
        "errorRows": 执行出错语句条数,
        "errorData": [
            {
                "errorCode": "出错响应码",
                "errorSql": "出错sql语句1"
            },
            {
                "errorCode": "出错响应码",
                "errorSql": "出错sql语句2"
            }
        ]
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值