zoukankan      html  css  js  c++  java
  • 读写分离MYSQL类

    2014年4月27日 12:34:08

    概述:

    1. 根据sql语句判断是连接读库还是写库

    2. 链式调用$this->where()->get()

    3. 不同的主机对应不同的实例, 不再多次new

      1 <?php
      2 class DBRWmysql
      3 {
      4     private static $Instance = null;
      5 
      6     private $links = array();//链接数组
      7     private $link = null; //当前连接
      8     public $dbType = 'read';
      9 
     10     public $_host=''; //数据库所在主机名
     11     public $_database = '';//当前数据库名
     12     public $_tablename = '';//当前表的表名
     13     public $_dt ='';//database.tablename
     14     public $isRelease = 0; //查询完成后是否释放
     15 
     16     public $fields = '*';
     17     public $arrWhere = [];
     18     public $order = '';
     19     public $arrOrder = [];
     20     public $limit = '';
     21     public $sql = '';
     22 
     23     public $rs;//结果集
     24 
     25     private function __construct($database='', $tablename='', $isRelease=0)
     26     {
     27         $this->_database = $database;//database name
     28         $this->_tablename = $tablename;//table name
     29         $this->_dt = "`{$this->_database}`.`{$this->_tablename}`";
     30         $this->isRelease = $isRelease;
     31     }
     32 
     33     public static function getInstance($database='', $tablename='', $isRelease=0)
     34     {
     35         if (self::$Instance == null) {
     36             self::$Instance = new DBRWmysql($database, $tablename, $isRelease);
     37         }
     38 
     39         self::$Instance->_database  = $database;
     40         self::$Instance->_tablename = $tablename;
     41         self::$Instance->_dt        = "`{$database}`.`{$tablename}`";
     42         self::$Instance->isRelease  = $isRelease;
     43 
     44         return self::$Instance;
     45     }
     46 
     47     //如果主机没变,并且已经存在MYSQL连接,就不再创建新的连接
     48     //如果主机改变,就再生成一个实例创建一个连接
     49     //type == 'write'或'read'
     50     public function getLink($type)
     51     {
     52         $this->dbType = $$type;
     53 
     54         //随机选取一个数据库连接(区分读写)
     55         $dbConfig = DBConfig::$$type;
     56         $randKey = array_rand($dbConfig);
     57         $config = $dbConfig[$randKey];
     58 
     59         //链接数据库
     60         $host = $config['host'];
     61         $username = $config['username'];
     62         $password = $config['password'];
     63 
     64         if (empty($this->links[$host])) {
     65             $this->_host = $host;
     66             $this->links[$host] = new mysqli($host, $username, $password);
     67             if($this->links[$host]->connect_error) {
     68                 $this->error($this->links[$host]->connect_error);
     69             }
     70         }
     71 
     72         //初始化链接
     73         $this->link = $this->links[$host];
     74         $this->link->query("set names utf8mb4;"); //支持emoji表情
     75         $this->link->query("use {$this->_database};");
     76     }
     77     
     78     public function getCurrentLinks()
     79     {
     80         return $this->links;
     81     }
     82     
     83     //析构函数
     84     public function __destruct()
     85     {
     86         foreach ($this->links as $v) {
     87             $v->close();
     88         }
     89     }
     90     
     91     //查询封装
     92     public function query($sql)
     93     {
     94         $this->sql = $sql;
     95         if (strpos($sql, 'select') !== false) {
     96             $this->getLink('read');//读库
     97         } else {
     98             $this->getLink('write');//写库
     99         }
    100 
    101         $this->rs = $this->link->query($sql);
    102         ($this->rs === false) && $this->error('sql error: '.$sql.PHP_EOL.$this->link->error);
    103 
    104         //查询完成后释放链接, 并删除链接对象
    105         if ($this->isRelease) {
    106             $this->link->close();
    107             unset($this->links[$this->_host]);
    108         }
    109         return $this->rs;
    110     }
    111     
    112 
    113     //
    114     public function insert($arrData)
    115     {
    116         foreach ($arrData as $key=>$value) {
    117             $fields[] = $key;
    118             $values[] = "'".$value."'";
    119             // $fields[] = '`'.$key.'`';
    120             // $values[] = "'".$value."'";
    121         }
    122         $strFields = implode(',', $fields);
    123         $strValues = implode(',', $values);
    124         $sql = "insert into {$this->_dt} ($strFields) values ($strValues)";
    125         $this->query($sql);
    126         $insert_id = $this->link->insert_id;
    127         
    128         return $insert_id;
    129     }
    130 
    131     //
    132     public function replace($arrData)
    133     {
    134         foreach ($arrData as $key=>$value) {
    135             $fields[] = $key;
    136             $values[] = "'{$value}'";
    137         }
    138         $strFields = implode(',', $fields);
    139         $strValues = implode(',', $values);
    140         $sql = "replace into {$this->_dt} ($strFields) values ($strValues)";
    141         
    142         $this->query($sql);
    143         
    144         return $this->link->insert_id;
    145     }
    146     
    147     //148     //每次插入多条记录
    149     //每条记录的字段相同,但是值不一样
    150     public function insertm($arrFields, $arrData)
    151     {
    152         foreach ($arrFields as $v) {
    153             // $fields[] = "`{$v}`";
    154             $fields[] = $v;
    155         }
    156         
    157         foreach ($arrData as $v) {
    158             $data[] = '('.implode(',', $v).')';
    159         }
    160         
    161         $strFields = implode(',', $fields);
    162         $strData = implode(',', $data);
    163         
    164         $sql = "insert into {$this->_dt} ($strFields) values {$strData}";
    165         
    166         $this->query($sql);
    167         
    168         return $this->link->insert_id;
    169     }
    170     
    171     //
    172     public function delete()
    173     {
    174         $where = $this->getWhere();
    175         $limit = $this->getLimit();
    176 
    177         $sql = " delete from {$this->_dt} {$where} {$limit}";
    178         $this->query($sql);
    179         return $this->link->affected_rows;
    180     }
    181     
    182     //
    183     public function update($data)
    184     {
    185         $where = $this->getWhere();
    186 
    187         $arrSql = array();
    188         foreach ($data as $key=>$value) {
    189             $arrSql[] = "{$key}='{$value}'";
    190         }
    191         $strSql = implode(',', $arrSql);
    192         
    193         $sql = "update {$this->_dt} set {$strSql} {$where} {$this->limit}";
    194         
    195         $this->query($sql);
    196         
    197         return $this->link->affected_rows;
    198     
    199     }
    200 
    201     //获取总数
    202     public function getCount()
    203     {
    204         $where = $this->getWhere();
    205         
    206         $sql = " select count(1) as n from {$this->_dt} {$where} ";
    207         $resault = $this->query($sql);
    208         
    209         ($resault===false) && $this->error('getCount error: '.$sql);
    210         
    211         $arrRs = $this->rsToArray($resault);
    212         
    213         $num = array_shift($arrRs);
    214         return $num['n'];
    215     }
    216     
    217     //将结果集转换成数组返回
    218     //如果field不为空,则返回的数组以$field为键重新索引
    219     public function rsToArray($field = '')
    220     {
    221         $arrRs = $this->rs->fetch_all(MYSQLI_ASSOC); //该函数只能用于php的mysqlnd驱动
    222         $this->rs->free();//释放结果集
    223         
    224         if ($field) {
    225             $arrResult = [];
    226             foreach ($arrRs as $v) {
    227                 $arrResult[$v[$field]] = $v;
    228             }
    229             return $arrResult;
    230         }
    231         
    232         return $arrRs;
    233     }
    234     
    235     //给字段名加上反引号
    236     public function qw($strFields)
    237     {
    238         $strFields = preg_replace('#s+#', ' ', $strFields);
    239         $arrNewFields = explode(' ', $strFields );
    240         $arrNewFields = array_filter($arrNewFields);
    241         foreach ($arrNewFields as $k => $v) {
    242             $arrNewFields[$k]= '`'.$v.'`';
    243         }
    244         return implode(',', $arrNewFields);
    245     }
    246 
    247     //处理入库数据,将字符串格式的数据转换为...格式(未实现)
    248     public function getInsertData($strData)
    249     {
    250         // $bmap = "jingdu,$jingdu weidu,$weidu content,$content";
    251     }
    252 
    253     //select in
    254     //arrData 整数数组,最好是整数
    255     public function select_in($key, $arrData, $fields='')
    256     {
    257         $fields = $fields ? $fields : '*';
    258         sort($arrData);
    259         $len = count($arrData);
    260         $cur = 0;
    261         $pre = $arrData[0];
    262 
    263         $new = array('0' => array($arrData[0]));
    264         for ($i = 1; $i < $len; $i++) {
    265             if (($arrData[$i] - $pre) == 1 ) {
    266                 $new[$cur][] = $arrData[$i];
    267             } else {
    268                 $cur = $i;
    269                 $new[$cur][] = $arrData[$i];
    270             }
    271             $pre = $arrData[$i];
    272         }
    273 
    274         $arrSql = array();
    275         foreach ($new as $v) {
    276             $len = count($v) - 1;
    277             if ($len) {
    278                 $s = $v[0];
    279                 $e = end($v);
    280                 $sql = "(select $fields from {$this->_dt} where $key between $s and $e)";
    281             } else {
    282                 $s = $v[0];
    283                 $sql = "(select $fields from {$this->_dt} where $key = $s)";
    284             }
    285 
    286             $arrSql[] = $sql;
    287         }
    288         
    289         $strUnion = implode(' UNION ALL ', $arrSql);
    290         $res = $this->query($strUnion);
    291         return $this->rstoarray($res);
    292     }
    293     
    294     //where in
    295     public function setWhereIn($key, $arrData)
    296     {
    297         if (empty($arrData)) {
    298             $str = "(`{$key}` in ('0'))";
    299             $this->addWhere($str);
    300             return $str;
    301         }
    302         
    303         foreach ($arrData as &$v) {
    304             $v = "'{$v}'";
    305         }
    306         $str = implode(',', $arrData);
    307         $str = "(`{$key}` in ( {$str} ))";
    308         
    309         $this->addWhere($str);
    310         
    311         return $this;
    312     }
    313     
    314     //where in
    315     public function setWhere($arrData)
    316     {
    317         if (empty($arrData)) {
    318             return '';
    319         }
    320         
    321         foreach ($arrData as $k => $v) {
    322             $str = "(`{$k}` = '{$v}')";
    323             $this->addWhere($str);
    324         }
    325         
    326         return $this;
    327     }
    328     
    329     //between and
    330     public function setWhereBetween($key, $min, $max)
    331     {
    332         $str = "(`{$key}` between '{$min}' and '{$max}')";
    333         $this->addWhere($str);
    334         return $this;
    335     }
    336     
    337     //where a>b
    338     public function setWhereBT($key, $value)
    339     {
    340         $str = "(`{$key}` > '{$value}')";
    341         $this->addWhere($str);
    342         return $this;
    343     }
    344     
    345     //where a<b
    346     public function setWhereLT($key, $value)
    347     {
    348         $str = "(`{$key}` < '{$value}')";
    349         $this->addWhere($str);
    350         return $this;
    351     }
    352     
    353     //组装where条件
    354     public function addWhere($where)
    355     {
    356         $this->arrWhere[] = $where;
    357     }
    358     
    359     //获取最终查询用的where条件
    360     public function getWhere()
    361     {
    362         if (empty($this->arrWhere)) {
    363             return 'where 1';
    364         } else {
    365             return 'where '.implode(' and ', $this->arrWhere);
    366         }
    367     }
    368     
    369     //以逗号隔开
    370     public function setFields($fields)
    371     {
    372         $this->fields = $fields;
    373         return $this;
    374     }
    375     
    376     // order by a desc
    377     public function setOrder($order)
    378     {
    379         $this->arrOrder[] = $order;
    380         return $this;
    381     }
    382     
    383     //获取order语句
    384     public function getOrder()
    385     {
    386         if (empty($this->arrOrder)) {
    387             return '';
    388         } else {
    389             $str = implode(',', $this->arrOrder);
    390             $this->order = "order by {$str}";
    391         }
    392         return $this->order;
    393     }
    394     
    395     //e.g. '0, 10'
    396     //用limit的时候可以加where条件优化:select ... where id > 1234 limit 0, 10 
    397     public function setLimit($limit)
    398     {
    399         $this->limit = 'limit '.$limit;
    400         return $this;
    401     }
    402 
    403     //直接查询sql语句, 返回数组格式
    404     public function arrQuery($sql, $field='')
    405     {
    406         $this->query($sql);
    407         $this->clearQuery();
    408         ($this->rs===false) && $this->error('select error: '.$sql);
    409         return $this->rsToArray($field);
    410     }
    411     
    412     //如果 $field 不为空, 则返回的结果以该字段的值为索引
    413     //暂不支持join
    414     public function get($field='')
    415     {
    416         $where = $this->getWhere();
    417         $order = $this->getOrder();
    418         
    419         $sql = " select {$this->fields} from {$this->_dt} {$where} {$order} {$this->limit} ";
    420         return $this->arrQuery($sql, $field);
    421     }
    422     
    423     //获取一条记录
    424     public function getOne()
    425     {
    426         $this->setLimit(1);
    427         $rs = $this->get();
    428 
    429         return !empty($rs) ? $rs[0] : [];
    430     }
    431     
    432     //获取一条记录的某一个字段的值
    433     public function getOneField($field)
    434     {
    435         $this->setFields($field);
    436         $rs = $this->getOne();
    437 
    438         return !empty($rs[$field]) ? $rs[$field] : '';
    439     }
    440 
    441     //获取数据集中所有某个字段的值
    442     public function getFields($field)
    443     {
    444         $this->setFields($field);
    445         $rs = $this->get();
    446         $result = [];
    447         foreach ($rs as $v) {
    448             $result[] = $v[$field];
    449         }
    450         unset($rs);
    451 
    452         return $result;
    453     }
    454     
    455     //清除查询条件
    456     //防止干扰下次查询
    457     public function clearQuery()
    458     {
    459         $this->fields = '*';
    460         $this->arrWhere = [];
    461         $this->order = '';
    462         $this->arrOrder = [];
    463         $this->limit = '';
    464     }
    465 
    466     //断开数据库连接
    467     public function close()
    468     {
    469         $this->link->close();
    470     }
    471 
    472     //事务
    473     //自动提交开关
    474     public function autocommit($bool)
    475     {
    476         $this->link->autocommit($bool);
    477     }
    478 
    479     //事务完成提交
    480     public function commit()
    481     {
    482         $this->link->commit();
    483     }
    484 
    485     //回滚
    486     public function rollback()
    487     {
    488         $this->link->rollback();
    489     }
    490 
    491 
    492     //输出错误sql语句
    493     public function error($sql)
    494     {
    495         //if (IS_TEST) {}
    496         exit($sql);
    497     }
    498 }

    最后编辑: 2016年4月16日 19:45:14 星期六

  • 相关阅读:
    微服务2:微服务全景架构
    SystemVerilog语言简介
    Slip打包与解包及MATLAB程序
    恶性卷积码
    通信原理之调制解调(2)QPSK
    FPGA仿真只适合开发定制IP的设计师?
    用CCS开发DSP应用程序的代码结构、加电装载及在线编程
    符号能量问题
    该如何选择?
    无线通信距离的计算
  • 原文地址:https://www.cnblogs.com/iLoveMyD/p/3693939.html
Copyright © 2011-2022 走看看