golang使用json格式实现增删查改的实现示例
需求和思路
在一般的小项目或者一个小软件,例如客户端之类的小程序中,可能会需要数据的持久化.但是使用一般的数据库(Mysql)之类的不合适.使用sqlite3这种嵌入式的是个较好的方法,但是Go语言中sqlite3的库是C语言的,Cgo不支持跨平台编译.正是由于这种需求,才想到使用json格式将数据直接保存在文件中.
具体的思路是怎么样呢?在Go语言中如果要将数据转化成json格式的话,有两种格式struct和map.如果同时需要增删查改功能的话,将map作为中间格式是比较合适的.接下来我们就来实现它.
查询操作
这种操作的实现比较简单,直接将文件中的数据读取出来,使用json库反序列化就可以了.代码如下:
typeProductstruct{
Namestring`json:"name"`
Numint`json:"num"`
}
funcfindAll(){
ps:=make([]Product,0)
data,err:=ioutil.ReadFile("./index.json")
iferr!=nil{
log.Fatal(err)
}
//这里参数要指定为变量的地址
err=json.Unmarshal(data,&ps)
iferr!=nil{
log.Fatal(err)
}
fmt.Println(ps)
}
添加操作
添加的实现实在查询的基础上的,我们需要先查询文件中的数据库,并转化为map格式,再将struct也转化为map格式(这里要使用反射),合并map,json序列化,最后保存在文件中.代码如下:
funccreate(){
fields:=make([]map[string]interface{},0)
p1:=&Product{
Name:"Blog",
Num:2,
}
_,_=json.Marshal(p1)
//读取文件中的数据,保存为map格式
data,_:=ioutil.ReadFile("./index.json")
err:=json.Unmarshal(data,&fields)
iferr!=nil{
log.Fatal(err)
}
//使用反射将struct转化为map
tp:=reflect.TypeOf(p1).Elem()
vp:=reflect.ValueOf(p1).Elem()
field:=make(map[string]interface{},0)
fori:=0;i
条件查询
思路:将struct转化为map,根据输入的条件查询.查询的结果转化为struct.代码如下:
funcFindOne(){
product:=&Product{}
p1:=&Product{
Name:"John",
Num:23,
}
//使用反射将struct转化为map
tp:=reflect.TypeOf(p1).Elem()
vp:=reflect.ValueOf(p1).Elem()
field:=make(map[string]interface{},0)
fori:=0;i
修改操作
修改操作在查询操作的基础上实现,修改操作需要有一个id值,能确定元素的唯一性.代码如下:
funcUpdate(){
p1:=&Product{
Id:"2bbec87025968879c3c9682abe3bf730",
Name:"John_e",
Num:100,
}
//使用反射将struct转化为map
tp:=reflect.TypeOf(p1).Elem()
vp:=reflect.ValueOf(p1).Elem()
field:=make(map[string]interface{},0)
fori:=0;i
删除操作
最后就是删除操作了,这个比较思路简单,输入唯一的id值,删除对应的字段,再保存到文件就可以了.代码如下:
funcDelete(){
p1:=&Product{
Id:"db43fa2d4f69cddce7494941cb36032b",
Name:"John_e",
Num:100,
}
_,_=json.Marshal(p1)
//读取文件中的数据,保存为map格式
//数据转化为map时,数值类型的统一变成float64
data,_:=ioutil.ReadFile("./index.json")
fields:=make([]map[string]interface{},0)
err:=json.Unmarshal(data,&fields)
iferr!=nil{
log.Fatal(err)
}
length:=len(fields)
forindex,field:=rangefields{
iffield["_id"]==p1.Id{
ifindex==length-1{
fields=fields[0:index]
}else{
fields=append(fields[0:index],fields[index+1:]...)
}
}
}
out,_:=json.MarshalIndent(fields,"","")
_=ioutil.WriteFile("./index.json",out,0755)
}
完整版
最后在附上完整版代码:
packagestore
import(
"bytes"
"crypto/md5"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"strings"
"time"
)
typeStorestruct{
Dirstring
}
funcNewStore(dirstring)(*Store,error){
//.开头的为相对路径,补全为全路径
ifstrings.HasPrefix(dir,"."){
pwd,_:=os.Getwd()
dir=filepath.Join(pwd,dir)
}
store:=&Store{Dir:dir}
st,err:=os.Stat(dir)
iferr!=nil{
err=os.Mkdir(dir,0755)
iferr!=nil{
returnnil,err
}
}elseifst!=nil&&!st.IsDir(){
returnnil,errors.New("filealreadyexists")
}
returnstore,nil
}
//创建与结构体对应的json文件
func(s*Store)Sync(values...interface{})error{
for_,v:=rangevalues{
tb:=parseTn(v)
iftb==""{
returnerrors.New("doesnotfindstore")
}
_path:=filepath.Join(s.Dir,tb)
_,err:=os.Stat(_path)
iferr!=nil{
_=ioutil.WriteFile(_path,[]byte("[]"),0755)
}
}
returnnil
}
//删除所有
func(s*Store)Destroy()error{
returnos.RemoveAll(s.Dir)
}
func(s*Store)FindAll(vinterface{})error{
_path,err:=s.before(v)
iferr!=nil{
returnerr
}
out,err:=s.readAll(_path)
iferr!=nil{
returnerr
}
err=json.Unmarshal(out,&v)
returnerr
}
func(s*Store)FindOne(vinterface{},columns...string)(interface{},error){
_path,err:=s.before(v)
iferr!=nil{
returnnil,err
}
data,err:=s.readAll(_path)
iferr!=nil{
returnnil,err
}
fields:=make([]map[string]interface{},0)
err=json.Unmarshal(data,&fields)
iferr!=nil{
returnnil,err
}
m:=structToMap(v)
length:=len(columns)
for_,item:=rangefields{
fori:=0;i90||index-point<2{
out.WriteByte(b)
continue
}
//首字符大写,直接转化为小写
ifindex==0{
out.WriteByte(b+32)
point=index
}
//连续三个大写,触发转化
ifindex-point>=2{
out.WriteByte(95)
out.WriteByte(b+32)
point=index
}
}
returnout.String()
}
funcparseTn(vinterface{})string{
varnamestring
tp:=reflect.TypeOf(v).Elem()
switchtp.Kind(){
casereflect.Ptr:
sp:=strings.Split(tp.String(),".")
name=sp[len(sp)-1]
casereflect.Slice:
sp:=strings.Split(tp.String(),".")
name=sp[len(sp)-1]
casereflect.Struct:
name=tp.Name()
}
name=toSnake(name)
returnname+".json"
}
funcrandId()string{
returnfmt.Sprintf("%x",md5.Sum([]byte(time.Now().String())))
}
到此这篇关于golang使用json格式实现增删查改的实现示例的文章就介绍到这了,更多相关golangjson增删查改内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!