连接到PostgreSQL数据库

我对使用标准的[database/sql]连接到PostgreSQL和使用ORM的GORM连接到PostgreSQL这两种情况进行了比较。

一种选择: 标准

首先,如果使用标准的[database/sql]。

package main

import (
    "database/sql"
    "fmt"
    "log"
    _ "github.com/lib/pq"
)

type Sale struct {
    Id   string
    OrderId string
}

func main() {
    db, err := sql.Open("postgres", "postgres://user:pass@host:port/dbname")
    if err != nil {
        log.Fatalln("接続失敗", err)
    }
    defer db.Close()

    // 取得件数を条件[$1]にする
    // ?だとエラーが発生
    //cmd := "select id, order_id from final_sales where id like $1"
    cmd := "select id, order_id from final_sales where id like $1"
    //取得するデータが1件の場合は、QueryRowも利用できる
    rows, _ := db.Query(cmd, "T00%")
    defer rows.Close()

    var sales []Sale // 取得するデータの構造体を用意(複数取得するのでスライス)
    for rows.Next() {
        var tmp Sale // 取得の格納用
        err := rows.Scan(&tmp.Id, &tmp.OrderId)
        if err != nil {
            log.Fatalln("取得失敗", err)
        }
        sales = append(sales, tmp)
    }
    for _, sale := range sales {
        fmt.Println(sale.Id, sale.OrderId)
    }
}

ORM – Object Relational Mapping (对象关系映射)

下一步使用ORM [gorm] 的情况下。

package main

import (
    "fmt"
    "log"

    "github.com/jinzhu/gorm"

    _ "github.com/lib/pq"
)

// `デフォルトのテーブル名は`sales`と自動判断
type Sale struct {
    Id   string `gorm:"column:sale_id"`
    OrderId string `gorm:"column:order_id"`
}

// 今回は、デフォルトではないので指定する
func (Sale) TableName() string {
    return "final_sales"
}

func main() {
    db, err := gorm.Open("postgres", "postgres://user:pass@host:port/dbname")
    if err != nil {
        log.Fatalln("接続失敗", err)
    }
    defer db.Close()

    var sales []Sale // 取得するデータの構造体を用意(複数取得するのでスライス)
    err = db.Where("sale_id like ?", "T00%").Find(&sales).Error

    if err != nil {
        log.Fatalln("取得失敗", err)
    }

    fmt.Println(sales)
}

相悖之处

导入

在中国翻过来的话是:我们将导入github.com/jinzhu/gorm来代替database/sql。

连接方式

将连接从 sql.Open 更改为 gorm.Open。

声明结构体

在结构体声明中添加gorm:”column:sale_id”。
这将用于gorm在自动提取数据时的判断。

另外,OrderId將自動進行蛇形命名法和駝峰命名法之間的轉換。
因此,即使沒有指定列名,也沒有問題。

type Sale struct {
    Id   string `gorm:"column:sale_id"`
    OrderId string
}

请参考以下网站。
指定列名的方法

指定表格名称

在gorm中,声明的结构体的复数形式会自动判断为表名。
由于本次与自动判断的名称不同,因此需要声明表名。

func (Sale) TableName() string {
    return "final_sales"
}

请查看下述内容:
复数形式的表名。

数据获取方式

由於使用ORM,不需要撰寫SQL語句。
當然也可以選擇撰寫SQL語句。

使用ORM可以一次获取多个数据,而不需要使用for循环逐个获取并存储到结构体的切片中。

err = db.Where("sale_id like ?", "T00%").Find(&sales).Error

请参考以下内容:
在哪里
错误处理

整理

我曾经有过在本地的SQLite和服务器上的SQLSever中分别编写SQL的项目经验。
如果你了解ORM,就可以避免这样繁琐的操作。
目前,我已经准备了连接到PostgreSQL的环境变量,如果无法获取到环境变量,则会将其判断为本地开发环境,并连接到SQLite。
由于没有编写原始SQL,所以目前即使数据库发生变化,也不会出现错误。

然而,在一般项目中,我认为准备相同的数据库在服务器和本地上是好的,这样可以避免因数据库差异而产生的行为差异。此外,还需要记住ORM特有的写法。

请参照这个指南办事。

指定列名的方法
多个表名的复数形式
WHERE
错误处理机制

广告
将在 10 秒后关闭
bannerAds