hyperf的eloquent模型必须显式声明$table、$primarykey、$keytype等属性,否则因无约定推导易查不到数据或报column not found;增删改查需注意连接池、事务绑定及事件触发差异。

模型类怎么写,字段映射才不会错
Hyperf 的 Eloquent 模型不是靠约定自动推导表名和主键,必须显式声明关键信息,否则查不到数据或报 Column not found 错误。
-
$table必须指定,不写会默认用类名复数(如User→users),但实际表名常带前缀或不规则(如sys_user),直接写死更可靠 -
$primaryKey默认是id,如果主键是user_id或复合主键(Hyperf 不支持),必须手动设,否则find()失效 -
$keyType默认int,若主键是字符串(如 UUID),要设为string,否则where('id', 'xxx')会被转成整型比较 -
$casts用于类型转换,比如'status' => 'boolean',避免取出来还是'1'字符串
增删改查写法和 Laravel 有啥不一样
语法看着像 Laravel,但底层走协程连接池,且不兼容部分动态属性写法。最常踩的坑是:用 new Model() 赋值后不调 save() 就以为存进去了,或者用 create() 却没开 $fillable。
-
创建:必须开
$fillable才能用create();否则用new Model([...])->save(),或直接Model::insert([...])批量插入 -
查询:
get()返回集合,first()返回单个模型或null;别用find(0),0 会被当成字符串处理,查不到 -
更新:
where()->update()是原生 SQL 更新,不触发模型事件;find()->fill()->save()才走生命周期钩子 -
删除:
delete()调用模型实例才触发事件;where()->delete()是硬删,跳过事件和软删除逻辑
事务里模型操作为啥不回滚
Hyperf 的事务默认绑定在连接上,但 Eloquent 模型如果不显式指定连接,可能跑在默认连接池里,导致事务上下文不一致——看着写了 transaction,其实模型操作根本没进事务。
- 必须统一用
Db::connection('name')->transaction(...),并在里面用Model::on('name')->xxx()指定同名连接 - 或者给模型加
protected $connection = 'name';,再用Model::transaction(...)(Hyperf 3.0+ 支持) - 别在事务里混用
Db::table()和 Eloquent,前者不认模型的$connection,容易漏掉 - 事务内抛异常必须是
throw new Exception,不能只return false,否则框架不捕获、不回滚
为什么刚 save 的模型,再 find 就查不到
这不是缓存问题,而是协程上下文里连接未复用或连接池配置太小,导致第二次查询拿了新连接,而事务还没提交,或主从延迟没同步完。
- 确认是否在事务中:事务未提交前,其他协程/连接看不到变更,
find()查的是快照 - 检查
config/autoload/databases.php中连接池max_connections是否足够,高并发下池子耗尽会新建连接,破坏一致性 - 读写分离场景下,
save()写主库,find()可能路由到从库,需强制走主库:Model::on('default')->find(...) - 别依赖
$model->fresh(),它会发新查询,但不一定在同一连接上下文,建议事务内用变量暂存结果











