mirror of
https://gitee.com/johng/gf
synced 2026-07-05 13:22:16 +08:00
ORM查询缓存特性开发中
This commit is contained in:
1
TODO
1
TODO
@ -15,6 +15,7 @@ gpage分页增加对自定义后缀的支持,如:2.html, 2.php等等;
|
||||
gvalid包增加tag与校验规则绑定的支持特性;
|
||||
ghttp获取参数支持直接转struct功能;
|
||||
map转struct增加对tag的支持;
|
||||
gdb增加查询缓存特性;
|
||||
|
||||
|
||||
DONE:
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user