ORM查询缓存特性开发中

This commit is contained in:
John
2018-07-19 15:33:17 +08:00
parent 9ebf00c455
commit 326a58e3fa
5 changed files with 90 additions and 33 deletions

1
TODO
View File

@ -15,6 +15,7 @@ gpage分页增加对自定义后缀的支持如:2.html, 2.php等等
gvalid包增加tag与校验规则绑定的支持特性
ghttp获取参数支持直接转struct功能
map转struct增加对tag的支持
gdb增加查询缓存特性
DONE:

View File

@ -16,6 +16,7 @@ import (
_ "github.com/go-sql-driver/mysql"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/container/gring"
"gitee.com/johng/gf/g/os/gcache"
)
const (
@ -83,13 +84,14 @@ type Link interface {
// 数据库链接对象
type Db struct {
link Link // 底层数据库类型管理对象
master *sql.DB // 实例化数据库链接(master)
slave *sql.DB // 实例化数据库链接(slave可能会与master相同)
charl string // SQL安全符号(左)
charr string // SQL安全符号(右)
debug *gtype.Bool // (默认关闭)是否开启调试模式,当开启时会启用一些调试特性
sqls *gring.Ring // (debug=true时有效)已执行的SQL列表
link Link // 底层数据库类型管理对象
master *sql.DB // 实例化数据库链接(master)
slave *sql.DB // 实例化数据库链接(slave可能会与master相同)
charl string // SQL安全符号(左)
charr string // SQL安全符号(右)
debug *gtype.Bool // (默认关闭)是否开启调试模式,当开启时会启用一些调试特性
sqls *gring.Ring // (debug=true时有效)已执行的SQL列表
cache *gcache.Cache // 查询缓存,需要注意的是,事务查询不支持缓存
}
// 执行的SQL对象
@ -222,6 +224,7 @@ func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) {
charl : link.getQuoteCharLeft(),
charr : link.getQuoteCharRight(),
debug : gtype.NewBool(),
cache : gcache.New(),
}, nil
}

View File

