golangでDB接続(PostgreSQL)を試したのでそのサンプルです。
以下サンプル。
まずは接続先のPostgreSQL環境を準備します。
ここは手っ取り早く、Docker で環境を作りました。
(前提)
Docker がインストール済みであること
postgresql がインストール済みであること(psql コマンドを使用して DB接続を確認するため)
下記の docker-compose.yml を作成し、「docker-compose up -d」で起動します。
[docker-compose.yml]
version: '3'
services:
postgres:
image: postgres:14
container_name: postgres
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: sample
TZ: "Asia/Tokyo"
- 5432:5432
volumes:
docker exec -it postgres psql -U user -d sample
上記コマンドでPostgreSQLに接続ができます。
これでPostgreSQL環境構築は完了です。
docker exec -it postgres psql -U user -d sample
psql (14.10 (Debian 14.10-1.pgdg120+1))
Type "help" for help.
sample=#
続いて、Go でPostgreSQL に接続する処理を書いていきます。
pq ライブラリを使用しました。
下記で各種ファイルを用意します。
mkdir sample
go mod init sample
touch main.go
まずは main.go には下記の内容を記載します。
package main
import (
"fmt"
"log"
)
func main() {
connStr := "user=user password=password dbname=sample sslmode=disable"
_, err := sql.Open("postgres", connStr)
log.Fatal(err)
}
fmt.Println("DB接続")
}
「_ "github.com/lib/pq"」のところでコンパイルエラーになるので、
go mod tidy
を実行することで、pq が go.mod の依存関係に追加されます。(go.mod ファイルが更新される)
ここまでできたら、main.go を実行します。
「DB接続」と表示されれば、問題なく接続ができています。
go run main.go
DB接続
接続するだけだと面白くないので、DBへのCRUDも試します。
まずは動作検証用のテーブルを用意。
CREATE TABLE "user" (
id SERIAL PRIMARY KEY,
name VARCHAR(255),
age INT
);
続いてデータの登録です。
データ登録用の dbInsert 関数を追加しています。
package main
import (
"fmt"
"log"
)
func main() {
connStr := "user=user password=password dbname=sample sslmode=disable"
db, err := sql.Open("postgres", connStr)
log.Fatal(err)
}
fmt.Println("DB接続")
var command string
fmt.Print("コマンドを入力 (insert/update/delete/select): ")
fmt.Scan(&command)
switch command {
case "insert":
dbInsert(db)
default:
fmt.Println("無効なコマンド")
}
}
func dbInsert(db *sql.DB) {
var name string
var age int
fmt.Print("名前を入力: ")
fmt.Scan(&name)
fmt.Print("年齢を入力: ")
fmt.Scan(&age)
// INSERT文を実行
result, err := db.Exec("INSERT INTO \"user\" (name, age) VALUES ($1, $2)", name, age)
log.Fatal(err)
}
// 追加成功時のメッセージと追加されたレコード内容を表示
fmt.Println("追加しました。")
lastInsertID, _ := result.LastInsertId()
fmt.Printf("追加されたレコードのID: %d, 名前: %s, 年齢: %d\n", lastInsertID, name, age)
}
コマンドラインから、insert/update/delete/select のいずれかの入力を受け付け、
insert の場合にデータ登録を行うようにしています。
これを実行してみます。
go run main.go
DB接続
コマンドを入力 (insert/update/delete/select): insert
名前を入力: test
年齢を入力: 10
追加しました。
追加されたレコードのID: 0, 名前: test, 年齢: 10
PostgreSQLにもSelect句を投げてみます。
select * from public.user;
id | name | age
----+------+-----
1 | test | 10
(1 row)
無事に登録できています。
続いてデータの更新です。
データ更新用の dbUpdate 関数を追加しています。
func main() {
connStr := "user=user password=password dbname=sample sslmode=disable"
db, err := sql.Open("postgres", connStr)
log.Fatal(err)
}
fmt.Println("DB接続")
var command string
fmt.Print("コマンドを入力 (insert/update/delete/select): ")
fmt.Scan(&command)
switch command {
case "insert":
dbInsert(db)
case "update":
dbUpdate(db)
default:
fmt.Println("無効なコマンド")
}
}
func dbUpdate(db *sql.DB) {
var id int
var name string
var age int
fmt.Print("更新対象のレコードのIDを入力: ")
fmt.Scan(&id)
fmt.Print("名前を入力: ")
fmt.Scan(&name)
fmt.Print("年齢を入力: ")
fmt.Scan(&age)
// UPDATE文を実行
result, err := db.Exec("UPDATE \"user\" SET name = $1, age = $2 WHERE id = $3", name, age, id)
log.Fatal(err)
}
// 更新成功時のメッセージと更新されたレコード内容を表示
rowsAffected, _ := result.RowsAffected()
if rowsAffected > 0 {
fmt.Println("更新しました。")
fmt.Printf("更新されたレコードのID: %d, 新しい名前: %s, 新しい年齢: %d\n", id, name, age)
} else {
fmt.Println("指定されたIDのレコードが見つかりませんでした。")
}
}
コマンドラインからの入力が、update の場合にデータ更新を行うようにしています。
これを実行してみます。
go run main.go
DB接続
コマンドを入力 (insert/update/delete/select): update
更新対象のレコードのIDを入力: 1
名前を入力: test_update
年齢を入力: 20
更新しました。
更新されたレコードのID: 1, 新しい名前: test_update, 新しい年齢: 20
PostgreSQLにもSelect句を投げてみます。
select * from public.user where id = 1;
id | name | age
----+-------------+-----
1 | test_update | 20
(1 row)
無事に更新できています。
続いてデータの検索です。
データ検索用の dbSelect 関数を追加しています。
func main() {
connStr := "user=user password=password dbname=sample sslmode=disable"
db, err := sql.Open("postgres", connStr)
log.Fatal(err)
}
fmt.Println("DB接続")
var command string
fmt.Print("コマンドを入力 (insert/update/delete/select): ")
fmt.Scan(&command)
switch command {
case "insert":
dbInsert(db)
case "update":
dbUpdate(db)
case "select":
dbSelect(db)
default:
fmt.Println("無効なコマンド")
}
}
func dbSelect(db *sql.DB) {
var id int
fmt.Print("検索対象のレコードのIDを入力: ")
fmt.Scan(&id)
// SELECT文を実行
row := db.QueryRow("SELECT id, name, age FROM \"user\" WHERE id = $1", id)
var selectedID int
var selectedName string
var selectedAge int
// 取得したレコードの値をスキャン
err := row.Scan(&selectedID, &selectedName, &selectedAge)
if err == sql.ErrNoRows {
fmt.Println("指定されたIDのレコードが見つかりませんでした。")
} else {
log.Fatal(err)
}
return
}
// 取得したレコードの内容を表示
fmt.Printf("ID: %d, 名前: %s, 年齢: %d\n", selectedID, selectedName, selectedAge)
}
コマンドラインからの入力が、select の場合にデータ検索を行うようにしています。
これを実行してみます。
go run main.go
DB接続
コマンドを入力 (insert/update/delete/select): select
検索対象のレコードのIDを入力: 1
ID: 1, 名前: test_update, 年齢: 20
PostgreSQLにもSelect句を投げてみます。
select * from public.user where id = 1;
id | name | age
----+-------------+-----
1 | test_update | 20
(1 row)
無事に検索できています。
続いてデータの削除です。
データ削除用の dbDelete 関数を追加しています。
func main() {
connStr := "user=user password=password dbname=sample sslmode=disable"
db, err := sql.Open("postgres", connStr)
log.Fatal(err)
}
fmt.Println("DB接続")
var command string
fmt.Print("コマンドを入力 (insert/update/delete/select): ")
fmt.Scan(&command)
switch command {
case "insert":
dbInsert(db)
case "update":
dbUpdate(db)
case "select":
dbSelect(db)
case "delete":
dbDelete(db)
default:
fmt.Println("無効なコマンド")
}
}
func dbDelete(db *sql.DB) {
var id int
fmt.Print("削除対象のレコードのIDを入力: ")
fmt.Scan(&id)
// DELETE文を実行
result, err := db.Exec("DELETE FROM \"user\" WHERE id = $1", id)
log.Fatal(err)
}
// 削除成功時のメッセージを表示
rowsAffected, _ := result.RowsAffected()
if rowsAffected > 0 {
fmt.Println("削除しました。")
} else {
fmt.Println("指定されたIDのレコードが見つかりませんでした。")
}
}
コマンドラインからの入力が、delete の場合にデータ削除を行うようにしています。
これを実行してみます。
go run main.go
DB接続
コマンドを入力 (insert/update/delete/select): delete
削除対象のレコードのIDを入力: 1
削除しました。
PostgreSQLにもSelect句を投げてみます。
select * from public.user where id = 1;
id | name | age
----+------+-----
(0 rows)
無事に削除できています。
以上サンプルになります。