golang gorm 使用in_Go語言-GORM簡單上手
阿新 • • 發佈:2021-01-30
技術標籤:golang gorm 使用in
前言
GORM 是Go語言上目前最流行的ORM(物件關係對映(Object Relational Mapping,簡稱ORM)是通過使用描述物件和資料庫之間對映的元資料,將面嚮物件語言程式中的物件自動持久化到關係資料庫中)庫,其支援Mysql,Sqlite3,PostgreSQL和SqlServer資料庫,這篇文章我以最簡單的CURD來介紹GORM操作PostgreSQL.
安裝
- go module
- 如果你Golang版本是1.12+並開啟go module,直接在程式碼中先import
import ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/postgres")
- 再執行go mod tidy
$ go mod tidy go: downloading github.com/jinzhu/now v1.0.0go: downloading cloud.google.com/go v0.37.4go: downloading golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728cgo: downloading github.com/google/go-cmp v0.2.0
- gopath
- go get 安裝,然後import
go get -u github.com/jinzhu/gorm
定義postgresql結構體
結構體引數分別為host,user,password,dbname,port,sslmode和例項化gorm.db
type postgres struct {host stringuser stringpassword stringsslmode stringdbname stringport intdb *gorm.DB}
例項化結構體,將預設埠設定為5432
func NewPsql(post postgres) *postgres {if post.port==0 {post.port = 5432}return &postgres{host: post.host,user: post.user,password: post.password,sslmode: post.sslmode,dbname: post.dbname,port: post.port,db: post.db,}}
連線資料庫方法
func (p *postgres) Connect() *postgres {connectInfo := fmt.Sprintf("host=%s port=%d user=%s dbname=%s password=%s sslmode=%s",p.host, p.port, p.user, p.dbname, p.password, p.sslmode)db, err := gorm.Open("postgres", connectInfo)if err != nil {log.Println(err.Error())log.Println("Postgres 資料庫連線失敗")return nil}log.Println("Postgres 資料庫連線成功")p.db = dbreturn p}
測試資料庫連線
- docker 啟動一個postgresql資料庫
docker run -id --name postgres -p 5432:5432 -e POSTGRES_PASSWORD="123456" postgres
- 建立一個測試資料庫
psql -h 127.0.0.1 -U postgresPassword for user postgres:psql (12.1, server 12.3 (Debian 12.3-1.pgdg100+1))Type "help" for help.postgres=# l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges-----------+----------+----------+------------+------------+----------------------- postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 | template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres + | | | | | postgres=CTc/postgres(3 rows)postgres=# create database testdb;CREATE DATABASEpostgres=# c testdbpsql (12.1, server 12.3 (Debian 12.3-1.pgdg100+1))You are now connected to database "testdb" as user "postgres".
- 執行程式碼測試
func main() {NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb",}).Connect()}
$ go run main_postgresql.go2020/05/28 10:14:36 Postgres 資料庫連線成功
自動遷移
目前自動遷移僅支援表結構遷移
- 程式碼實現
func (p *postgres) AutoMigrate(out interface{}) {if err := p.db.AutoMigrate(out).Error; err != nil {log.Fatalf("自動建立表結構失敗%s", err.Error())return}log.Printf("自動建立表結構成功")}
- 定義表對映結構體
我們定義了一個簡單記錄人員資訊的結構體,ID為主鍵,自增,其他分別是Name,Sex,Age
type Member struct {ID uint `gorm:"primary_key"`Name string `json:"name"`Sex string `json:"sex"`Age int `json:"age"`}
- 根據結構體建立表結構
func main() {P := NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb",}).Connect() P.AutoMigrate(&Member{})}
$ go run main_postgresql.go2020/05/28 10:21:24 Postgres 資料庫連線成功2020/05/28 10:21:24 自動建立表結構成功
- 資料庫互動查看錶和表結構
testdb=# d List of relations Schema | Name | Type | Owner--------+----------------+----------+---------- public | members | table | postgres public | members_id_seq | sequence | postgres(2 rows)testdb=# d members Table "public.members" Column | Type | Collation | Nullable | Default--------+---------+-----------+----------+------------------------------------- id | integer | | not null | nextval('members_id_seq'::regclass) name | text | | | sex | text | | | age | integer | | |Indexes: "members_pkey" PRIMARY KEY, btree (id)
C-Create 建立資料
- 程式碼實現
// 方法實現func (p *postgres) Create(out interface{}) {// db.Create 需要傳入的引數是指標if err := p.db.Create(out).Error; err != nil {log.Fatalf("插入資料%v失敗err:%s", out, err.Error())return}log.Printf("插入資料%v成功", out)}// main函式呼叫,這裡批量建立5條資料func main() {P := NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb",}).Connect()P.AutoMigrate(&Member{})members := []Member{{Name: "zhangsan",Sex: "man",Age: 11,},{Name: "lisi",Sex: "man",Age: 12,},{Name: "wanger",Sex: "man",Age: 18,},{Name: "mazi",Sex: "man",Age: 16,},{Name: "liuliu",Sex: "man",Age: 11,},}for i := range members {P.Create(&members[i]) }}
$ go run main_postgresql.go2020/05/28 10:27:20 Postgres 資料庫連線成功2020/05/28 10:27:20 自動建立表結構成功2020/05/28 10:27:20 插入資料&{1 zhangsan man 功2020/05/28 10:27:20 插入資料&{2 lisi man 12}成功2020/05/28 10:27:20 插入資料&{3 wanger man 18}成功2020/05/28 10:27:20 插入資料&{4 mazi man 16}成功2020/05/28 10:27:20 插入資料&{5 liuliu man 11}成功# select * from memberstestdb=# select * from members; id | name | sex | age----+----------+-----+----- 1 | zhangsan | man | 11 2 | lisi | man | 12 3 | wanger | man | 18 4 | mazi | man | 16 5 | liuliu | man | 11(5 rows)
U-Update 更新資料
- 程式碼實現
// 方法func (p *postgres)Update(out interface{},data map[string]interface{},id uint) {if err := p.db.Model(out).Where("id = ?",id).Updates(data).Error;err != nil{log.Fatalf("更新%v資料id%d失敗err:%s", data,id, err.Error())return}log.Println("更新資料成功")}// mainfunc main() {P := NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb", }).Connect() P.Update(&Member{}, map[string]interface{}{"sex":"woman"},5)}
$ go run main_postgresql.go2020/05/28 10:37:45 Postgres 資料庫連線成功2020/05/28 10:37:45 更新資料成功# select * from members;testdb=# select * from members; id | name | sex | age----+----------+-------+----- 1 | zhangsan | man | 11 2 | lisi | man | 12 3 | wanger | man | 18 4 | mazi | man | 16 5 | liuliu | woman | 11(5 rows)
R-Retrieve 讀取資料
- 程式碼實現
func (p *postgres) Query(out interface{}) {if err := p.db.Find(out).Error; err != nil {log.Fatalf("查詢%v資料失敗err:%s", out, err.Error())return}log.Printf("查詢%v資料成功", out)fmt.Println(out)}// main呼叫func main() {P := NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb", }).Connect() q := &[]Member{} P.Query(q)}
$ go run main_postgresql.go2020/05/28 10:47:45 Postgres 資料庫連線成功2020/05/28 10:47:45 查詢&[{1 zhangsan man 11}2 lisi man 12} {4 mazi man 16} {5 liuliu woman 11}]資料成功&[{1 zhangsan man 11} {2 lisi man 12} {4 mazi man 16} {5 liuliu woman 11}]
D-Delete 刪除資料
- 程式碼實現
// 方法實現func (p *postgres)DeleteById(out interface{},id uint) {if err:=p.db.Where("id = ?",id).Delete(out).Error;err!=nil{log.Fatalf("資料id=%d刪除失敗",id)return}log.Printf("資料id=%d刪除成功",id)}// main 呼叫func main() {P := NewPsql(postgres{host: "127.0.0.1",user: "postgres",password: "123456",sslmode: "disable",dbname: "testdb", }).Connect() P.DeleteById(&Member{},3)}
$ go run main_postgresql.go2020/05/28 10:44:43 Postgres 資料庫連線成功2020/05/28 10:44:43 資料id=3刪除成功# select * from memberstestdb=# select * from members; id | name | sex | age----+----------+-------+----- 1 | zhangsan | man | 11 2 | lisi | man | 12 4 | mazi | man | 16 5 | liuliu | woman | 11(4 rows)
總結
通過以上示例,我們可以看到Gorm降低了開發人員使用資料的難度,讓sql語句可以用go程式碼簡單有快速實現,通過介面封裝,不管是mysql、postgresql、sqlserver、sqlite3,都可以使用相同的方法操作。