golang 開發入門02-使用bolt存儲用戶


定義返回數據字段名

上一篇中,最后訪問http://localhost:8000/users?id=1 返回結果

{"Id":1,"Username":"Lily","Password":""}

這里首寫字母一般需要改為小寫,修改User結構體

// 用戶實體
type User struct {
	// 主鍵
	Login string `json:"login"`
	// 用戶登錄名
	Username string `json:"username"`
	// 登錄密碼
	Password string `json:"password"`
}

通過給字段添加json標簽來指定實際序列化之后的字段名稱;通過標簽不僅可以改變字段名稱,比如要忽略字段password

// 用戶實體
type User struct {
	// 主鍵
	Login string `json:"login"`
	// 用戶登錄名
	Username string `json:"username"`
	// 登錄密碼
	Password string `json:"-"`
	
	Birthday string `json:"birthday,omitempty"`
}

"-" 表示忽略字段, "omitempty" 表示忽略空值,再請求http://localhost:8000/users?id=1,返回結果

{"login":"lazy","username":"Lazy Gene","birthday":"2018-09-21"}

使用bolt保存用戶

bolt是一個go語言實現的鍵值數據庫,通過使用一個內存映射的磁盤文件來管理數據,簡單易用;上一篇中臨時使用map來保存用戶

type UserStoreImpl struct {
	// 用map 模擬存儲數據庫
	db map[int] *domain.User
}

在應用重啟后,數據自然也就丟失了,引入bolt 嵌入式數據庫

go get github.com/boltdb/bolt/...

修改 iflytek.com/store/user.go

package store

import (
	"iflytek.com/domain"
	"log"
	"github.com/boltdb/bolt"
	"time"
	"encoding/json"
)


func Get(login string) (*domain.User, error) {
	db,err := bolt.Open("user.db", 0600, &bolt.Options{Timeout: 1 *time.Second})
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	user := new(domain.User)
	db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte("users"))
		u := b.Get([]byte(login))
		err := json.Unmarshal(u, &user)
		return err
	})
	return user,nil
}

func Gets() ([]*domain.User,error ) {
	return nil,nil
}

func Save(u *domain.User) error {
	db,err := bolt.Open("user.db", 0600, &bolt.Options{Timeout: 1 *time.Second})
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	db.Update(func(tx *bolt.Tx) error {
        // 創建一個users桶
        b,err := tx.CreateBucketIfNotExists([]byte("users"))
		if err != nil {
		    return nil
		}
		encoded, err := json.Marshal(u)
	    if err != nil {
	      return err
	    }
	    return b.Put([]byte(u.Login), encoded)
	})
	return nil	
}

func Update(u *domain.User) error {
	return nil
}

func Delete(id int) error {
	return nil
}

看Save方法中

db,err := bolt.Open("user.db", 0600, &bolt.Options{Timeout: 1 *time.Second})

使用Open打開數據庫,第一個參數為庫路徑,第二參數為文件模式,0600 即當前用戶讀寫,第三個參數為配置參數,Timeout指定超時時間;再看

db.Update(func(tx *bolt.Tx) error { ...}

為寫操作,這里將傳入的用戶對象寫入到庫中,在Get方法 用db.View 讀取數據。

添加保存用戶接口

修改 iflytek.com/main.go,添加了post方法的實現,用來保存用戶

package main

import (
	"iflytek.com/domain"
	"iflytek.com/store"
	"net/http"
	"encoding/json"
	"fmt"
	"io/ioutil"
)

func main() {
	http.HandleFunc("/users", usersHandler)
    http.ListenAndServe(":8000", nil)
}

func usersHandler(w http.ResponseWriter, req *http.Request) {
	if req.Method == "GET" {
		id := req.URL.Query().Get("login")
		if id=="" {
			w.Write([]byte("未傳ID參數")); 
			return
		}
		user,_ := store.Get(id)
		fmt.Print(user)
		b,_ := json.Marshal(user)
		w.Write(b)
	} else if req.Method == "POST" {
		requestData,err := ioutil.ReadAll(req.Body)
		if err != nil {
			w.Write([]byte("{\"code\":1,\"msg\",\"解析參數失敗\"}"))
		}
		user := new(domain.User)
		json.Unmarshal(requestData, &user)
		err = store.Save(user)
		if err != nil {
			w.Write([]byte("{\"code\":1,\"msg\",\"保存失敗\"}"))
		}
		w.Write([]byte("{\"code\":0,\"msg\",\"OK\"}"))
	}
}

完成改造!此篇優化了數據展示和引入的存儲bolt, 下篇將繼續對代碼進行優化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM