数据库缓存

This commit is contained in:
hoteas 2019-11-10 18:00:45 +08:00
parent 7d479f181a
commit 048c457303
4 changed files with 127 additions and 104 deletions

View File

@ -2,7 +2,10 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="b2aca021-ff30-4cbf-8dc9-8cdd4f4c39dc" name="Default Changelist" comment=""> <list default="true" id="b2aca021-ff30-4cbf-8dc9-8cdd4f4c39dc" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/dri/db/auto.go" beforeDir="false" afterPath="$PROJECT_DIR$/dri/db/auto.go" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/application.go" beforeDir="false" afterPath="$PROJECT_DIR$/application.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/cache_db.go" beforeDir="false" afterPath="$PROJECT_DIR$/cache_db.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/db.go" beforeDir="false" afterPath="$PROJECT_DIR$/db.go" afterDir="false" />
</list> </list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@ -29,6 +32,7 @@
<property name="aspect.path.notification.shown" value="true" /> <property name="aspect.path.notification.shown" value="true" />
<property name="go.import.settings.migrated" value="true" /> <property name="go.import.settings.migrated" value="true" />
<property name="go.sdk.automatically.set" value="true" /> <property name="go.sdk.automatically.set" value="true" />
<property name="go.tried.to.enable.integration.vgo.integrator" value="true" />
</component> </component>
<component name="RunDashboard"> <component name="RunDashboard">
<option name="ruleStates"> <option name="ruleStates">
@ -69,7 +73,7 @@
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1573372557346</updated> <updated>1573372557346</updated>
<workItem from="1573372558521" duration="18000" /> <workItem from="1573372558521" duration="18000" />
<workItem from="1573372583551" duration="3256000" /> <workItem from="1573372583551" duration="5432000" />
</task> </task>
<task id="LOCAL-00001" summary="清理"> <task id="LOCAL-00001" summary="清理">
<created>1573372845218</created> <created>1573372845218</created>
@ -99,7 +103,14 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1573375745411</updated> <updated>1573375745411</updated>
</task> </task>
<option name="localTasksCounter" value="5" /> <task id="LOCAL-00005" summary="自动设置数据库">
<created>1573375887561</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1573375887561</updated>
</task>
<option name="localTasksCounter" value="6" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">

View File

