ridibooks / platform-gnfdb
数据库库
Requires
- doctrine/dbal: ^2.5
Requires (Dev)
- phpunit/phpunit: ^5
README
这里通过 Git Subrepo 管理代码。
警告 请不要直接提交。
0. 安装
可以使用 composer 进行安装。
安装 ridibooks/platform-gnfdb 或 gnf/gnfdb 即可。
composer require ridibooks/platform-gnfdb
1. 连接方法
在 gnfdb 包中实例化 Gnf\db\PDO 即可使用。
Gnf\db\PDO 接受 \PDO 作为参数。创建连接并传递参数。
<?php $pdo_dbh = new PDO('mysql:host={host}', $user, $password); $db = new Gnf\db\PDO($pdo_dbh);
2. SELECT 相关
使用的 method 列表如下。
- sqlDict / sqlDicts - 以数组 (PDO::FETCH_ASSOC) 形式接收结果值。
- sqlObject / sqlObjects - 以对象 (PDO::FETCH_OBJ) 形式接收结果值。
以上 method 的形式如下。
- sqlDict($sql, ...)
与 \PDO 的 prepare 语法相同,但不支持 ":column:" 这样的 bind,只支持使用 "?" 进行 bind。
单个查询的 sqlDict / sqlObject 在数据不存在时返回 null,而多个查询的 sqlDicts / sqlObjects 在数据不存在时返回空数组。
使用示例
$db->sqlDict('SELECT * FROM tb_book WHERE id = ?', $b_id); $db->sqlDicts( 'SELECT * FROM tb_book INNER JOIN cpdp_books ON (tb_book.id = cpdp_books.b_id AND cpdp_books.approve_status = ?) WHERE tb_book.id = ? AND tb_book.pub_id = ?', ApproveStatus::OPEN, $b_id, $pud_ib );
3. WHERE 条件的扩展使用方法
可以直接指定 WHERE 条件并绑定 ?,但为了方便,提供了以下函数。
- sqlWhere($where)
$where 是以 column => condition 形式构成的数组。
3.1 条件编写方法
- 简单比较直接使用值。
- 比较运算符使用以下函数的值。
sqlLesser($value)
< $value
sqlLesserEqual($value)
<= $value
sqlGreater($value)
> $value
sqlGreaterEqual($value)
>= $value
- 范围运算符
sqlBetween($start, $end)
$start <= value <= $end
sqlRange($start, $end)
$start <= b < $end
- LIKE 语句的使用方法如下。
sqlLike($keyword)
like '%{$keyword}%'
sqlLikeBegin($keyword)
like '{$keyword}%'
条件编写示例
<?php //단순 비교 $db->sqlDict( 'SELECT * FROM tb_book WHERE ?', sqlWhere(['id' => $b_id]) ); // => SELECT * FROM tb_book WHERE id = {$b_id} //비교 연산자 $db->sqlDict( 'SELECT * FROM tb_book WHERE ?', sqlWhere(['pub_id' => sqlLesser($pub_id)]) ); // => SELECT * FROM tb_book WHERE pub_id < {$pub_id} //Between $db->sqlDict( 'SELECT * FROM tb_book WHERE ?', sqlWhere(['regdate' => sqlBetween('20160101000000', '20161231235959')]) ); // => SELECT * FROM tb_book WHERE regdate BETWEEN '20160101000000' AND '20161231235959' //like $db->sqlDict( 'SELECT * FROM tb_book WHERE ?', sqlWhere(['title' => sqlLike('체험판')]) ); // => SELECT * FROM tb_book WHERE title like '%체험판%'
- 简单比较时,如果比较对象是数组,则应用 IN 查询。
比较对象是数组的查询示例
<?php $b_ids = ['101000940', '101000941', '101000945']; $db->sqlDicts( 'SELECT * FROM tb_book WHERE ?', sqlWhere(['id' => $b_ids]) ); // => SELECT * FROM tb_book WHERE id IN ('101000940', '101000941', '101000945')
3.2 可一起使用的函数
- sqlRaw($value)
- 直接使用输入的值。
- sqlLimit($count)
limit $count
- sqlLimit($from, $count)
limit $from, $count
- sqlNull()
- null 值,直接使用值作为 null 即可。
- sqlNot($value)
- 应用 Not。可以与 sqlGreater 等其他运算符组合使用。
3.3 AND, OR 复合使用
前面提到的 sqlWhere 是使用 AND 编写的函数,而 sqlOr($where) 函数可以编写 OR 语句。
通过混合使用这两个函数,可以编写多种 WHERE 语句。
复合查询
<?php $where = [ 'tb_book.pub_id' => sqlNot(101), sqlOr( [ 'tb_book.category' => sqlNot( [ 4001, 4003 ] ) ], [ 'tb_book.serial_completed' => sqlNot('Y'), 'tb_book.series_id' => sqlNot('') ], ['tb_category.genre' => sqlNot('comic')], ['tb_book.is_setbook' => 'Y'] ) ]; $db->sqlDicts( 'SELECT tb_book.id FROM tb_book LEFT JOIN tb_book_comic ON (tb_book.id = tb_book_comic.b_id) LEFT JOIN tb_category ON (tb_book.category = tb_category.id) WHERE ?', sqlWhere($where) ); /* SELECT tb_book.id FROM tb_book LEFT JOIN tb_book_comic ON (tb_book.id = tb_book_comic.b_id) LEFT JOIN tb_category ON (tb_book.category = tb_category.id) WHERE tb_book.pub_id != 101 AND ( tb_book.category NOT IN (4001, 4003) OR ( tb_book.serial_completed != 'Y' AND tb_book.series_id != '' ) OR tb_category.genre != 'comic' OR tb_book.is_setbook = 'Y' ) */
3.4 扩展的表语句
可以直接在查询中编写表名,但只编写与 JOIN 的 ON 条件连接的列,可以简单地创建 JOIN 查询。
支持的函数如下。
- sqlTable($table) - 单个表使用
- sqlJoin($tables) - JOIN 查询
- sqlLeftJoin($tables) - LEFT JOIN 查询
- sqlInnerJoin($tables) - INNER JOIN 查询
编写方法
- 表格列表是以数组形式编写并使用的。
- 键和值都应编写为相互JOIN的列。
- 最好使用之前声明的表格作为键值。
- 首次声明时,键为FROM子句的表格,值为后续的JOIN表格。
- 值可以写单个表格以只进行一次JOIN,也可以写数组以进行多个表格的顺序JOIN。
表格语法示例
<?php // 단일 테이블 $db->sqlDict('SELECT * FROM ?', sqlTable('tb_book')); // => SELECT * FROM tb_book // join 테이블 - 1:1 관계만 $tables = [ 'tb_book.id' => 'tb_book_comic.b_id', 'tb_book.category' => 'tb_category.id' ]; $db->sqlDicts('SELECT * FROM ?', sqlLeftJoin($tables)); /* SELECT * FROM tb_book LEFT JOIN tb_book_comic ON (tb_book.id = tb_book_comic.b_id) LEFT JOIN tb_category ON (tb_book.category = tb_category.id) */ // join 테이블 - 첫 테이블에 join이 여러개 걸리는 경우 $tables = [ 'tb_book_production.b_id' => ['tb_book.id', 'platform_withhold.b_id'], 'tb_book.pub_id' => 'tb_publisher.id', 'tb_publisher.id' => 'tb_publisher_manager.pub_id', 'tb_book.id' => 'tb_book_search.b_id' ]; $db->sqlDicts('SELECT * FROM ?', sqlLeftJoin($tables)); /* SELECT * FROM tb_book_production LEFT JOIN tb_book ON (tb_book_production.b_id = tb_book.id) LEFT JOIN platform_withhold ON (tb_book_production.b_id = production_withhold.b_id) LEFT JOIN tb_publisher ON (tb_book.pub_id = tb_publisher.id) LEFT JOIN tb_publisher_manager ON (tb_publisher.id = tb_publisher_manager.pub_id) LEFT JOIN tb_book_search ON (tb_book.id = tb_book_search.b_id) */
3.5 其他
- sqlAdd($something) - 将column + $something查询转换为
- sqlStrcat($something) - 将concat(colum, $something)查询转换为
- sqlPassword($something) - sql password()函数
- sqlColumn($column) - 当想安全地使用列名时
- sqlWhereWithClause($where) - 与sqlWhere()相同,但'WHERE'在条件语句前先行
- sqlRange($A, $B) - $a <= column < $b
- sqlNow() - sql now()函数
4. CRUD
CRUD支持以下方法。
-
sqlInsert(table, data)
-
sqlUpdate(table, data, where);
-
sqlDelete(table, where)
-
sqlInsertOrUpdate(table, data, update_where = null) - INSERT INTO ~~ ON DUPLICATE KEY UPDATE语句
-
sqlInsertBulk(table, data_keys, data_valuess) - 批量用sqlInsert
-
sqlInsertOrUpdateBulk(table, data_keys, data_valuess) - 批量用sqlInsertOrUpdate
变量如下。
- table - 单个表格名(未应用sqlTable的)
- data - 要添加/更新的数据数组,column => value构成
- data_keys 要添加/更新的数据的键数组
- data_valuess 要添加/更新的数据数组列表,[[column => value], [column => value] ...]构成
- where, update_where - 条件语句(sqlWhere可以没有)
5. 事务
事务支持以下两种方法。
-
transactional
-
$success = $db->transactional(function($db) { $db->sqlDo($sql); });
-
-
sqlBegin-sqlEnd
-
$db->sqlBegin(); dbQueries($db); $success = $db->sqlEnd();
-
sqlEnd可以用sqlCommit, sqlRollback方法替代。
-
6. 其他等等
已编写的方法列表
sqlDo($sql, ...)
- 简单执行sqlCount($table, $where)
- SELECT count(*) FROM ~~ 的缩写sqlData($sql, ...)
- 与Dict/Object不同,只提取SELECT子句的第一个列,值为null则返回nullsqlDatas($sql, ...)
- 与上相同,值为null则返回空数组sqlArray($sql, ...)
- 与Dict类似,但key值以数字输入(PDO::FETCH_NUM)sqlArrays($sql, ...)
- 与Dicts类似,与上相同sqlLine($sql, ...)
- 与sqlArray相同sqlLines($sql, ...)
- 与sqlArrays相同sqlDump($sql, ...)
- 返回查询解析结果sqlDumpBegin(); sqlDo($sql, ...); sqlDumpEnd()
- sqlDo调用时,在sqlDumpEnd中可以获取执行的query。