Cache模块

go-doudou集成了https://github.com/go-redis/cache在新窗口打开库,实现了开箱即用的对sql查询结果的本地内存缓存和redis缓存。

wrapper.DBwrapper.Tx接口的方法签名中只有GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) errorSelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error集成了缓存机制。

具体用法请参考示例代码和里面的注释。

func main() {

    ...

    // 创建redis连接实例
	ring := redis.NewRing(&redis.RingOptions{
		Addrs: map[string]string{
			"server1": ":6379",
		},
	})

    // 创建cache实例
	mycache := cache.New(&cache.Options{
        // redis缓存
		Redis: ring,
        // 本地内存缓存,如果不需要可以删去此行
        // 支持多种内存缓存库,请参考go-redis/cache库的README.md里的说明
		LocalCache:   cache.NewTinyLFU(1000, time.Minute),
        // 开启redis缓存的命中统计
		StatsEnabled: true,
	})

	u := dao.NewUserDao(wrapper.NewGddDB(db, 
        // wrapper.NewGddDB工厂方法里没有设置默认的cache实例,
        // 所以需要用户自己调用wrapper.WithCache方法传入自定义的实例
        wrapper.WithCache(mycache), 
        // 调用wrapper.WithRedisKeyTTL方法可以传入redis里的key的过期时间,
        // 可以不传,默认值是一个小时
        wrapper.WithRedisKeyTTL(10*time.Second)))

	...

    // 直接调用dao层代码即可
	_, err = u.Insert(context.TODO(), &user)
	if err != nil {
		panic(err)
	}
	logrus.Printf("user %s's id is %d\n", user.Name, user.Id)

    // 直接调用dao层代码即可
	got, err := u.PageMany(context.TODO(), Page{
		Orders: []Order{
			{
				Col:  "age",
				Sort: "desc",
			},
		},
		Offset: 0,
		Size:   1,
	}, C().Col("age").Gt(27))
	if err != nil {
		panic(err)
	}
    
    ...

    // 重复调用,可以从日志中看到效果
	got, err = u.PageMany(context.TODO(), Page{
		Orders: []Order{
			{
				Col:  "age",
				Sort: "desc",
			},
		},
		Offset: 0,
		Size:   1,
	}, C().Col("age").Gt(27))
	if err != nil {
		panic(err)
	}
	 
    ...

	fmt.Println(mycache.Stats())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

日志输出示例,请注意HIT: 后面的值,false表示未命中缓存,true表示缓存命中。&{Hits:2 Misses:2}表示2次查询命中缓存,2次没命中。

INFO[2022-05-23 20:54:24] SQL: INSERT INTO `test`.`ddl_user` ( `id`, `name`, `phone`, `age`, `no`, `school`, `is_student`, `delete_at`, `avg_score`, `hobby`) VALUES ( '0', 'jack', '13552053960', '30', '0', null, '0', null, '97.53
4', '')
INFO[2022-05-23 20:54:24] user jack's id is 14                                                                     
INFO[2022-05-23 20:54:24] SQL: select * from ddl_user where `age` > '27' order by `age` desc limit 0,1  HIT: false 
INFO[2022-05-23 20:54:24] SQL: select count(1) from ddl_user where `age` > '27' HIT: false                         
INFO[2022-05-23 20:54:24] returned user jack's id is 14                                                            
INFO[2022-05-23 20:54:24] returned user jack's average score is 97.534                                             
INFO[2022-05-23 20:54:24] SQL: select * from ddl_user where `age` > '27' order by `age` desc limit 0,1  HIT: true  
INFO[2022-05-23 20:54:24] SQL: select count(1) from ddl_user where `age` > '27' HIT: true                          
INFO[2022-05-23 20:54:24] returned user jack's id is 14                                                            
INFO[2022-05-23 20:54:24] returned user jack's average score is 97.534                                             
&{Hits:2 Misses:2}                                                                                                             
INFO[2022-05-23 20:54:24] SQL: delete from ddl_user where `age` > '27';       
1
2
3
4
5
6
7
8
9
10
11
12
13