db类
<h1>DB类对象</h1>
<ul>
<li><strong>单例模式</strong>
Init()方法获取的是DB类的单例,不管在什么地方、多少次使用Init()方法,始终获取的是同一个DB类对象
一般情况下,只需要使用Init()方法获取DB类对象即可</li>
<li><strong>获取多个DB类对象</strong>
使用 <code>$db = db::New()</code> 获取一个db实例
<strong>在init() 或者 New() 的时候可以传入数据库的连接参数,格式同配置文件的 DB 字段</strong>
<strong>多数情况下使用单例模式,使用 $db->Table(tableName) 切换数据表即可满足需求</strong></li>
</ul>
<pre><code> use lib\z\dbc\db;
$db = db::Init(); //单例模式
$db1 = db::New('table'); //传入数据表名
$db2 = db::New('table', $config); //传入数据表名和连接参数</code></pre>
<p><strong> <font color=red>注意:需要自己保证合法性!</font></strong></p>
<h1>一些基本操作</h1>
<ul>
<li><strong>获取数据表名前缀 GetPrefix()</strong>
<pre><code>$fix = $db-&gt;GetPrefix();</code></pre></li>
<li><strong>指定或者切换数据表 Table()</strong>
<pre><code>$db-&gt;Table('user');
$db-&gt;Table('user a'); //同时指定别名</code></pre></li>
<li><strong>获取 db 类的 pdo 对象</strong>
<pre><code>$pdo = $db-&gt;PDO;</code></pre></li>
<li><strong>获取最后执行的 sql 语句 PDO->GetSql()</strong>
<pre><code>$db-&gt;PDO-&gt;GetSql();</code></pre></li>
</ul>
<h1>Where 条件</h1>
<p>>多数情况下使用数组参数即可满足要求
>在实现复杂的where条件时,如果数组参数满足不了要求,可以使用字符串参数
>字符串参数 框架将不做解析,直接交给PDO处理
>在书写字符串参数时应尽量遵循SQL的书写规范</font></p>
<h3>基本操作</h3>
<pre><code>$where['id'] = 10; // where `id`=10; 等于
$where['id &gt;'] = 10; // where `id`&gt;10; 大于
$where['id &lt;'] = 10; //where `id`&lt;10; 小于
$where['id &gt;='] = 10; //where `id`&gt;=10; 大于等于
$where['id &lt;='] = 10; //where `id`&lt;=10; 小于等于
$where['id &lt;&gt;'] = 10; //where `id`&lt;&gt;10; 不等于</code></pre>
<p><strong>IN 和 NOT IN</strong></p>
<pre><code>$where['id'] = [2,4,6,8]; //where `id` IN(2,4,6,8);
$where['id IN'] = [2,4,6,8]; //同上 指定操作符是'IN'
$where['id NOT IN'] = [2,4,6,8]; //where `id` NOT IN(2,4,6,8)</code></pre>
<p><strong>BETWEEN 和 NOT BETWEEN</strong></p>
<pre><code>$where['id BETWEEN'] = [1,10] //WHERE `id` BETWEEN 1 AND 10
$where['id NOT BETWEEN'] = [1,10] //WHERE `id` NOT BETWEEN 1 AND 10</code></pre>
<p><strong>LIKE</strong></p>
<pre><code>$where['name LIKE'] = '%tom%' //WHERE `name` LIKE %tom%
$where['name'] = '%tom%' //WHERE `name` LIKE %tom%</code></pre>
<p><strong>多个字段对应同一个值的情况:</strong></p>
<pre><code>$where['id|uid'] = 10; //where `id`=10 OR `uid`=10</code></pre>
<h2>连接多个条件</h2>
<p><strong>默认使用 AND 连接多个条件</strong></p>
<pre><code>$where['id &gt;'] = 10;
$where['pot &gt;'] = 100;
//...更多
where `id`&gt;10 AND `pot`&gt;100 AND ...更多 //合并后的条件</code></pre>
<p><strong>OR</strong></p>
<pre><code>$where['id &gt;'] = 10;
$where['OR pid &lt;'] = 20;
$where = ['id &gt;'=&gt;10,'OR pid &lt;'=&gt;20]; // 也可以写在一个数组里面
WHERE `id`&gt;10 OR `pid`&lt;20 // 合并后的语句</code></pre>
<p><strong>使用 And(), Or() 方法应对稍微复杂一点的条件</strong></p>
<pre><code>$m = D('user');
$where = ['id &gt;'=&gt;10,'pot &gt;'=&gt;100];
$or = ['pid &lt;'=&gt; 20, 'OR pot &lt;'=&gt;100];
$and = ['state'=&gt;1]
$user = $m-&gt;where($where)-&gt;Or($or)-&gt;And($and)-&gt;select();
// 合并后的语句:
WHERE (`id `&gt;10 AND `pot `&gt;100) OR (`pid`&lt;20 OR `pot`&lt;100) AND (`state`=1)</code></pre>
<h2>使用字符串参数</h2>
<p><strong>框架不做解析,也不绑定参数,<font color=red>需注意语句安全</font></strong></p>
<pre><code>$where = &quot;`id`&gt;10 AND `pot`&gt;100&quot;;</code></pre>
<p><strong>绑定参数的方式:</strong></p>
<pre><code>$m = D('user');
$where = &quot;`id`&gt;:id AND `pot`&gt;:pot&quot;; //将参数绑定到 :id 和 :pot 上
$arr = [':id'=&gt;10,':pot'=&gt;100]; //给绑定参数赋值
$user = $m-&gt;where($where, $arr)-&gt;select(); //$arr作为第二个参数传入where函数</code></pre>
<p><strong>where 条件的数组参数:
键名可以是一段sql语句
键名前加冒号时候表示后面的值是绑定sql语句,而不是当做值</strong></p>
<pre><code>$where['DATE_FORMAT(`addTime`, &quot;%m&quot;) AS `date`'] = ['1','2','3'];
$where[':content'] = 'IS NULL'; // IS NULL 当作sql处理
$where[':date'] = 'IN(&quot;1&quot;,&quot;2&quot;,&quot;3&quot;)'; // IN(&quot;1&quot;,&quot;2&quot;,&quot;3&quot;) 当作sql处理</code></pre>
<h1>写入相关的操作</h1>
<ul>
<li>
<p><strong>添加数据 Insert()</strong>
数组 $data 键=>值 和数据表 字段=>值 对应</p>
<pre><code>$data['code'=&gt;1, 'name'=&gt;'name'];
$id = $db-&gt;Insert($data);
// 第二个参数为true,当主键重复时不执行操作
$id = $db-&gt;Insert($data, true);</code></pre>
</li>
<li>
<p><strong>批量添加数据 BatchInsert()</strong>
$keys 是要插入的数据字段,顺序和数组$data成员数据的顺序相对应
$data 是一个二维数组,成员数据的顺序和$keys的顺序相对应
返回成功插入数据的行数</p>
<pre><code>$keys = ['id', 'tid', 'mark'];
$data = [
[1, 2, ''],
[2, 3, ''],
[3, 5, ''],
];
$rows = $db-&gt;BatchInsert($keys, $data);
// 第三个参数为true,当主键重复时不执行操作
$rows = $db-&gt;BatchInsert($keys, $data, true);</code></pre>
</li>
<li>
<p><strong>更新数据 Update()</strong>
<strong>支持 Join关联</strong>
数组 $data 键=>值 和数据表 字段=>值 对应
<strong>键名前加冒号: 后面的值会当作sql来执行,不做数据绑定 <font color=red>注意语句安全检查</font></strong></p>
<pre><code>$data['code'=&gt;1, 'name'=&gt;'name'];
$result = $db-&gt;Where(['id'=&gt;1])-&gt;Update($data); //通过where条件指定 id 是1的数据行
// 参数的键名前加冒号:,会当作sql来执行,不做数据绑定
$save = [':num' =&gt; '`num` + 10']; // num字段值增加10
$result = $db-&gt;Where(['id'=&gt;1])-&gt;Update($save);</code></pre>
</li>
<li>
<p><strong>删除数据 Delete()</strong>
<strong>支持 Join关联</strong></p>
<pre><code>$result = $db-&gt;Where(['id'=&gt;1])-&gt;Delete(); //通过where条件指定 id 是1的数据行</code></pre>
</li>
<li>
<p><strong>有则更新无则插入 IfUpdate()</strong>
<font color=red>返回值
-1: 执行了update操作;
0: 没有变更;
其它: 新增数据行的主键值
</font></p>
<pre><code>$data['id'=&gt;1, 'name'=&gt;'name'];
$result = $db-&gt;IfUpdate($data);
// 如果要更新的字段有所不同:
$update = ['nickname'=&gt;'nickname']; //指定要更新的数据
$result = $db-&gt;IfUpdate($data, $update);</code></pre>
</li>
</ul>
<h1>查询相关的操作</h1>
<ul>
<li>
<p><strong>查询一条数据 Find()</strong></p>
<pre><code>$row = $db-&gt;Where($where)-&gt;Find();
$name = $db-&gt;Where($where)-&gt;Find('name'); // 查询一条数据中的一列
// 第二个参数为true:锁定数据行,事务处理中才有效
$name = $db-&gt;Where($where)-&gt;Find('', true);</code></pre>
</li>
<li>
<p><strong>查询多条数据 Select()</strong></p>
<pre><code>$rows = $db-&gt;Where($where)-&gt;Select();
$name = $db-&gt;Where($where)-&gt;Select('name'); // 查询多条数据中的一列
// 第二个参数为true:锁定数据行,事务处理中才有效
$name = $db-&gt;Where($where)-&gt;Select('', true);</code></pre>
</li>
<li>
<p><strong>查询总数据量 Count()</strong></p>
<pre><code>$number = $db-&gt;Where($where)-&gt;Count();</code></pre>
</li>
<li>
<p><strong>限制返回的数据量 Limit()</strong></p>
<pre><code>$rows = $db-&gt;Where($where)-&gt;Limit(10)-&gt;Select();
$rows = $db-&gt;Where($where)-&gt;Limit('100, 10')-&gt;Select();</code></pre>
</li>
<li>
<p><strong>设置查询字段 Filed()</strong></p>
<pre><code>$rows = $db-&gt;Field(['id', 'name', 'SUM(`point`) AS point'])-&gt;Where($where)-&gt;select();
$rows = $db-&gt;Field('id, name, SUM(`point`) AS point')-&gt;Where($where)-&gt;select();</code></pre>
</li>
<li>
<p><strong>关联查询 Join()</strong></p>
<pre><code>$where = &quot;a.id &gt; 10&quot;;
$join = 'LEFT JOIN info b ON a.id=b.id';
$rows = $db-&gt;Table('user a')-&gt;Join($join)-&gt;Where($where)-&gt;Select();
//支持多个join组合成数组:
$join[] = 'LEFT JOIN info b ON a.id=b.id';
$join[] = 'LEFT JOIN bill c ON c.uid=b.uid';
// ... 更多的join</code></pre>
</li>
<li>
<p><strong>排序 Order()</strong></p>
<pre><code>$rows = $db-&gt;Where($where)-&gt;Order('uid DESC')-&gt;Select();</code></pre>
</li>
<li>
<p><strong>分组查询 Group()</strong></p>
<pre><code>$rows = $db-&gt;field($field)-&gt;Where($where)-&gt;Group('uid')-&gt;Select();</code></pre>
</li>
<li>
<p><strong>聚合条件过滤 Having()</strong>
<strong>Having() 参数跟 Where() 相同</strong></p>
<pre><code>$where = &quot;id &gt; 10&quot;;
$having = 'num &gt; 100';
$rows = $db-&gt;Field('uid, SUM(num) AS num')-&gt;Group('uid')-&gt;Having($having)-&gt;Where($where)-&gt;Select();</code></pre>
</li>
<li><strong>数据分页 Page()</strong>
<pre><code>$conf = ['num' =&gt; $num, 'p' =&gt; $p, 'return' =&gt; true];
$data = $db-&gt;where($where)-&gt;Page($conf)-&gt;Select();
$page = $db-&gt;GetPage();</code></pre>
<p><strong>参数说明</strong></p></li>
</ul>
<table>
<thead>
<tr>
<th>字段</th>
<th>类型</th>
<th>说明</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>p</td>
<td>int</td>
<td>页码</td>
<td>1</td>
</tr>
<tr>
<td>var</td>
<td>string</td>
<td>页码参数名(生成分页链接用)</td>
<td>p</td>
</tr>
<tr>
<td>num</td>
<td>int</td>
<td>每页数据量</td>
<td>10</td>
</tr>
<tr>
<td>max</td>
<td>int</td>
<td>最大页码数</td>
<td>0:不限制</td>
</tr>
<tr>
<td>inrange</td>
<td>bool</td>
<td>强制页码在合法范围(超出实际最大分页数时返回最后一页的数据)</td>
<td>true</td>
</tr>
<tr>
<td>rolls</td>
<td>int</td>
<td>生成的页码链接数量(生成分页链接用)</td>
<td>10</td>
</tr>
<tr>
<td>ver</td>
<td>string</td>
<td>版本号</td>
<td>当前版本号,生成a链接用</td>
</tr>
<tr>
<td>mod</td>
<td>int</td>
<td>url模式</td>
<td>当前模式,生成a链接用</td>
</tr>
<tr>
<td>nourl</td>
<td>string</td>
<td>空链接的地址</td>
<td>javascript:;,生成a链接用</td>
</tr>
<tr>
<td>return</td>
<td>array</td>
<td>需要返回的参数: [prev, next, first, last, list]<br>分别代表:上一页,下一页,第一页,最后一页,页码链接的数组</td>
<td>无</td>
</tr>
</tbody>
</table>
<p><strong>如果不需要分页的具体链接,可将return字段设为 true,默认返回以下字段:</strong></p>
<table>
<thead>
<tr>
<th>字段</th>
<th>类型</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>num</td>
<td>int</td>
<td>每页数据量</td>
</tr>
<tr>
<td>pages</td>
<td>int</td>
<td>总分页数</td>
</tr>
<tr>
<td>rows</td>
<td>int</td>
<td>总数据量</td>
</tr>
<tr>
<td>r</td>
<td>int</td>
<td>当前页的数据量</td>
</tr>
<tr>
<td>p</td>
<td>int</td>
<td>页码</td>
</tr>
</tbody>
</table>
<h2>进阶功能</h2>
<h3>获取当前db使用的pdo对象</h3>
<pre><code>$pdo = $db-&gt;PDO;</code></pre>
<h3>获取查询句柄</h3>
<p><strong>返回的是查询结果的pdo句柄</strong></p>
<pre><code>$h = $db-&gt;where($where)-&gt;Fetch();
while($row = $h-&gt;fetch(\PDO::FETCH_ASSOC)){
// 遍历每行数据...
}</code></pre>
<h3>事务处理</h3>
<ul>
<li>开始事务处理
<pre><code>$db-&gt;Begin();</code></pre></li>
<li>提交事务
<pre><code>$db-&gt;Commit();</code></pre></li>
<li>回滚事务
<pre><code>$db-&gt;Rollback();</code></pre></li>
<li>构造Sql语句
构造完成后此次构造相关的参数数据将被清除
<pre><code>$db-&gt;Field($field)-&gt;Where($where)-&gt;Group($group);
$sql = $db-&gt;Parse();</code></pre></li>
</ul>
<h3>子查询 SubQuery()</h3>
<p><strong>注意子查询作为数组参数时,参数名前必须加<font color=red>冒号</font>表示绑定SQL语句</strong></p>
<pre><code>// 跟 Select() 的用法相同,只是返回构造好的sql语句
$sql = $db-&gt;Where($where)-&gt;SubQuery('uid');
$where[':uid'] = $sql; //Where条件中加入子查询, 参数名前加冒号表示绑定SQL语句
$data = $db-&gt;Where($where)-&gt;Select();</code></pre>
<h3>合并查询 Merge()</h3>
<pre><code>$s1 = $db-&gt;Table($table)-&gt;Where($where)-&gt;SubQuery();
$s2 = $db-&gt;Table($table)-&gt;Where($where)-&gt;SubQuery();
// 合并结果集,默认去除重复行
$data = $db-&gt;Table($table)-&gt;Where($where)-&gt;Merge([$s1, $s2])-&gt;Select();
// 第二个参数 'ALL',不去除重复行
$data = $db-&gt;Table($table)-&gt;Where($where)-&gt;Merge([$s1, $s2], 'ALL')-&gt;Select();</code></pre>
<h3>从结果集中查询 Tmp()</h3>
<p><strong>此处Tmp()类似于Table()</strong></p>
<pre><code>$tmp = $db-&gt;Table('user')-&gt;Where(['uid &gt;'=&gt;10])-&gt;SubQuery();
$data = $db-&gt;Tmp($tmp)-&gt;Where(['uid &lt;'=&gt;15])-&gt;Select();
// 第二个参数指定别名
$data = $db-&gt;Tmp($tmp, 'a')-&gt;Where(['a.uid &lt;'=&gt;15])-&gt;Select();</code></pre>
<h3>查询缓存 Cache()</h3>
<p><strong>缓存方式在配置文件DB的 cache_mod 字段</strong>
cache_mod 可选值:'file', 'redis', 'memcached'</p>
<pre><code>$data = $db-&gt;Where($where)-&gt;Cache(60)-&gt;Select(); //缓存60秒
//支持分页缓存,分页参数是固定的,否则也就没必要缓存了
$conf = ['num' =&gt; $num, 'p' =&gt; $p, 'return' =&gt; true];
$data = $db-&gt;Where($where)-&gt;Page($conf)-&gt;Cache(60)-&gt;Select();
$page = $db-&gt;GetPage();</code></pre>
<h3>清理缓存 CleanCache()</h3>
<pre><code>$db-&gt;CleanCache($db_name, $table);
// 删除$db_name库的$table表的缓存($table必须是带有前缀的完整表名,如果为空则是删除$db_name下的所有缓存)</code></pre>
<h3>合并关联查询</h3>
<pre><code>$data = [
['id'=&gt;1, 'uid' =&gt;1, 'title'=&gt;'title1', 'content'=&gt;'content1'],
['id'=&gt;2, 'uid' =&gt;2, 'title'=&gt;'title2', 'content'=&gt;'content2'],
// ...
];
$chain = [
'users'=&gt;['uid', ['uid'=&gt;'username']],
'counter'=&gt;['count_id', ['id'=&gt;['read_num', 'share_num'=&gt;'sNum']]],
];
// $chain 的结构:
// [目标表名=&gt;[目标表主键名, [数据源(主表)外键名或主键名=&gt;[目标表的字段]]]]
$db-&gt;QueryChain($data, $chain);
// 合并后 $data 的数据结构:
[
['id'=&gt;1, 'uid' =&gt;1, 'title'=&gt;'title1', 'content'=&gt;'content1', 'username'=&gt;'username1', 'read_num'=&gt;1, 'sNum'=&gt;2],
['id'=&gt;2, 'uid' =&gt;2, 'title'=&gt;'title2', 'content'=&gt;'content2', 'username'=&gt;'username2', 'read_num'=&gt;3, 'sNum'=&gt;4],
// ...
]</code></pre>
<h1>数据库结构文件</h1>
<p><strong><font color=red>此配置只针对 db类操作有效</font></strong>
<strong>文件位置请参见项目结构</strong></p>
<pre><code>return [
/**user表的配置**/
'user'=&gt;[
/**主键名,建议添加此字段,可以优化查询**/
'prikey'=&gt;'id',
/**
* 可操作字段
* 此配置影响 插入,修改,以及不指定查询字段的操作
* 不在此数组中字段无法添加和修改
* 查询数据时未指定Field或Field为*则只返回此数组中的字段
*/
'columns'=&gt;['id', 'uid', 'username', 'passwd', 'regtime'], // 可操作字段
/**
* 字段别名
* 此配置影响查询返回的字段名
* 格式是 实际字段名 =&gt; 要返回的字段名
*/
'alias'=&gt;['userid'=&gt;'uid','username'=&gt;'name','password'=&gt;'passwd'],
/**
* 数据库执行写入操作后的回调
* 可接收 $params, $db 两个参数
* $params 参数根据操作不同,会包含[result, data, sql, bind, where]等字段
* $db 是当前的 db 对象
*/
'call'=&gt;[
'update'=&gt;function($params, $db){
$id = $db-&gt;getWhereByKey('id'); // 获取本次操作数据行的主键
// 执行操作...
},
'insert'=&gt;function($params, $db){
// 执行操作...
},
'delete'=&gt;function($params, $db){
// 执行操作...
},
],
],
/**其他数据表**/
'other'=&gt;[
...
],
]</code></pre>