golang 开发入门02-使用bolt存储用户

Posted ljgeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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, 下篇将继续对代码进行优化。

以上是关于golang 开发入门02-使用bolt存储用户的主要内容,如果未能解决你的问题,请参考以下文章

golang elasticsearch 文档操作(CRUD) --- 2022-04-02

Part of defining a topology is specifying for each bolt which streams it should receive as input(示例代

Golang 从入门到放弃

golang 接口开发入门01- 从0开始构建项目

Golang 从入门到放弃

golang简明入门进阶指南02 数组切片map类型的基础使用