go语言简介
首先go语言作为一门新语言,2007年开始研发,2009年11月开源,2012年初发布Go1稳定版本,截止目前还是在1.0时代,那么,这么一个“新生代语言”相比于活跃在各大公司之前的前辈,如:C,Java,python等具有哪些优势呢?
go语言的最大的优势在于高并发,go程,协程,一台pc机,即可完成百万级别的并发
go语言有自动垃圾回收机制,而且是一门底层语言
redis简介
redis是一种高速高性能的内存数据库,存储的是键值对数据
由于极高的存储和访问速度,redis常被用来作为数据缓存服务器
另外redis是支持数据持久化的(即redis会自动将数据写入磁盘)——这是redis大杀四方的重要原因
redis支持多个slave端同时向master端进行写入,这经常被用在分布式爬虫等场景中
2010年以后redis开始大面积流行,关系型数据库(核心数据)+redis(缓存)是常规的、常见的数据解决方案
mysql简介
Mysql是最流行的关系型数据库管理系统;
所谓的关系型数据库,是指建立在关系模型基础上的数据库,即数据表之间不是相互独立的,而是彼此关联的;
数据表中的每行代表一条数据,每列代表一个属性(也叫字段);
最著名的三大关系型数据库包括:Oracle(甲骨文),SQLServer(微软),MySQL(甲骨文);
MySQL是开源、免费的,且功能强大(64位机最大支持8T存储);
支持C/C++、Python、Java、PHP、Ruby、Perl等多种语言;
正文
下面就直奔主题
众所周知,在工作中,redis和mysql都是常用的数据库,redis常用来缓存,mysql作为关系型数据库常用来存储核心数据,那么如何实现交互呢
package main
import (
"fmt"
//此处注意“_”表示引用mysql函数中init的方法而无需使用函数
_ "github.com/go-sql-driver/mysql"
"github.com/garyburd/redigo/redis"
"github.com/jmoiron/sqlx"
)
type Person struct {
//对应id表字段
Id int `db:"id"`
//对应name表字段
Name string `db:"name"`
//对应age表字段
Age int `db:"age"`
//对应rmb表字段
Rmb float64 `db:"rmb"`
}
func main() {
var cmd string
for {
fmt.Println("请输入命令:")
fmt.Scan(&cmd)
//fmt.Println("你输入的是:",cmd)
switch cmd {
case "getall":
GetAll()
default:
fmt.Println("不能识别的命令")
}
fmt.Println()
}
}
func GetAll() {
//先看看redis里有没有数据
conn, _ := redis.Dial("tcp", "localhost:6379")
defer conn.Close()
reply, err := conn.Do("lrange", "mlist", 0, -1)
pkeys, _ := redis.Strings(reply, err)
fmt.Println(pkeys)
if len(pkeys) > 0 {
//如果有
fmt.Println("从redis获得数据")
// 从redis里直接读取
for _, key := range pkeys {
retStrs, _ := redis.Strings(conn.Do("hgetall", key))
//fmt.Println(retStrs)
fmt.Printf("{%s %s %s}\n", retStrs[1], retStrs[3], retStrs[5])
}
} else {
//如果没有
fmt.Println("从mysql获得数据")
//查询数据库
db, _ := sqlx.Open("mysql", "root:123456@tcp(localhost:3306)/mydb")
defer db.Close()
var persons []Person
db.Select(&persons, "select id,name,age,rmb from person")
fmt.Println(persons)
//写入redis并且设置过期时间
for _, p := range persons {
//将p以hash形式写入redis
_, e1 := conn.Do("hmset", p.Id, "name", p.Name, "age", p.Age, "rmb", p.Rmb)
//将这个hash的key加入mlist
_, e2 := conn.Do("rpush", "mlist", p.Id)
//设置过期时间
_, e3 := conn.Do("expire", p.Id, 60)
_, e4 := conn.Do("expire", "mlist", 60)
if e1 != nil || e2 != nil || e3 != nil || e4 != nil {
fmt.Println(p.Name, "写入失败", e1, e2, e3, e4)
} else {
fmt.Println(p.Name, "写入成功")
}
}
}
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
这样一个简单的二级缓存就完成了,打印结果为,在终端输入getall命令后查redis里有无数据,有则遍历打印,无则查询mysql中,打印之,并把数据写入redis作为缓存,时间我设置为60s,具体需要可以修改。