ZPF MYSQL数据库链接层

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 2015年3月31日 18:27:34 最后编辑: 2016年4月17日 00:22:00 星期日 读写分离: 根据最终的sql语句来判断是读还是写  (随后会考察并加上一致性哈希) 链式调用: 参看下边用法 如果在一次PHP生命周期内,链接了多台机器, 那么每台机器的连接都会保存下来, 并...

2015年3月31日 18:27:34

最后编辑: 2016年4月17日 00:22:00 星期日

读写分离: 根据最终的sql语句来判断是读还是写  (随后会考察并加上一致性哈希)

链式调用: 参看下边用法

如果在一次PHP生命周期内,链接了多台机器, 那么每台机器的连接都会保存下来, 并且各有一份

如果在高并发下需要连接完就放弃链接, 可以在连接的时候传入参数$isRelease=1 (下边第4行的第二个参数)

用法(代码在某一个model文件中):

 1     //获取论坛一级帖子列表
 2     public function getTiezi()
 3     {
 4         $r = $this->getlink('tiezi')
 5             ->setWhere(['level' => 0])
 6             ->setFields('id, strtime, content, nickname')
 7             ->setOrder('id desc')
 8             ->get();
 9         return $r;
10     }

setWhere, setWhereIn, setWhereBetween, setWhereBT(大于), setWhereLT(小于)

setFields, setOrder, setLimit,

insert, insertm, replace, update, 

getCount,

get: 获取多条记录, getOne:获取一条记录, getOneField:获取某一条记录的某一个字段的值, getFields:获取多条记录的某个字段的所有值

select_in: 通过事先排序,分组,union all, 来优化select in 语句中有大量数字的查询

还没有group by having, 子查询,连结查询的实现, 建议结合redis等nosql, 尽量避免链接查询和子查询

mysql类的完整代码:

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

 

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
存储 SQL 关系型数据库
MySQL Group 字段逗号链接
【4月更文挑战第26天】
|
5月前
|
JavaScript 关系型数据库 MySQL
nodejs链接mysql
nodejs链接mysql
|
5月前
|
关系型数据库 MySQL
Mysql基础第十九天,使用不同类型的链接
Mysql基础第十九天,使用不同类型的链接
39 0
Mysql基础第十九天,使用不同类型的链接
|
12月前
|
关系型数据库 MySQL Linux
MySQL数据库----------安装anaconda---------python与数据库的链接
MySQL数据库----------安装anaconda---------python与数据库的链接
172 0
|
5月前
|
关系型数据库 MySQL PHP
|
3月前
|
关系型数据库 MySQL Java
软件开发2003 -Can·t to MySQL server on ‘xxxxxx‘(10038),宝塔初始化安装mysql,远程链接MySql注意事项,开始时服务器是没有放开端口的,宝塔也都开
软件开发2003 -Can·t to MySQL server on ‘xxxxxx‘(10038),宝塔初始化安装mysql,远程链接MySql注意事项,开始时服务器是没有放开端口的,宝塔也都开
|
5月前
|
Java 关系型数据库 MySQL
【JAVA进阶篇教学】第八篇:Java链接MySql数据库异常
【JAVA进阶篇教学】第八篇:Java链接MySql数据库异常
|
5月前
|
SQL 数据可视化 关系型数据库
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
【MySQL-11】多表查询全解-【多表关系/内外自连接/子查询/多表查询案例链接】(可cv代码&案例演示)
|
5月前
|
关系型数据库 Java 测试技术
云效产品使用常见问题之流水线Maven单元测试链接rds要配置白名单如何解决
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
5月前
|
SQL 关系型数据库 MySQL
下一篇
无影云桌面