可以实现长链接.断线重连,总而言之就是好用.推荐用!
4.gif
安装composer require joshcam/mysqli-database-class:dev-master
查看源码我们可以看到__construct()方法中需要传

$host = null, $username = null, $password = null, $db = null, $port = null, $charset = 'utf8', $socket = null

懒得修改!源码的命名了!直接在配置文件mysql.ini追加

username = 'root'
db = 'video'

使用MysqliDb看文档很简单!我觉得一是我聪明.第二是因为他文档写的很清晰明了!

use MysqliDb;

可以复用链接的哦~省去再链接的资源.如下再另一个方法中调用链接

public function getSql()
{
    $db = new MysqliDb(\Yaconf::get('mysql'));
    $data = ['name' => 'mysql','content'=>'123'];
    $res = $db->insert('test',$data);
    return $this->writeJson(0,'ok',['res' => $res]);
}

public function getSqlAgain()
{
    $db =  MysqliDb::getInstance();
    $res = $db->get('test',1);
    return $this->writeJson(0,'ok',$res);
}

如果没有链接的话.getSqlAgain()报错

[Exception][file:/Users/qvbilam/Sites/easyswoole/vendor/joshcam/mysqli-database-class/MysqliDb.php][line:320]MySQL host or socket is not set

自己判断解决这个问题把!
2.jpg
利用IOC容器实现单例长连接
在框架的\EasySwoole\EasySwooleEvent::mainServerCreate中,引入了MysqliDb.php后,即可进行IOC注入。

Di::getInstance()->set('MYSQL',\MysqliDb::class,\Yaconf::get('mysql'));

获取数据库示例

$db = Di::getInstance()->get('MYSQL');
注意:为避免出现多个进程复用同一个数据库连接的情况,请勿在服务启动前的任一位置执行Di::getInstance()->get('MYSQL')。 workerStart事件中使用数据库,请以手动new class()的方式来获取一个数据库对象,其次,在单例子模式下,请注意数据库断线重连问题, MysqliDb类库中有实现断线自动重连。

创建App\Model\Video对数据库的连接进行判断

namespace App\Model;

use App\Model\Model;
use EasySwoole\Component\Di;

class Video
{
    protected $db;
    protected $tableName = 'test';
    public function __construct()
    {
        $db = Di::getInstance()->get("MYSQL");
        if($db instanceof \MysqliDb){
            $this->db = $db;
        }else{
            $this->db = new \MysqliDb(\Yaconf::get('mysql'));
        }
    }

}

在长链接中玩们使用的这个sql类库对断线重连做了判断.所以我们不用担心
在源码中vendor/joshcam/mysqli-database-class/MysqliDb.php可以自行去了解一下哈

public function rawQuery($query, $bindParams = null)
{
    $params = array(''); // Create the empty 0 index
    $this->_query = $query;
    $stmt = $this->_prepareQuery();

    if (is_array($bindParams) === true) {
        foreach ($bindParams as $prop => $val) {
            $params[0] .= $this->_determineType($val);
            array_push($params, $bindParams[$prop]);
        }

        call_user_func_array(array($stmt, 'bind_param'), $this->refValues($params));
    }

    $stmt->execute();
    $this->count = $stmt->affected_rows;
    $this->_stmtError = $stmt->error;
    $this->_stmtErrno = $stmt->errno;
    $this->_lastQuery = $this->replacePlaceHolders($this->_query, $params);
    $res = $this->_dynamicBindResults($stmt);
    $this->reset();

    return $res;
}

如果按照博客用到Tp风格的数据库注意一定要把继承的Model去掉哈.不然会报错

[Exception][file:/Users/qvbilam/Sites/easyswoole/vendor/easyswoole/mysqli/src/DbObject.php][line:502]Return value of EasySwoole\Mysqli\DbObject::getDb() must be an instance of EasySwoole\Mysqli\Mysqli, null returned

这个问题整的我读了好久的源码!5.jpg
App\ModelVideo中设置表名protected $tableName = 'test';
查询记录

// 查询id>=40的两条数据
public function videoSel()
{
    $res = $this->db
        ->where('id', 40, '>=')
        ->get($this->tableName,2);
    return $res;
}

条件where也可以这样写

public function videoSel()
    {
        $res = $this->db
//            ->where('id', 40, '>=')
            ->where('id', ['>=' => 40])
            ->get($this->tableName, 2);
        return $res;
    }

插入记录

public function videoAdd()
{
    $data = ['name' => 'videoAdd', 'content' => 'hello'];
    $id = $this->db->insert($this->tableName, $data);
    if ($id) {
        return $id;
    } else {
        return $this->db->getLastError();
    }
}

更新记录

public function videoEdit()
{
    $data = ['name' => 'videoupdate2', 'content' => 'hello world'];
    $res = $this->db->where('id',45)->update($this->tableName, $data);
    if ($res) {
        return $this->db->count . '条数据修改成功';
    } else {
        return $this->db->getLastError();
    }
}

删除记录

public function videoDel()
{
    $res = $this->db->where('id',['>=' => 42])->delete($this->tableName);
    if($res){
        return '删除成功';
    }else{
        return '删除失败';
    }
}

分页
先读一下源码吧

public function paginate ($table, $page, $fields = null) {
    $offset = $this->pageLimit * ($page - 1);
    $res = $this->withTotalCount()->get ($table, Array ($offset, $this->pageLimit), $fields);
    $this->totalPages = ceil($this->totalCount / $this->pageLimit);
    return $res;
}

在我们的模型中编写分页

/*
 * data 当前页数据
 * count 一共的数据
 * page 当前页
 * totalPages 总共页
*/
public function videoPage()
{
    $page = 1;
    //将页面限制设置为每页2个结果。20默认
    $this->db->pageLimit = 10;
    $products = $this->db->arraybuilder()->paginate("test",$page);
    $data = [
        'data' => $products,
        'count' => $this->db->totalCount,
        'page' => $page,
        'totalPages' => $this->db->totalPages
    ];
    return $data;
}

 剩下的自己去参照下面的文档测吧!搞定了mysqli接下来该在EasySwoole中使用Redis了.对于聪明的人来说一点都不难的2.jpg

Last modification:February 6th, 2020 at 02:14 pm