@ -28,6 +28,9 @@ type Model struct {
limit int // 分页条数
data interface{} // 操作记录(支持Map/List/string类型)
batch int // 批量操作条数
cacheEnabled bool // 当前SQL操作是否开启查询缓存功能
cacheTime int // 查询缓存时间
cacheName string // 查询缓存名称
}
// 链式操作,数据表字段,可支持多个表,以半角逗号连接
@ -243,13 +246,22 @@ func (md *Model) Batch(batch int) *Model {
return md
}
// 查询缓存/清除缓存操作,需要注意的是,事务查询不支持缓存。
// 当time < 0时表示清除缓存 time=0时表示不过期, time > 0时表示过期时间time过期时间单位
// name表示自定义的缓存名称便于业务层精准定位缓存项(如果业务层需要手动清理时,必须指定缓存名称)
// 例如:查询缓存时设置名称,清理缓存时可以给定清理的缓存名称进行精准清理。
func (md *Model) Cache(time int, name ... string) *Model {
md.cacheEnabled = true
md.cacheTime = time
if len(name) > 0 {
md.cacheName = name[0]
}
return md
}
// 链式操作select
func (md *Model) Select() (Result, error) {
if md.tx == nil {
return md.db.GetAll(md.getFormattedSql(), md.whereArgs...)
} else {
return md.tx.GetAll(md.getFormattedSql(), md.whereArgs...)
}
return md.getAll(md.getFormattedSql(), md.whereArgs...)
}
// 链式操作,查询所有记录
@ -269,15 +281,6 @@ func (md *Model) One() (Record, error) {
return nil, nil
}
// 链式操作查询单条记录并自动转换为struct对象
func (md *Model) Struct(obj interface{}) error {
one, err := md.One()
if err != nil {
return err
}
return one.ToStruct(obj)
}
// 链式操作,查询字段值
func (md *Model) Value() (Value, error) {
one, err := md.One()
@ -290,8 +293,17 @@ func (md *Model) Value() (Value, error) {
return nil, nil
}
// 链式操作查询单条记录并自动转换为struct对象
func (md *Model) Struct(obj interface{}) error {
one, err := md.One()
if err != nil {
return err
}
return one.ToStruct(obj)
}
// 链式操作查询数量fields可以为空也可以自定义查询字段
// 当给定自定义查询字段时,该字段必须为数量结果,否则会引起歧义,如:Fields("COUNT(id)")
// 当给定自定义查询字段时,该字段必须为数量结果,否则会引起歧义,使用如md.Fields("COUNT(id)")
func (md *Model) Count() (int, error) {
if md.fields == "" || md.fields == "*" {
md.fields = "COUNT(1)"
@ -300,11 +312,43 @@ func (md *Model) Count() (int, error) {
if len(md.groupBy) > 0 {
s = fmt.Sprintf("SELECT COUNT(1) FROM (%s) count_alias", s)
}
if md.tx == nil {
return md.db.GetCount(s, md.whereArgs...)
} else {
return md.tx.GetCount(s, md.whereArgs...)
list, err := md.getAll(s, md.whereArgs...)
if err != nil {
return 0, err
}
if len(list) > 0 {
for _, v := range list[0] {
return gconv.Int(v), nil
}
}
return 0, nil
}
// 查询操作对底层SQL操作的封装
func (md *Model) getAll(sql string, args...interface{}) (Result, error) {
var err error
var result Result
var cacheKey string
// 查询缓存查询处理
if md.cacheEnabled && md.tx == nil {
cacheKey = md.cacheName
if len(cacheKey) == 0 {
cacheKey = sql
}
if v := md.db.cache.Get(cacheKey); v != nil {
return v.(Result), nil
}
}
if md.tx == nil {
result, err = md.db.GetAll(sql, args...)
} else {
result, err = md.tx.GetAll(sql, args...)
}
// 查询缓存保存处理
if len(cacheKey) > 0 && md.cacheTime >= 0 {
md.db.cache.Set(cacheKey, result, md.cacheTime*1000)
}
return result, err
}
// 格式化当前输入参数返回可执行的SQL语句不带参数
@ -326,4 +370,4 @@ func (md *Model) getFormattedSql() string {
s += fmt.Sprintf(" LIMIT %d, %d", md.start, md.limit)
}
return s
}
}

View File

@ -72,12 +72,12 @@ func SetCap(cap int) {
}
// (使用全局KV缓存对象)设置kv缓存键值对过期时间单位为毫秒
func Set(key string, value interface{}, expire int64) {
func Set(key string, value interface{}, expire int) {
cache.Set(key, value, expire)
}
// (使用全局KV缓存对象)批量设置kv缓存键值对过期时间单位为毫秒
func BatchSet(data map[string]interface{}, expire int64) {
func BatchSet(data map[string]interface{}, expire int) {
cache.BatchSet(data, expire)
}
@ -97,7 +97,7 @@ func BatchRemove(keys []string) {
}
// 基于内存缓存的锁锁成功返回true失败返回false当失败时表示有其他的锁存在
func Lock(key string, expire int64) bool {
func Lock(key string, expire int) bool {
if v := cache.Get(key); v != nil {
return false
}
@ -160,7 +160,7 @@ func (c *Cache) getOrNewExpireSet(expire int64) *gset.StringSet {
}
// 设置kv缓存键值对过期时间单位为毫秒expire<=0表示不过期
func (c *Cache) Set(key string, value interface{}, expire int64) {
func (c *Cache) Set(key string, value interface{}, expire int) {
var e int64
if expire != 0 {
e = gtime.Millisecond() + int64(expire)
@ -174,7 +174,7 @@ func (c *Cache) Set(key string, value interface{}, expire int64) {
}
// 批量设置
func (c *Cache) BatchSet(data map[string]interface{}, expire int64) {
func (c *Cache) BatchSet(data map[string]interface{}, expire int) {
var e int64
if expire != 0 {
e = gtime.Millisecond() + int64(expire)
@ -190,7 +190,7 @@ func (c *Cache) BatchSet(data map[string]interface{}, expire int64) {
}
// 基于内存缓存的锁锁成功返回true失败返回false当失败时表示有其他的锁存在
func (c *Cache) Lock(key string, expire int64) bool {
func (c *Cache) Lock(key string, expire int) bool {
if v := c.Get(key); v != nil {
return false
}

View File

@ -51,6 +51,15 @@ func SetInterval(t time.Duration, callback func() bool) {
}()
}
// 设置当前进程全局的默认时区
func SetTimeZone(zone string) error {
location, err := time.LoadLocation(zone)
if err == nil {
time.Local = location
}
return err
}
// 获取当前的纳秒数
func Nanosecond() int64 {
return time.Now().UnixNano()