1. 程式人生 > 其它 >golang gorm 使用in_Go語言-GORM簡單上手

golang gorm 使用in_Go語言-GORM簡單上手

技術標籤:golang gorm 使用in

f06042e890948e8dacb560f36832bbd0.png

前言

GORM 是Go語言上目前最流行的ORM(物件關係對映(Object Relational Mapping,簡稱ORM)是通過使用描述物件和資料庫之間對映的元資料,將面嚮物件語言程式中的物件自動持久化到關係資料庫中)庫,其支援Mysql,Sqlite3,PostgreSQL和SqlServer資料庫,這篇文章我以最簡單的CURD來介紹GORM操作PostgreSQL.

安裝

  1. 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
  1. 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,都可以使用相同的方法操作。