Swoole系列6.4Hyperf操作数据库

Posted 码农老张Zy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swoole系列6.4Hyperf操作数据库相关的知识,希望对你有一定的参考价值。

Hyperf操作数据库

对于一个 MVC 框架来说,连接操作各种数据库是最基本的功能。而对于 Swoole ,其实我们前面并没有讲很多关于数据库方面的东西,毕竟这不是我们这个系列的主要内容。但之前我们也讲过 连接池 相关的内容,如果小伙伴们不记得了,可以回去看看哦。

连接操作 mysql

在 Hyperf 中,要操作 MySQL 数据库的话,和 Laravel 也非常类似,在 .env 文件中配置相关的连接信息。

DB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=123456
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
DB_PREFIX=

它的数据库配置文件在 config/autoload/databases.php 中,同样也可以配置多组配置。

return [
    'default' => [
        'driver' => env('DB_DRIVER', 'mysql'),
        'host' => env('DB_HOST', 'localhost'),
        'database' => env('DB_DATABASE', 'hyperf'),
        'port' => env('DB_PORT', 3306),
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => env('DB_CHARSET', 'utf8'),
        'collation' => env('DB_COLLATION', 'utf8_unicode_ci'),
        'prefix' => env('DB_PREFIX', ''),
        'pool' => [
            'min_connections' => 1,
            'max_connections' => 10,
            'connect_timeout' => 10.0,
            'wait_timeout' => 3.0,
            'heartbeat' => -1,
            'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60),
        ],
        'commands' => [
            'gen:model' => [
                'path' => 'app/Model',
                'force_casts' => true,
                'inheritance' => 'Model',
            ],
        ],
    ],
];

可以看到,在这个配置文件中,相比 Laravel 多了一些内容。从名字就可以看出,pool 相关的内容是连接池的配置。而 commands 则是生成 模型 类所需要使用的命令行配置。

之前我们就一直说过,Hyperf 的数据库操作和模型本身就是基于 Laravel 的组件的,在官方文档上也说了它是基于 illuminate/database 实现的,查询构造器同样也是基于 Laravel Query Builder 。因此,接下来的内容就比较简单了。

查询构造器

// CREATE TABLE `db_test` (
//   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
//   `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
//   `sex` int(11) NOT NULL DEFAULT '0',
//   PRIMARY KEY (`id`)
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Router::get('/db/add', function()
    $data = [
        [
            'name'=>'Peter',
            'sex' => 1,
        ],
        [
            'name'=>'Tom',
            'sex' => 1,
        ],
        [
            'name'=>'Susan',
            'sex' => 2,
        ],
        [
            'name'=>'Mary',
            'sex' => 2,
        ],
        [
            'name'=>'Jim',
            'sex' => 1,
        ],
    ];
    foreach ($data as $v) 
        $insertId[] = \\Hyperf\\DbConnection\\Db::table('db_test')->insertGetId($v);
    
    return $insertId;
);

Router::get('/db/update', function(\\Hyperf\\HttpServer\\Contract\\RequestInterface $request)
    $data = [
        'name' => $request->input('name', ''),
        'sex' => $request->input('sex', 0),
        'id' => $request->input("id", 0),
    ];

    if($data['id'] < 1 || !$data['name'] || !in_array($data['sex'], [1, 2]))
        return '参数错误';
    

    return \\Hyperf\\DbConnection\\Db::table('db_test')->where("id", "=", $data['id'])->update($data);
);

Router::get('/db/delete', function(\\Hyperf\\HttpServer\\Contract\\RequestInterface $request)
    $id = $request->input('id', 0);
    if($id < 1)
        return '参数错误';
    

    return \\Hyperf\\DbConnection\\Db::table('db_test')->delete($id);
);

Router::get('/db/list', function (\\Hyperf\\HttpServer\\Contract\\RequestInterface $request) 
    $where = [];
    if($request->has("name"))
        $where[] = ['name', 'like', '%' . $request->input('name') . '%'];
    
    if($request->has("sex"))
        $where[] = ['sex', '=', $request->input('sex')];
    

    return \\Hyperf\\DbConnection\\Db::table('db_test')
        ->select(['*'])
        ->where($where)
        ->orderBy('id', 'desc')
        ->limit(10)
        ->offset(0)
        ->get()
        ->toArray();
);

Router::get('/db/info', function (\\Hyperf\\HttpServer\\Contract\\RequestInterface $request, \\Hyperf\\HttpServer\\Contract\\ResponseInterface $response) 
    $id = (int)$request->input('id', 0);
    if($id < 1)
        return '参数错误';
    

    return $response->json(\\Hyperf\\DbConnection\\Db::table('db_test')->find($id));
);

