0. 견적
sqlx 주소: https://github.com/jmoiron/sqlx
PostgreSQL 공식 웹사이트:https://www.postgresql.org/
1. PostgreSQL 설치 및 실행
공식 웹사이트로 이동하여 바이너리 패키지 https://www.postgresql.org/download/를 다운로드할 수 있습니다.
apt, 소스 코드 또는 WAPP, LAPP 등을 사용하여 설치할 수도 있습니다.
docker가 더 편리하기 때문에 docker를 직접 설치하고 실행하여
데이터 저장을 위한 디렉토리를 생성합니다.
mkdir /data
mkdir /data/postgres
PostgreSQL 실행
docker run -it --name postgres --restart always -e POSTGRES_PASSWORD='admin123' -e ALLOW_IP_RANGE=0.0.0.0/0 -v /data/postgres:/var/lib/postgresql -p 54321:5432 -d postgres
-e POSTGRES_PASSWORD='abc123'
비밀번호를 admin123으로 설정-e ALLOW_IP_RANGE=0.0.0.0/0
모든 IP는 연결할 수 있습니다-v /data/postgres:/var/lib/postgresql
데이터는 /data/postgres에 로컬로 존재합니다.-p 54321:5432
지정된 포트는 54321입니다.
PgAdmin4 연결 테스트
2. 데이터베이스에 연결하기 위해 이동
가장 중요한 것은 dsn을 설정하는 것입니다. 호스트는 데이터베이스 IP 또는 도메인 이름으로 설정됩니다. 포트는 기본적으로 포트 5432입니다. 여기서는 54321을 사용합니다. 사용자는 postgres, 암호는 admin123입니다. dbname은 요구 사항에 따라 설정됩니다.
package main
import (
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
var db *sqlx.DB
func initDB() (err error) {
dsn := "host=X.X.X.X port=54321 user=postgres password=admin123 dbname=postgres sslmode=disable"
db, err := sqlx.Connect("postgres", dsn)
if err != nil {
fmt.Printf("connect DB failed, err:%v\n", err)
return
}
db.SetMaxOpenConns(50)
db.SetMaxIdleConns(5)
return
}
func main() {
err := initDB()
if err != nil {
return
}
fmt.Println("DB Connected...")
}
3. 테스트용 라이브러리 및 테이블 생성
test
테스트용 새 데이터베이스 만들기
CREATE DATABASE "test"
WITH
ENCODING = 'UTF8'
;
또 다른 테이블을 구축user_info
CREATE TABLE "public"."user_info" (
"id" serial4,
"uid" int8 NOT NULL,
"name" varchar(255) NOT NULL,
"group" varchar(255) NOT NULL,
"balance" decimal(8,2) NOT NULL,
"proportion" float8 NOT NULL,
"create_time" timestamp NOT NULL,
"comments" varchar(255),
PRIMARY KEY ("id")
);
CREATE INDEX "indexs" ON "public"."user_info" USING btree (
"name",
"group"
);
CREATE UNIQUE INDEX "uniques" ON "public"."user_info" USING btree (
"uid"
);
4. 추가, 삭제 및 수정
sqlx의 exec 추가, 삭제 및 사용
인서트 증가
? ,? ,?
데이터를 삽입할 때 MySQL에서 사용하는 자리 표시자 와 PG에서 사용하는 자리 표시자 에 주의하십시오.$1 ,$2 ,$3
func testInsert() {
sqli := `INSERT INTO "public"."user_info"
("uid", "name", "group", "balance", "proportion", "create_time", "comments")
VALUES ($1, $2, $3, $4, $5, $6, $7);`
_, err := db.Exec(sqli, 100, "名字", "组", 2.33, 27.148, "2022-05-08 18:11:22", nil)
if err != nil {
fmt.Printf("insert failed, err:%v\n", err)
return
}
fmt.Printf("insert success\n")
}
삭제 삭제
ID가 6인 행 삭제
func testDelete() {
sqld := `DELETE FROM "public"."user_info" WHERE "id" = $1`
ret, err := db.Exec(sqld, 6)
if err != nil {
fmt.Printf("delete failed, err:%v\n", err)
return
}
n, err := ret.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("delete success, affected rows:%d\n", n)
}
업데이트 변경
uid 100으로 이름을 Zhang San으로 변경
func testUpdate() {
sqlu := `UPDATE "public"."user_info" SET "name" = $1 WHERE "uid" = $2`
ret, err := db.Exec(sqlu, "张三", 100)
if err != nil {
fmt.Printf("update failed, err:%v\n", err)
return
}
n, err := ret.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return
}
fmt.Printf("update success, affected rows:%d\n", n)
}
5. 확인
쿼리하기 전에 구조체를 작성하고 찾은 후 바로 바인딩
type UserInfoType struct {
Id int `db:"id"`
Uid int64 `db:"uid"`
Name string `db:"name"`
Group string `db:"group"`
Balance float64 `db:"balance"`
Proportion float64 `db:"proportion"`
CreateTime time.Time `db:"create_time"`
Comments sql.NullString `db:"comments"`
}
5.1 단일 데이터 행 쿼리
func testSelectOne() {
sqls := `SELECT * FROM "public"."user_info" WHERE "uid" = $1`
var user UserInfoType
err := db.Get(&user, sqls, 100)
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
}
fmt.Printf("one user: %#v\n", user)
}
5.2 여러 행의 데이터 쿼리
func testSelectAll() {
sqls := `SELECT * FROM "public"."user_info" WHERE "uid" > $1`
var users []UserInfoType
err := db.Select(&users, sqls, 0)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
fmt.Printf("all users: %#v\n", users)
}
5.3 쿼리 중
uid가 설정된 행을 쿼리합니다(2,3).
func testSelectIn() {
uids := []int{
2, 3}
sqlin := `SELECT * FROM "public"."user_info" WHERE "uid" in(?)`
query, args, err := sqlx.In(sqlin, uids)
if err != nil {
fmt.Printf("sqlin failed, err:%v\n", err)
return
}
query = db.Rebind(query)
fmt.Println(query)
var users []UserInfoType
err = db.Select(&users, query, args...)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
fmt.Printf("all user: %#v\n", users)
}