Laravel 存取数组类型到 PgSql 带来的思考 硬核

「这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

需求描述

今天需要一个问题,推荐算法同学在PgSql数据库创建了一个 integer[] 类型的字段,需要我们业务同学写入数据。

调研了好久发现 Laravel 没有提供底层支持,需要自己实现。

遇到的坑

  1. 我使用的 NaviCat 作为数据库的可视化管理工具,发现在我的可视化工具上根本没有 integer[] 这个类型,显示的是 varchar 类型,这里困扰了我半天。
  2. PHP 获得 pgsql 中数组类型的数据得到是这种类型 {1,2,3} ,就是字符串!所以我的NaviCat 显示 varchar 类型也是合理的。

实现需求

可以只看核心代码部分,代码段中写明了注释。

简单来说就是 {} 和 [] 的互相转化,基于字符串拼接的方式实现。

因为不管是pgsql中存储的还是我通过PHP读取到的类型都是字符串,并不是数组类型,这是个核心问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
php复制代码public static function updateJoinHouseGroupId($userid, $houseGroupId)
{
$model = self::query()
->selectRaw('"joinHouseGroupId"')
->where('userid', $userid)
->first();

if ($model) {
$model->houseGroupId = $houseGroupId;
$joinHouseGroupId = $model->joinHouseGroupId;

//核心代码begin---------------------------
if ($joinHouseGroupId) {
//已经有的要重新拼接
$joinHouseGroupIdStr = substr($joinHouseGroupId, 1, strlen($joinHouseGroupId) - 2);
//查询专场是否在有效期内
$joinHouseGroupIds = explode(',', $joinHouseGroupIdStr);
$joinNotExpireHouseGroupIds = HouseGroupInfo::getNotExpireIds($joinHouseGroupIds);
if ($joinNotExpireHouseGroupIds) {
$joinHouseGroupId = "{" . implode(',', $joinNotExpireHouseGroupIds) . "," . $houseGroupId . "}";
} else {
$joinHouseGroupId = "{" . $houseGroupId . "}";
}
} else {
$joinHouseGroupId = "{" . $houseGroupId . "}";
}
//核心代码end----------------------------------

self::query()
->where('userid', $userid)
->update([
'joinHouseGroupId' => $joinHouseGroupId,
]);
}
}

进一步思考

上述代码勉强实现了需求,但是不够优雅,我期望的形式是,自定义一个类型,比如 pgArray

当我在model中做如下设置时,能自动实现 gpsql中存取的数组转成PHP可以直接处理的数组。

1
2
3
ini复制代码protected $casts = [
'xxxx' => 'pgArray',
];

以最简单的int型数组举例,PHP能处理的数组是这样的:[1,2,3]

而PgSql中存储的数组是这样的:{1,2,3}

要实现在存取时自动转换

大家有什么好想法欢迎在评论区讨论

硬核文章推荐

PHP转Go 2021年年中总结

如何第一时间收到接口报错?不用测试妹子再质疑你是不是接口挂了。

Git使用实战:多人协同开发,紧急修复线上bug的Git操作指南。

性能优化反思:不要在for循环中操作DB

性能优化反思:不要在for循环中操作DB 进阶版

最后

👍🏻:觉得有收获请点个赞鼓励一下!

🌟:收藏文章,方便回看哦!

💬:评论交流,互相进步!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%