@ -7,12 +7,12 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"log"
"strings" "strings"
) )
@ -21,7 +21,7 @@ type Application struct {
Router Router
contextBase contextBase
Port string //端口号 Port string //端口号
TLSPort string //ssl访问端口号 TLSPort string //ssl访问端口号
connectListener []func(this *Context) bool //所有的访问监听,true按原计划继续使用false表示有监听器处理 connectListener []func(this *Context) bool //所有的访问监听,true按原计划继续使用false表示有监听器处理
connectDbFunc func(err ...*Error) *sql.DB connectDbFunc func(err ...*Error) *sql.DB
configPath string configPath string
@ -97,47 +97,38 @@ func (this *Application) Run(router Router) {
IsRun = true IsRun = true
} }
ch := make(chan int) ch := make(chan int)
if ObjToCeilInt(this.Port)!=0{ if ObjToCeilInt(this.Port) != 0 {
go func() { go func() {
App[this.Port] = this App[this.Port] = this
this.Server.Handler = this this.Server.Handler = this
//启动服务 //启动服务
this.Server.Addr = ":" + this.Port this.Server.Addr = ":" + this.Port
err:=this.Server.ListenAndServe() err := this.Server.ListenAndServe()
log.Println(err) log.Println(err)
ch <-1 ch <- 1
}()
}else if ObjToCeilInt(this.TLSPort)!=0{
go func() {
App[this.TLSPort] = this
this.Server.Handler = this
//启动服务
this.Server.Addr = ":" + this.TLSPort
err:=this.Server.ListenAndServeTLS(this.Config.GetString("tlsCert"),this.Config.GetString("tlsKey"))
log.Println(err)
ch <-2
}() }()
}else{ } else if ObjToCeilInt(this.TLSPort) != 0 {
go func() {
App[this.TLSPort] = this
this.Server.Handler = this
//启动服务
this.Server.Addr = ":" + this.TLSPort
err := this.Server.ListenAndServeTLS(this.Config.GetString("tlsCert"), this.Config.GetString("tlsKey"))
log.Println(err)
ch <- 2
}()
} else {
log.Println("没有端口启用") log.Println("没有端口启用")
return return
} }
value := <-ch
value := <- ch
log.Println("启动服务失败 : ", value) log.Println("启动服务失败 : ", value)
} }
@ -153,11 +144,13 @@ func (this *Application) SetConnectDB(connect func(err ...*Error) *sql.DB) {
this.connectDbFunc = connect this.connectDbFunc = connect
this.Db.SetConnect(this.connectDbFunc) this.Db.SetConnect(this.connectDbFunc)
this.Db.DBCached=false this.Db.DBCached = false
if this.Config.GetCeilInt("dbCached")!=0{ if this.Config.GetCeilInt("dbCached") != 0 {
this.Db.DBCached=true this.Db.DBCached = true
} }
this.Db.Type = this.Config.GetString("dbType")
} }
//设置配置文件路径全路径或者相对路径 //设置配置文件路径全路径或者相对路径
@ -220,7 +213,7 @@ func (this *Application) SetConfig(configPath ...string) {
this.Config.Put(k, v) //程序配置 this.Config.Put(k, v) //程序配置
Config.Put(k, v) //系统配置 Config.Put(k, v) //系统配置
} }
}else { } else {
log.Println("配置文件不存在,或者配置出错,使用缺省默认配置") log.Println("配置文件不存在,或者配置出错,使用缺省默认配置")
} }
@ -232,11 +225,10 @@ func (this *Application) SetConfig(configPath ...string) {
err = json.Indent(&out, []byte(this.Config.ToJsonString()), "", "\t") err = json.Indent(&out, []byte(this.Config.ToJsonString()), "", "\t")
//判断配置文件是否序列有变化有则修改配置,五则不变 //判断配置文件是否序列有变化有则修改配置,五则不变
//fmt.Println(len(btes)) //fmt.Println(len(btes))
if len(btes)!=0&&out.String()==string(btes){ if len(btes) != 0 && out.String() == string(btes) {
return return
} }
err = ioutil.WriteFile(this.configPath, out.Bytes(), os.ModeAppend) err = ioutil.WriteFile(this.configPath, out.Bytes(), os.ModeAppend)
if err != nil { if err != nil {

View File

@ -2,8 +2,8 @@ package hotime
import ( import (
"encoding/json" "encoding/json"
"time"
"strings" "strings"
"time"
) )
type CacheDb struct { type CacheDb struct {
@ -17,18 +17,46 @@ func (this *CacheDb) initDbTable() {
if this.isInit { if this.isInit {
return return
} }
if this.Db.Type == "mysql" {
dbNames := this.Db.Query("SELECT DATABASE()") dbNames := this.Db.Query("SELECT DATABASE()")
if len(dbNames) == 0 {
return
}
dbName := dbNames[0].GetString("DATABASE()")
res := this.Db.Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='" + dbName + "' AND TABLE_NAME='cached'")
if len(res) != 0 {
this.isInit = true
return
}
_, e := this.Db.Exec("CREATE TABLE `cached` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ckey` varchar(60) DEFAULT NULL, `cvalue` varchar(2000) DEFAULT NULL, `time` bigint(20) DEFAULT NULL, `endtime` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=198740 DEFAULT CHARSET=utf8")
if e.GetError() == nil {
this.isInit = true
}
if len(dbNames) == 0 {
return
} }
dbName := dbNames[0].GetString("DATABASE()")
res := this.Db.Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='" + dbName + "' AND TABLE_NAME='cached'") if this.Db.Type == "sqlite" {
if len(res) == 0 { res := this.Db.Query(`select * from sqlite_master where type = 'table' and name = 'cached'`)
this.Db.Exec("CREATE TABLE `cached` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ckey` varchar(60) DEFAULT NULL, `cvalue` varchar(2000) DEFAULT NULL, `time` bigint(20) DEFAULT NULL, `endtime` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=198740 DEFAULT CHARSET=utf8")
if len(res) != 0 {
this.isInit = true
return
}
_, e := this.Db.Exec(`CREATE TABLE "cached" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"ckey" TEXT(60),
"cvalue" TEXT(2000),
"time" integer,
"endtime" integer
);`)
if e.GetError() == nil {
this.isInit = true
}
} }
this.isInit = true
} }
@ -71,13 +99,13 @@ func (this *CacheDb) set(key string, value interface{}, tim int64) {
func (this *CacheDb) delete(key string) { func (this *CacheDb) delete(key string) {
del:=strings.Index(key,"*") del := strings.Index(key, "*")
//如果通配删除 //如果通配删除
if del!=-1{ if del != -1 {
key=Substr(key,0,del) key = Substr(key, 0, del)
this.Db.Delete("cached", Map{"ckey": key+"%"}) this.Db.Delete("cached", Map{"ckey": key + "%"})
}else{ } else {
this.Db.Delete("cached", Map{"ckey": key}) this.Db.Delete("cached", Map{"ckey": key})
} }
} }

96
db.go
View File

@ -13,6 +13,7 @@ type HoTimeDB struct {
*sql.DB *sql.DB
contextBase contextBase
CacheIns CacheIns
Type string
DBCached bool DBCached bool
LastQuery string LastQuery string
LastData []interface{} LastData []interface{}
@ -31,7 +32,7 @@ func (this *HoTimeDB) SetConnect(connect func(err ...*Error) *sql.DB, err ...*Er
//事务如果action返回true则执行成功false则回滚 //事务如果action返回true则执行成功false则回滚
func (this *HoTimeDB) Action(action func(db HoTimeDB) bool) bool { func (this *HoTimeDB) Action(action func(db HoTimeDB) bool) bool {
db := HoTimeDB{DB: this.DB,CacheIns:this.CacheIns,DBCached:this.DBCached} db := HoTimeDB{DB: this.DB, CacheIns: this.CacheIns, DBCached: this.DBCached}
tx, err := db.Begin() tx, err := db.Begin()
if err != nil { if err != nil {
this.LastErr.SetError(err) this.LastErr.SetError(err)
@ -120,11 +121,11 @@ func (this *HoTimeDB) Row(resl *sql.Rows) []Map {
} }
//防止int被误读为float64 //防止int被误读为float64
jlis,e:=json.Marshal(lis) jlis, e := json.Marshal(lis)
if e!=nil{ if e != nil {
this.LastErr.SetError(e) this.LastErr.SetError(e)
}else{ } else {
lis.JsonToMap(string(jlis),&this.LastErr) lis.JsonToMap(string(jlis), &this.LastErr)
} }
dest = append(dest, lis) dest = append(dest, lis)
@ -433,37 +434,30 @@ func (this *HoTimeDB) Select(table string, qu ...interface{}) []Map {
query += temp query += temp
qs = append(qs, resWhere...) qs = append(qs, resWhere...)
md5:=this.md5(query,qs...) md5 := this.md5(query, qs...)
if this.DBCached&&this.CacheIns!=nil{ if this.DBCached && this.CacheIns != nil {
//如果缓存有则从缓存取 //如果缓存有则从缓存取
cacheData:=this.Cache(table+":"+md5) cacheData := this.Cache(table + ":" + md5)
if cacheData.Data!=nil{ if cacheData.Data != nil {
return cacheData.ToMapArray() return cacheData.ToMapArray()
} }
} }
//无缓存则数据库取 //无缓存则数据库取
res := this.Query(query, qs...) res := this.Query(query, qs...)
if res == nil { if res == nil {
res=[]Map{} res = []Map{}
} }
//缓存 //缓存
if this.DBCached&&this.CacheIns!=nil{ if this.DBCached && this.CacheIns != nil {
this.Cache(table+":"+md5,res) this.Cache(table+":"+md5, res)
} }
return res return res
} }
@ -592,7 +586,6 @@ func (this *HoTimeDB) where(data Map) (string, []interface{}) {
} }
} else { } else {
//fmt.Println(v) //fmt.Println(v)
where += " " + ObjToStr(v) where += " " + ObjToStr(v)
@ -641,17 +634,17 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
where += "`" + k + "` LIKE ? " where += "`" + k + "` LIKE ? "
v = "%" + ObjToStr(v) + "%" v = "%" + ObjToStr(v) + "%"
res = append(res, v) res = append(res, v)
case "[!~]"://左边任意 case "[!~]": //左边任意
k = strings.Replace(k, "[~]", "", -1) k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? " where += "`" + k + "` LIKE ? "
v = "%" + ObjToStr(v) v = "%" + ObjToStr(v)
res = append(res, v) res = append(res, v)
case "[~!]"://右边任意 case "[~!]": //右边任意
k = strings.Replace(k, "[~]", "", -1) k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? " where += "`" + k + "` LIKE ? "
v = ObjToStr(v) +"%" v = ObjToStr(v) + "%"
res = append(res, v) res = append(res, v)
case "[~~]"://手动任意 case "[~~]": //手动任意
k = strings.Replace(k, "[~]", "", -1) k = strings.Replace(k, "[~]", "", -1)
where += "`" + k + "` LIKE ? " where += "`" + k + "` LIKE ? "
//v = ObjToStr(v) //v = ObjToStr(v)
@ -684,9 +677,9 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
if reflect.ValueOf(v).Type().String() == "hotime.Slice" { if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
where += "`" + k + "` IN (" where += "`" + k + "` IN ("
res = append(res, (v.(Slice))...) res = append(res, (v.(Slice))...)
if len(v.(Slice))==0{ if len(v.(Slice)) == 0 {
where+=") " where += ") "
}else{ } else {
for i := 0; i < len(v.(Slice)); i++ { for i := 0; i < len(v.(Slice)); i++ {
if i+1 != len(v.(Slice)) { if i+1 != len(v.(Slice)) {
where += "?," where += "?,"
@ -708,11 +701,11 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
} else if k == "[#]" { } else if k == "[#]" {
k = strings.Replace(k, "[#]", "", -1) k = strings.Replace(k, "[#]", "", -1)
where += " " + ObjToStr(v) + " " where += " " + ObjToStr(v) + " "
} else { } else {
//fmt.Println(reflect.ValueOf(v).Type().String()) //fmt.Println(reflect.ValueOf(v).Type().String())
if v==nil{ if v == nil {
where += "`" + k + "` IS NULL" where += "`" + k + "` IS NULL"
}else if reflect.ValueOf(v).Type().String() == "hotime.Slice" { } else if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
//fmt.Println(v) //fmt.Println(v)
where += "`" + k + "` IN (" where += "`" + k + "` IN ("
@ -738,8 +731,8 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
} }
} else { } else {
where += "`" + k + "`=? " where += "`" + k + "`=? "
res = append(res, v) res = append(res, v)
} }
} }
@ -751,11 +744,11 @@ func (this *HoTimeDB) varCond(k string, v interface{}) (string, []interface{}) {
func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interface{}) (string, []interface{}) { func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interface{}) (string, []interface{}) {
//where:="" //where:=""
//fmt.Println(reflect.ValueOf(v).Type().String()) //fmt.Println(reflect.ValueOf(v).Type().String())
if v==nil{ if v == nil {
where += "`" + k + "` IS NOT NULL " where += "`" + k + "` IS NOT NULL "
}else if reflect.ValueOf(v).Type().String() == "hotime.Slice" { } else if reflect.ValueOf(v).Type().String() == "hotime.Slice" {
where += "`" + k + "` NOT IN (" where += "`" + k + "` NOT IN ("
res = append(res, (v.(Slice))...) res = append(res, (v.(Slice))...)
for i := 0; i < len(v.(Slice)); i++ { for i := 0; i < len(v.(Slice)); i++ {
@ -779,9 +772,8 @@ func (this *HoTimeDB) notIn(k string, v interface{}, where string, res []interfa
} }
} else { } else {
where += "`" + k + "` !=? " where += "`" + k + "` !=? "
res = append(res, v) res = append(res, v)
} }
@ -861,15 +853,15 @@ func (this *HoTimeDB) Update(table string, data Map, where Map) int64 {
res, err := this.Exec(query, qs...) res, err := this.Exec(query, qs...)
rows:=int64(0) rows := int64(0)
if err.GetError() == nil &&res!=nil{ if err.GetError() == nil && res != nil {
rows, _ = res.RowsAffected() rows, _ = res.RowsAffected()
} }
//如果更新成功,则删除缓存 //如果更新成功,则删除缓存
if rows!=0{ if rows != 0 {
if this.DBCached&&this.CacheIns!=nil{ if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*",nil) this.Cache(table+"*", nil)
} }
} }
@ -884,15 +876,15 @@ func (this *HoTimeDB) Delete(table string, data map[string]interface{}) int64 {
query += temp query += temp
res, err := this.Exec(query, resWhere...) res, err := this.Exec(query, resWhere...)
rows:=int64(0) rows := int64(0)
if err.GetError() == nil &&res!=nil{ if err.GetError() == nil && res != nil {
rows, _ = res.RowsAffected() rows, _ = res.RowsAffected()
} }
//如果删除成功,删除对应缓存 //如果删除成功,删除对应缓存
if rows!=0{ if rows != 0 {
if this.DBCached&&this.CacheIns!=nil{ if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*",nil) this.Cache(table+"*", nil)
} }
} }
//return 0 //return 0
@ -925,16 +917,16 @@ func (this *HoTimeDB) Insert(table string, data map[string]interface{}) int64 {
res, err := this.Exec(query, values...) res, err := this.Exec(query, values...)
id:=int64(0) id := int64(0)
if err.GetError() == nil &&res!=nil{ if err.GetError() == nil && res != nil {
id, this.LastErr.err = res.LastInsertId() id, this.LastErr.err = res.LastInsertId()
} }
//如果插入成功,删除缓存 //如果插入成功,删除缓存
if id!=0{ if id != 0 {
if this.DBCached&&this.CacheIns!=nil{ if this.DBCached && this.CacheIns != nil {
this.Cache(table+"*",nil) this.Cache(table+"*", nil)
} }
} }