【问题标题】:Dealing with NULL values in app and sending to DB处理应用程序中的 NULL 值并发送到数据库
【发布时间】:2018-02-01 16:19:34
【问题描述】:

我尝试在我的应用程序中使用可空变量,并将其发送到具有默认空列的数据库。

这是一个示例结构:

// Location type
type Location struct {
    ID      int `schema:"id"`
    Title   *string `schema:"title"`
}

Title 定义为 *string,因为它可以为 null(例如,没有用户输入或客户端应用程序将其作为 null 发送)。

这是我接收表单数据的函数:

// JSONLocationCreate func
func (a *App) JSONLocationCreate(w http.ResponseWriter, r *http.Request) {

    r.ParseForm()

    var e Location

    err := decoder.Decode(&e, r.PostForm)
    if err != nil {
        respondWithError(w, http.StatusBadRequest, "Invalid request payload")
        return
    }


    // --- SUCCESS ---
    // If e.Title has data, the following line works.

    // --- FAIL ---
    // If e.Title doesn’t have data (for whatever reason), it’s null, and crashes the app:
    log.Println(*e.Title)


    // Ultimately the variable would be sent off to a database.
    // Below I’m removing other functions and such, just including my statement line.


    // --- SUCCESS ---
    // If e.Title has data, the following line works.

    // --- FAIL ---
    // If e.Title is null (e.g. no user input), this crashes the app.
    statement := fmt.Sprintf("INSERT INTO locations(title) VALUES('%s')", *e.Title)

    // In either case, the crash error is similar to this:
    // panic serving [::1]:52459: runtime error: invalid memory address or nil pointer dereference
}

问题 1:如何在整个应用程序中使用可空变量(如 e.Title),而不会在变量为空时引发恐慌错误?将其包装在将 null 转换为“”字符串的函数中是最佳实践吗?如何透明地应用这样的函数,这样我就不必在变量的每个实例上都有类似“nullCheck(*e.Title)”的东西?

问题 2: 对于我的数据库查询,我不能将“”字符串值发送到数据库中来代替空值。到目前为止,我的查询是手动构建的。我想我需要一个函数来生成 SQL 查询,当变量为空时自动排除列和变量。

我在正确的轨道上吗?有什么例子吗?

经过数小时的搜索,我还没有理解所有的主题/教程。

【问题讨论】:

  • 您应该使用sql.NullX 类型。你可以阅读更多关于medium.com/aubergine-solutions/…
  • 感谢您的文章。我已经实现了它的结构处理程序。在这一点上,一切似乎都很好,除了我在解码我的 postform 时失败了。这篇文章和其他文章似乎主要涉及 db-to-json,而不是相反。
  • 好的,因为我使用的是 Gorilla Schema,如果使用那篇文章中的自定义结构处理程序,我还有额外的步骤要做。这是一个关于它的帖子:stackoverflow.com/questions/27744493/…
  • 无论如何,在尝试使用我的变量时,我似乎仍然需要做更多的事情。我看到当得到一个空变量时,它被保存在一个数组中。伙计,这是一个很深的兔子洞。我决定恢复使用无空数据库设计,无论我从中得到什么头痛,我都会在未来处理它……就这样吧;不管 NULL 提供什么优势……我现在有更大的鱼要炸。

标签: go


【解决方案1】:

通过为您的字段添加 getter 方法可以轻松解决问题 1

func (l Location) GetTitle() string {
    if l.Title == nil {
        return ""
    }
    return *l.Title
}

关注 2: 这取决于您要进行哪些 sql 查询,我建议您查看一些 ORM 库,它们会为您自动执行许多特定于 DB 的代码。 Gorm 是此类库的一个很好的例子:https://github.com/jinzhu/gorm

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2017-05-11
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多