呼叫 API 的過程,總是會接觸到資料層級,接著存取資料庫,
在 Golang 中操作資料庫
引入函式庫
import (
"database/sql"
_ "github.com/lib/pq"
)
連接資料庫,sql.Open 用來和資料庫連接,第一個參數是要使用的資料庫驅動,最後一個是連線字串
func testDatabase() {
var err error
Db, err = sql.Open("postgres", "dbname=gamilms user=gamilms sslmode=disable")
if err != nil {
panic(err)
}
defer Db.Close()
}
直接執行 SQL 來建立資料表
// postgres.sql
Create table users (
id serial primary key,
name varchar(255),
email varchar(255)
)
使用 QueryRow 來執行新增資料,並將 Scan 回來的資料,取出 Id 並返回
func createUser() (id int64) {
username := fmt.Sprintf("user%d", time.Now().UnixNano())
sqlStatement := fmt.Sprintf(`
INSERT INTO users ( email, name)
VALUES ('%s@gamilms.com', 'user%s')
RETURNING id`, username, username)
Db.QueryRow(sqlStatement).Scan(&id)
return id
}
讀取資料,使用 Query 執行 SQL,並印出全部列表
func readUsers() {
rows, err := Db.Query("select * from users")
if err != nil {
panic(err)
}
for rows.Next() {
user := User{}
err := rows.Scan(&user.ID, &user.Name, &user.Email)
if err != nil {
panic(err)
}
fmt.Printf(fmt.Sprintf("id: %d, name: %s, email: %s \n", user.ID, user.Name, user.Email))
}
}
更新資料,利用 Exec 執行 SQL
func updateUser(id int64) {
useremail := fmt.Sprintf("user%d@gmail.com", time.Now().UnixNano())
_, err := Db.Exec("update users set email = $2 where id = $1", id, useremail)
if err != nil {
panic(err)
}
return
}
刪除資料,一樣使用 Exec 執行 SQL
func deleteUser(id int64) {
_, err := Db.Exec("delete from users where id = $1", id)
if err != nil {
panic(err)
}
return
}
嘗試操作了 CRUD 在 PostgresSQL ,使用了三個方法 QueryRow, Query, Exec,
其中 QueryRow 只會傳回一筆資料,並可以用 Scan 的方法來取用資料,
而 Query 則回傳回全部的結果,也是可以用 Scan,
Exec 則用來執行不需要回傳查詢資料的 SQL
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/lib/pq"
)
type User struct {
ID int64
Name string
Email string
}
var Db *sql.DB
func testDatabase() {
var err error
Db, err = sql.Open("postgres", "dbname=gamilms user=gamilms sslmode=disable")
if err != nil {
panic(err)
}
id := createUser()
readUsers()
updateUser(id)
deleteUser(id)
defer Db.Close()
}
func createUser() (id int64) {
username := fmt.Sprintf("user%d", time.Now().UnixNano())
sqlStatement := fmt.Sprintf(`
INSERT INTO users ( email, name)
VALUES ('%s@gamilms.com', 'user%s')
RETURNING id`, username, username)
Db.QueryRow(sqlStatement).Scan(&id)
return id
}
func readUsers() {
rows, err := Db.Query("select * from users")
if err != nil {
panic(err)
}
for rows.Next() {
user := User{}
err := rows.Scan(&user.ID, &user.Name, &user.Email)
if err != nil {
panic(err)
}
fmt.Printf(fmt.Sprintf("id: %d, name: %s, email: %s \n", user.ID, user.Name, user.Email))
}
}
func deleteUser(id int64) {
_, err := Db.Exec("delete from users where id = $1", id)
if err != nil {
panic(err)
}
return
}
func updateUser(id int64) {
useremail := fmt.Sprintf("user%d@gmail.com", time.Now().UnixNano())
_, err := Db.Exec("update users set email = $2 where id = $1", id, useremail)
if err != nil {
panic(err)
}
return
}
func main() {
testDatabase()
}