eftec/daoone

单类中的过程式 MySQLI 数据访问类

3.30 2020-02-13 17:08 UTC

This package is auto-updated.

Last update: 2024-09-07 07:39:58 UTC


README

DaoOne。它是一个简单的 Mysqli 包装器

此库尽可能快。大多数操作都是简单的字符串/数组管理。

注意:此版本已移至 https://github.com/EFTEC/PdoOne
PdoOne 执行相同的任务,但它使用 PDO 库(而不是 MySQLi)。目前 PdoOne 与 Mysqli 和 SqlSrv 一起工作,但它具有许多其他 DaOne 上不存在的功能

Build Status Packagist Total Downloads Maintenance composer php php CocoaPods

迁移到 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=? where idproducttype=? ...

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 第一个公开版本