eftec / daoone
单类中的过程式 MySQLI 数据访问类
Requires
- ext-json: *
- ext-mysqli: *
- ext-openssl: *
Requires (Dev)
- phpunit/phpunit: ^5.7 || ^6.5
Suggests
- eftec/PdoOne: It is an a new version of this library
README
DaoOne。它是一个简单的 Mysqli 包装器
此库尽可能快。大多数操作都是简单的字符串/数组管理。
注意:此版本已移至 https://github.com/EFTEC/PdoOne
PdoOne 执行相同的任务,但它使用 PDO 库(而不是 MySQLi)。目前 PdoOne 与 Mysqli 和 SqlSrv 一起工作,但它具有许多其他 DaOne 上不存在的功能
迁移到 eftec/PdoOne
添加依赖项
通过 composer 安装
composer require eftec/pdoone
此库可以与 eftec/daoone 同时使用。
更改库
更改类,而不是使用 eftec/daoone -> eftec/pdoone
示例
之前
/** @var \eftec\DaoOne $db */ $db=null;
之后
/** @var \eftec\PdoOne $db */ $db=null;
构造函数
之前
$db=new DaoOne('127.0.0.1','root','abc.123','sakila');
之后
$db=new DaoOne('mysql','127.0.0.1','root','abc.123','sakila'); // check 'mysql'
操作符
如果我们使用 DaoOne::runGen(false),则必须检查结果。runGen (DaoOne) 返回 mysqli_result 对象。runGen (PdoOne) 返回 pdostatement 对象。
之前
$result=$db->runGen(false); // it returns a mysqli_result $result->fetch_assoc(); $result->free_result();
之后
$result=$db->runGen(false); // it returns a pdostatement $result->fetch( PDO::FETCH_ASSOC); $result=null;
它如何工作?
将此
$stmt->bind_param("s", $_POST['name']);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0) exit('No rows');
while($row = $result->fetch_assoc()) {
$ids[] = $row['id'];
$names[] = $row['name'];
$ages[] = $row['age'];
}
var_export($ages);
$stmt->close();
转换为此
$products=$dao
->select("*")
->from("myTable")
->where("name = ?",[$_POST['name']])
->toList();
目录
安装(使用 composer)
将以下要求添加到 composer.json,然后更新 composer。
{ "require": { "eftec/daoone": "^3.15" } }
或者使用以下命令通过 CLI 安装
composer require eftec/daoone
安装(手动)
只需下载文件 lib/DaoOne.php 并将其保存到文件夹中。
用法
启动连接
$dao=new DaoOne("127.0.0.1","root","abc.123","sakila",""); $dao->connect();
其中
- 127.0.0.1 是数据库所在的服务器。
- root 是用户
- abc.123 是 root 用户的密码。
- sakila 是使用的数据库。
- ""(可选)它可以是日志文件,例如 c:\temp\log.txt
运行未准备好的查询
$sql="CREATE TABLE `product` ( `idproduct` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(45) NULL, PRIMARY KEY (`idproduct`));"; $dao->runRawQuery($sql);
运行预处理查询
$sql="insert into `product`(name) values(?)"; $stmt=$dao->prepare($sql); $productName="Cocacola"; $stmt->bind_param("s",$productName); // s stand for string. Also i =integer, d = double and b=blob $dao->runQuery($stmt);
注意:您也可以使用过程链插入 insert($table,$schema,[$values])
运行带参数的预处理查询。
$dao->runRawQuery('insert into `product` (name) values(?)' ,array('s','cocacola'));
返回数据(第一种方法)
它返回 mysqli_statement。
$sql="select * from `product` order by name"; $stmt=$dao->prepare($sql); $dao->runQuery($stmt); $rows = $stmt->get_result(); while ($row = $rows->fetch_assoc()) { var_dump($row); }
此语句必须手动处理。
返回数据(第二种方法)
它返回关联数组。
$sql="select * from `product` order by name"; $stmt=$dao->prepare($sql); $dao->runQuery($stmt); $rows = $stmt->get_result(); $allRows=$rows->fetch_all(MYSQLI_ASSOC); var_dump($allRows);
运行事务
try { $sql="insert into `product`(name) values(?)"; $dao->startTransaction(); $stmt=$dao->prepare($sql); $productName="Fanta"; $stmt->bind_param("s",$productName); $dao->runQuery($stmt); $dao->commit(); // transaction ok } catch (Exception $e) { $dao->rollback(false); // error, transaction cancelled. }
startTransaction()
它开始一个事务
commit($throw=true)
它提交一个事务。
- 如果 $throw 为 true,则在事务提交失败时抛出异常。否则,不抛出。
rollback($throw=true)
它回滚一个事务。
- 如果 $throw 为 true,则在事务回滚失败时抛出异常。如果为 false,则忽略回滚失败或事务未打开的情况。
字段
throwOnError=true
如果为 true(默认值),则在发生错误时抛出错误。如果为 false,则执行继续
isOpen=true
如果数据库已连接,则为 true,否则为 false。
查询构建器(DQL)
您也可以构建一个过程式查询。
示例
$results = $dao->select("*")->from("producttype") ->where('name=?', ['s', 'Cocacola']) ->where('idproducttype=?', ['i', 1]) ->toList();
select($columns)
生成一个选择命令。
$results = $dao->select("col1,col2")->...
生成查询: select col1,col2 ...
$results = $dao->select("select * from table")->...
生成查询: select * from table ...
distinct($distinct='distinct')
生成一个选择命令。
$results = $dao->select("col1,col2")->distinct()...
生成查询: select distinct col1,col2 ...
注意: ->distinct('unique') 返回 select unique ..
from($tables)
生成一个 from 命令。
$results = $dao->select("*")->from('table')...
生成查询: select * from table
$tables 可以是一个单独的表或一个 SQL 构造。例如,下一个命令是有效的
$results = $dao->select("*")->from('table t1 inner join t2 on t1.c1=t2.c2')...
where($where,[$arrayParameters=array()])
生成一个 where 命令。
- $where 是一个数组或一个字符串。如果是字符串,则使用参数进行评估。如果有的话
$results = $dao->select("*") ->from('table') ->where('p1=1')...
生成查询: select * from table where p1=1
注意: ArrayParameters 是一个数组,如下所示: type,value.
类型是 i=integer,d=double,s=string 或 b=blob。如有疑问,请使用 "s"。
arrayParameters 的示例
['i',1 ,'s','hello' ,'d',20.3 ,'s','world']
$results = $dao->select("*") ->from('table') ->where('p1=?',['i',1])...
生成查询: select * from table where p1=?(1)
$results = $dao->select("*") ->from('table') ->where('p1=? and p2=?',['i',1,'s','hello'])...
生成查询: select * from table where p1=?(1) and p2=?('hello')
注意:where 可以嵌套。
$results = $dao->select("*") ->from('table') ->where('p1=?',['i',1]) ->where('p2=?',['s','hello'])...
生成查询: select * from table where p1=?(1) and p2=?('hello')
您还可以使用
$results = $dao->select("*")->from("table") ->where(['p1'=>'Coca-Cola','p2'=>1]) ->toList();
生成查询: select * from table where p1=?(Coca-Cola) and p2=?(1)
order($order)
生成一个 order 命令。
$results = $dao->select("*") ->from('table') ->order('p1 desc')...
生成查询: select * from table order by p1 desc
group($group)
生成一个 group 命令。
$results = $dao->select("*") ->from('table') ->group('p1')...
生成查询: select * from table group by p1
having($having,[$arrayParameters])
生成一个 group 命令。
$results = $dao->select("*") ->from('table') ->group('p1') ->having('p1>?',array('i',1))...
生成查询: select * from table group by p1 having p1>?(1)
注意:Having 可以嵌套 having()->having()
注意:Having 可以没有参数 having('col>10')
runGen($returnArray=true)
运行查询生成。
注意:如果 returnArray 为 true,则返回一个关联数组。如果 returnArray 为 false,则返回一个 mysqli_result
注意:它重置当前参数(如当前选择、from、where 等)
toList()
它是 runGen 的宏。它返回一个关联数组或 null。
$results = $dao->select("*") ->from('table') ->toList()
toResult()
它是 runGen 的宏。它返回一个 mysqli_result 或 null。
$results = $dao->select("*") ->from('table') ->toResult()
first()
它是 runGen 的宏。它返回第一行(如果有,如果没有,则返回 false)作为关联数组。
$results = $dao->select("*") ->from('table') ->first()
last()
它是 runGen 的宏。它返回最后一行(如果有,如果没有,则返回 false)作为关联数组。
$results = $dao->select("*") ->from('table') ->last()
有时运行 order() 和 first() 更有效,因为 last() 读取所有值。
sqlGen()
它返回 SQL 命令。
$sql = $dao->select("*") ->from('table') ->sqlGen(); echo $sql; // returns select * from table $results=$dao->toList(); // executes the query
注意:它不会重置查询。
查询构建器(DML),即插入、更新、删除
有四种方式执行每个命令。
假设我们想在列 col1 中添加一个 integer,值为 20
使用值列表的架构和值:第一个值是列,第二个值是值的类型(i=integer,d=double,s=string,b=blob)第二个数组包含值。
$dao->insert("table" ,['col1','i'] ,[20]);
在同一个列表中的架构和值:第一个值是列,第二个值是值的类型(i=integer,d=double,s=string,b=blob)第三个是值。
$dao->insert("table" ,['col1','i',20]);
使用两个关联数组的架构和值:
$dao->insert("table" ,['col1'=>'i'] ,['col1'=>20]);
使用单个关联数组的架构和值:类型自动计算。
$dao->insert("table" ,['col1'=>20]);
insert($table,$schema,[$values])
生成一个插入命令。
$dao->insert("producttype" ,['idproducttype','i','name','s','type','i'] ,[1,'cocacola',1]);
使用嵌套链(单个数组)
$dao->from("producttype") ->set(['idproducttype','i',0 ,'name','s','Pepsi' ,'type','i',1]) ->insert();
使用嵌套链多个设置
$dao->from("producttype") ->set("idproducttype=?",['i',101]) ->set('name=?',['s','Pepsi']) ->set('type=?',['i',1]) ->insert();
或(类型由 MySql 定义,尽可能自动)
$dao->from("producttype") ->set("idproducttype=?",['i',101]) ->set('name=?','Pepsi') ->set('type=?',1) ->insert();
使用嵌套链声明设置
$dao->from("producttype") ->set('(idproducttype,name,type) values (?,?,?)',['i',100,'s','Pepsi','i',1]) ->insert();
生成查询: insert into productype(idproducttype,name,type) values(?,?,?) ...
update($$table,$schema,$values,[$schemaWhere],[$valuesWhere])
生成一个插入命令。
$dao->update("producttype" ,['name','s','type','i'] //set ,[6,'Captain-Crunch',2] //set ,['idproducttype','i'] // where ,[6]); // where
$dao->update("producttype" ,['name'=>'Captain-Crunch','type'=>2] // set ,['idproducttype'=>6]); // where
$dao->from("producttype") ->set("name=?",['s','Captain-Crunch']) //set ->set("type=?",['i',6]) //set ->where('idproducttype=?',['i',6]) // where ->update(); // update
或
$dao->from("producttype") ->set("name=?",'Captain-Crunch') //set ->set("type=?",6) //set ->where('idproducttype=?',['i',6]) // where ->update(); // update
生成查询: update producttype set
name
=?,type
=? whereidproducttype
=? ...
delete([$table],[$schemaWhere],[$valuesWhere])
生成一个删除命令。
$dao->delete("producttype" ,['idproducttype','i'] // where ,[7]); // where
$dao->delete("producttype" ,['idproducttype'=>7]); // where
生成查询: delete from producttype where
idproducttype
=? ...
您还可以通过 DQL 构造链删除。
$dao->from("producttype") ->where('idproducttype=?',['i',7]) // where ->delete();
$dao->from("producttype") ->where(['idproducttype'=>7]) // where ->delete();
生成查询: delete from producttype where
idproducttype
=? ...
序列
序列是 AUTO_NUMERIC 字段的替代方案。它使用一个表来生成一个唯一的 ID。
使用的序列基于Twitter的雪花算法,它基于时间(含微秒)、节点ID和序列生成。这生成一个唯一的LONG(int 64)值。
创建序列
- $dao->nodeId 设置节点值(默认为1)。如果想在不同的集群之间使用唯一的值,可以将节点值设置为唯一。节点数量限制为1024个。
- $dao->tableSequence 设置表(和函数),默认值为snowflake。
$dao->nodeId=1; // optional
$dao->tableSequence='snowflake'; // optional
$dao->createSequence(); // it creates a table called snowflake and a function called next_snowflake()
使用序列
- $dao->getSequence([unpredictable=false]) 返回最后一个序列。如果序列生成失败,则返回-1。如果每1/1000秒调用该函数超过4096次,函数可能会失败。
$dao->getSequence() // string(19) "3639032938181434317"
$dao->getSequence(true) // returns a sequence by flipping some values.
不使用表创建序列
-
$dao->getSequencePHP([unpredictable=false]) 返回不使用表的序列。此序列比$dao->getSequence更高效,但使用随机值处理冲突。
-
如果unpredictable为true,则返回一个不可预测的数字(翻转一些数字)
$dao->getSequencePHP() // string(19) "3639032938181434317"
$dao->getSequencePHP(true) // string(19) "1739032938181434311"
变更列表
- 3.30 2020-02-13 一些清理。
- 3.28 2019-05-04 添加了注释。另外 ->select() 允许整个查询。
- 3.27 2019-04-21 添加了新的加密方法 SIMPLE(简短加密)和 INTEGER(将其转换为整数并返回)
- 3.26 2019-03-06 现在加密有自己的类。
- 3.25 2019-03-06 添加了 getSequencePHP()、getUnpredictable() 和 getUnpredictableInv()。
- 3.24 2019-02-06 添加了新的日期格式。
- 3.22 2018-12-30 添加了序列。
- 3.21 2018-12-17 修复了参数、set() 和 insert() 的bug。现在有几种方法可以插入。现在 NULL 是 self:null
- 3.20 2018-12-15 修复了参数和 insert() 的bug。
- 3.19 2018-12-09 现在 null 参数被视为 null。我们使用 PHP_INT_MAX 来表示值未设置。
- 3.18 2018-12-07 修改了最小稳定性。
- 3.17 2018-12-01 set() 现在允许第二个参数为单个值。
- 3.16 2018-11-03 添加了单元测试和 travis CI。
- 3.15 2018-10-27
-
- 现在它允许多个 select()
-
- function generateSqlFields()
- 3.14 2018-10-16
-
- 添加了 field throwOnError。
-
- 增加了对错误的更多控制。
-
- 现在方法在数据库未打开时失败。
-
- 添加了消息容器(可选)。它与 messages() 函数一起工作。
-
- 添加了 field isOpen
-
- 添加了方法 storeInfo()
- 3.13 2018-10-05 将命令 eval 改为 bind_param( ...)
- 3.12 2018-09-29 修复了 insert() 的bug,现在它返回最后一个身份。
- 3.11 2018-09-27 清理了代码。如果抛出异常,则重置链。
- 3.9 2018-09-24 一些修复。
- 3.7 添加了字符集。
- 3.6 更多的修复。
- 3.5 小修复。
- 3.4 DML 新特性。它允许嵌套操作
- ->from()->where()->delete()
- ->from()->set()->where()->update()
- ->from()->set()->insert()
- 3.3 DML 修改。它允许不同类型的参数。
- 3.2 插入、更新、删除
- 3.0 大幅重写。它添加了查询构建器功能。
- 2.6.4 更好的错误纠正。
- 2.6.3 修复了事务。现在嵌套事务不是嵌套的(并返回 false)。
- 2.6 第一个公开版本