【问题标题】:Use default MySQL function when retrieving a record on GORM在 GORM 上检索记录时使用默认 MySQL 函数
【发布时间】:2021-06-02 05:57:43
【问题描述】:

我有一个具有此定义的模型(简化版):

type MyModel struct {
    ID                int64  `gorm:"primary_key;AUTO_INCREMENT"`
    Uuid              string `gorm:"type:binary(16);index:uuid_idx;default:(UUID_TO_BIN(UUID(), true));"`
}

我将UUID_TO_BINswap_flag (docs) 一起使用以获得更好的性能。

我想知道在从MyModel 查询一行时,是否有办法告诉 GORM 在我的列 Uuid 上默认使用 BIN_TO_UUID(uuid, true)

【问题讨论】:

    标签: mysql go go-gorm


    【解决方案1】:

    在检索值之前执行函数的一种方法是使用Select,如下所示:

    db.Select("id, BIN_TO_UUID(uuid) AS uuid").First(&myModel)
    

    这并不理想,因为您必须始终记住在查询该模型时这样做。

    一个更好的方法是构建一个Custom Data Type。具体来说,您可以创建自己的类型来实现 GormDataTypeInterface 以让 Gorm 分配正确的 DB 列类型,以及自定义 Scan/Value 函数,这些函数将执行与二进制之间的转换,而不是依赖于 MySQL 函数。

    这看起来像这样:

    type MyUUID string 
    
    // GormDataType implements the GormDataTypeInterface 
    func (u MyUUID) GormDataType() string {
        return "varbinary(16)" 
    }
    
    // Scan implements the sql.Scanner interface
    func (u *MyUUID) Scan(v interface{}) error {
        // Transform v (a []byte value from the database) into 
        // a string representation and assign to u 
    }
    
    // Value implement driver.Valuer interface
    func (s MyUUID) Value() (driver.Value, error) {
        // Return a []byte representation of s
    }
    

    阅读driver.Valuesql.Scanner 上的文档也很好。

    您可以使用一些现有的 UUID go 库来实现这些,尽管 linked one 仅处理二进制扫描,它的 Valuer implementation 将 UUID 作为字符串返回,这会导致 MySQL 出错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-17
      • 2021-10-17
      • 2020-12-08
      • 2016-01-14
      • 2020-07-30
      • 1970-01-01
      • 2020-06-18
      • 2019-04-25
      相关资源
      最近更新 更多