vault backup: 2026-04-28 20:56:51
This commit is contained in:
+19
-20
@@ -166,26 +166,25 @@ type Ticket struct {
|
||||
> [!note] GORMDataType 的作用范围
|
||||
> 它只在**建表(AutoMigrate)**时生效,不影响运行时读写行为。也就是说,GORM 会用这个类型创建列,但数据的序列化和反序列化仍由 `database/sql` 的标准处理完成。
|
||||
|
||||
## 结合 Use 注册全局解析器
|
||||
## 全局类型解析器(Resolver)
|
||||
|
||||
对于不想在每个 struct 上实现接口的场景(比如第三方类型的扩展),可以用 `RegisterResolve`:
|
||||
GORM v1.25+ 引入了 Resolver API,可以在不修改类型定义的前提下注册自定义解析:
|
||||
|
||||
```go
|
||||
// 为 net.IP 类型注册 GORM 解析逻辑
|
||||
db.Use(clause.OnConflict{}, func(db *gorm.DB) error {
|
||||
// 这个方式已经过时了...
|
||||
return nil
|
||||
// 创建 DBConfig,为指定类型注册序列化/反序列化逻辑
|
||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
|
||||
Resolver: resolver.FullSaveResolver{
|
||||
Resolvers: map[reflect.Type]resolver.Resolver{
|
||||
reflect.TypeOf(net.IP{}): &IPResolver{}, // 自定义 net.IP 解析器
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// 更现代的方式是用 GORM 的 Resolver
|
||||
type MyType string
|
||||
|
||||
// 注册一个自定义数据类型解析器
|
||||
// 适用于无法给已有类型添加方法的情况
|
||||
```
|
||||
|
||||
> [!info] 注意
|
||||
> GORM 对全局类型注册的 API 在不同版本间有变化。推荐的实践是给类型加上方法实现 Valuer/Scanner——这样代码内聚性更好,依赖也更清晰。
|
||||
> [!tip] 何时使用 Resolver?
|
||||
> - **场景一**:第三方包提供的类型,无法添加方法实现 Valuer/Scanner
|
||||
> - **场景二**:项目中大量地方用到同一自定义类型,避免每个文件重复实现接口
|
||||
> - **首选方案**:仍然是直接给类型实现 `driver.Valuer` + `sql.Scanner`——代码内聚性更好,IDE 也能做类型检查
|
||||
|
||||
## AutoMigrate 时的自定义类型
|
||||
|
||||
@@ -193,12 +192,12 @@ type MyType string
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[字段类型 T] --> B{T 实现<br/>GORMDataType?}
|
||||
B -->|是| C["使用返回值<br/>作为列类型"]
|
||||
B -->|否| D{"T 是已知内置类型?"}
|
||||
D -->|是| E["使用默认映射"]
|
||||
D -->|否| F["尝试 driver.Valuer<br/>推断类型"]
|
||||
F --> G["使用 driver.Value<br/>的反射结果"]
|
||||
A["字段类型 T"] --> B{"是否实现 GORMDataType?"}
|
||||
B -- "是" --> C["使用返回值作为列类型"]
|
||||
B -- "否" --> D{"T 是已知内置类型?"}
|
||||
D -- "是" --> E["使用默认映射"]
|
||||
D -- "否" --> F["尝试从 driver.Valuer 推断"]
|
||||
F --> G["根据 driver.Value 反射确定"]
|
||||
|
||||
style A fill:#4FC08D,color:#fff
|
||||
style C fill:#3B82F6,color:#fff
|
||||
|
||||
Reference in New Issue
Block a user