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 星期六

转载于:https://www.cnblogs.com/iLoveMyD/p/3693939.html

读写分离MYSQL类相关推荐

  1. mysql 读写分离缺点6_6\MySQL 主从同步 , MySQL 读写分离 , MySQL 性能调优

    6\MySQL 主从同步 , MySQL 读写分离 , MySQL 性能调优 day06 一,mysql 主从同步 二,数据读写分离 三,MySQL 优化 ++++++++++++++++++++++ ...

  2. 数据切分——Atlas读写分离Mysql集群的搭建

    关于数据切分的原理可以参见博客: http://blog.csdn.net/jhq0113/article/details/44226789 关于Atlas的介绍可以参见博客: http://blog ...

  3. 读写分离mysql数据库mariadb_MariaDB数据库读写分离实现(一):mysql-proxy的使用

    一.mysql-proxy简介 MySQL-Proxy是处在你的MySQL数据库客户和服务端之间的程序,它还支持嵌入性脚本语言Lua.这个代理可以用来分析.监控和变换(transform)通信数据,它 ...

  4. Atlas读写分离Mysql集群的搭建

    MySQL + Atlas --- 部署读写分离 http://www.cnblogs.com/yyhh/archive/2015/12/29/5084844.html 转载于:https://blo ...

  5. MySQL+Amoeba实现数据库主从复制和读写分离

    MySQL读写分离是在主从复制的基础上进一步通过在master上执行写操作,在slave上执行读操作来实现的.通过主从复制,master上的数据改动能够同步到slave上,从而保持了数据的一致性.实现 ...

  6. mysql driver 读写分离_Mysql主从复制和读写分离实践

    1.主从复制 原理 MySQL之间数据复制的基础是二进制日志文件(binary log file).一台MySQL数据库一旦启用二 进制日志后,其作为master,它的数据库中所有操作都会以" ...

  7. 【DB宝42】MySQL高可用架构MHA+ProxySQL实现读写分离和负载均衡

    文章目录 一.MHA+ProxySQL架构 二.快速搭建MHA环境 2.1 下载MHA镜像 2.2 编辑yml文件,创建MHA相关容器 2.3 安装docker-compose软件(若已安装,可忽略) ...

  8. 通过proxysql实现MySQL主从读写分离

    原文: https://www.yuque.com/wei01/wql35u/wbgk1a 自行部署MySQL主从环境 安装proxysql # 安装依赖包 yum install gnutls pe ...

  9. SpringBoot下MySQL的读写分离

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 02-下篇-SpringBoot下MySQL的读写分离 dusuanyun 2018-07- ...

  10. mysql+mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离

    数据库性能优化普遍采用集群方式,oracle集群软硬件投入昂贵,今天花了一天时间搭建基于mysql的集群环境. 主要思路 简单说,实现mysql主备复制-->利用mycat实现负载均衡. 比较了 ...

最新文章

  1. SAP MM 不常用事务代码之MBSL - Copy Material Document
  2. 发那科冲压直线搬运机器人_行业应用 | 直线七轴软件配置
  3. 分享我设计的iOS项目目录结构
  4. ListView与.FindControl()方法的简单练习 #2 -- ItemUpdting事件中抓取「修改后」的值
  5. 将一个二维数组合并成一个一维数组
  6. CodeForces 722C Destroying Array
  7. sublime 添加 ConvertToUTF-8
  8. C语言——恶搞之关机代码
  9. 整流、滤波与线性串联型稳压电源工作原理
  10. 客户分段模型(Customer Segmentation Models)
  11. ffmpeg GPU加速压制视频
  12. Mysql中使用逗号隔开多张表生成的表实例
  13. 计算机无法删除ie,ie无法删除怎么办
  14. 日常一记(3)--禁止excel自动运行宏
  15. 微信小程序之发送通知消息(通过openid推送消息给用户)
  16. HTML+CSS静态网页作业:NBA勒布朗詹姆斯篮球明星带js(5页)
  17. android使用wifi连接android手机
  18. java 的 clear 和 compact
  19. springboot时间格式化与空值格式化
  20. 如何删除iso镜像文件?

热门文章

  1. JD_Source Code for problem 1581
  2. Search Insert Position - LeetCode
  3. 配置github的SSH key及GitHub项目上传方式一——使用终端命令行
  4. mysql事件【定时器】
  5. [转] 各种数据类型转换
  6. 【转】J2ME开发环境的建立
  7. springboot情操陶冶-web配置(六)
  8. 进程部分(IPC机制及生产者消费者模型)和线程部分
  9. JS--我发现,原来你是这样的JS:面向对象编程OOP[3]--(JS继承)
  10. Scrum Meeting 2 (2016-12-19 Mon)