连接到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
错误处理机制