一次性把增删改查的操作都给出了哦。使用的数据库表也是之前我们在讲 Laravel 系列时使用过的。非常明显地就可以看出,这一系列的操作,甚至是方法名以及参数都和我们 Laravel 中的查询构造器基本是一致的。不同的就是在 Hyperf 中,Db 后面这个字母是小写的,而在 Laravel 中则是两个大写字母。

同时,在上面的例子中我们还看到了请求和响应对象相关的操作,如何获取请求参数,如何输出响应数据,并且还能指定为响应 json 格式。这两个注入对象参数在控制器中也是可以使用的,我们就不再单独去讲控制器啦。

模型

模型这一块其实也很简单,它也是基于 Laravel 的 Eloquent ORM 。我们先使用一个命令生成模型。

php bin/hyperf.php gen:model db_test

这样就会在 app/Model 目录下生成一个 DbTest.php 文件。

class DbTest extends Model

    protected $table = 'db_test';
    protected $fillable = [];
    protected $casts = ['id' => 'integer', 'sex' => 'integer'];

剩下的还需要多解释嘛,来一个简单的小例子吧。

Router::get('/db/model/list', function (\\Hyperf\\HttpServer\\Contract\\RequestInterface $request) 
    $where = [];
    if($request->has("name"))
        $where[] = ['name', 'like', '%' . $request->input('name') . '%'];
    
    if($request->has("sex"))
        $where[] = ['sex', '=', $request->input('sex')];
    

    return \\App\\Model\\DbTest::select()->where($where)
        ->orderBy('id', 'desc')
        ->limit(10)
        ->offset(0)
        ->get()
        ->toArray();
);

关于模型其它的操作就不演示了,非常简单方便,使用过 Laravel 的同学上手没难度的。

连接操作 Redis

MySQL 数据库的内容说完了,我们再来看看 Redis ,同样也不难,也是配置 .env 就可以直接使用了,不过我们还是看一下它的配置文件,在 config/autoload/redis.php 中。

return [
    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'auth' => env('REDIS_AUTH', null),
        'port' => (int) env('REDIS_PORT', 6379),
        'db' => (int) env('REDIS_DB', 0),
        'pool' => [
            'min_connections' => 1,
            'max_connections' => 10,
            'connect_timeout' => 10.0,
            'wait_timeout' => 3.0,
            'heartbeat' => -1,
            'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60),
        ],
    ],
];

和 MySQL 一样,也有连接池的配置。之前我们讲连接池的时候也是讲的 MySQL 和 Redis 的连接池,这里正好也对应上了。

接下来也是两个简单的小例子。

Router::get('/db/redis/set', function () 
    $redis = Hyperf\\Utils\\ApplicationContext::getContainer()->get(\\Hyperf\\Redis\\Redis::class);
    return $redis->set("time", "看看现在时间 " . date("Y-m-d H:i:s"));
);

Router::get('/db/redis/get', function () 
    $container = Hyperf\\Utils\\ApplicationContext::getContainer();

    $redis = $container->get(\\Hyperf\\Redis\\Redis::class);

    return $redis->get("time");
);

稍有不同的是,redis 对象的产生方式是需要从 ApplicationContext 这个应用上下文对象的静态方法中获取的。

总结

今天的内容非常简单,没有什么学习压力吧。一开始就说过了,这个框架的很多东西都和 Laravel 是一样一样的,而且我之前的项目甚至可以达到大部分的代码平行迁移过来。怎么说呢,百花齐放是好事,各种思想经验可以学习借鉴,但天下大同也不是什么坏事,对于业务应用来说会非常方便。

有兴趣的小伙伴到这里其实就完全可以尝试尝试用 Hyperf 写一个小程序试试咯!

测试代码:

https://github.com/zhangyue0503/swoole/tree/main/6.%E6%A1%86%E6%9E%B6/hyperf-skeleton

参考文档:

https://hyperf.wiki/2.2/#/zh-cn/db/quick-start

https://hyperf.wiki/2.2/#/zh-cn/redis

以上是关于Swoole系列6.4Hyperf操作数据库的主要内容,如果未能解决你的问题,请参考以下文章

Swoole系列6.3Hyperf 运行各种网络服务

Swoole系列6.3Hyperf 运行各种网络服务

Swoole系列6.5Hyperf中的其它事项

Swoole系列6.5Hyperf中的其它事项

Swoole系统6.2安装运行Hyperf

Swoole系统6.2安装运行Hyperf