go语言 mysql redis_Go语言入门(十) Mysql与Redis操作

Mysql与Redis操作

Mysql开发

安装mysql,创建test库

创建表

mysql> CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT '', `age` int(11) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

mysql> insert into user (name,age)values('jim',18)

SQL查询

单行查询: Db.QueryRole

多行查询: Db.Query

import (

"fmt"

_"github.com/go-sql-driver/mysql"

"database/sql"

)

type User struct {

Id int64 `db:"id"`

Name string `db:"name"`

Age int `db:"age"`

}

func connMysql() {

dns := "root:123456@tcp(localhost:3306)/test"

conn,err := sql.Open("mysql",dns)

if err != nil {

fmt.Printf("connect mysql err:%v\n",err)

return

}

err = conn.Ping()

if err != nil {

fmt.Printf("ping faild,err :%v\n",err)

}

fmt.Printf("connect mysql successfully!\n")

QueryRow(conn)

Query(conn)

defer conn.Close()

}

func QueryRow(Db *sql.DB) {

id := 1

//单行数据查询

row := Db.QueryRow("select id,name,age from user where id=?",id)

var user User

err := row.Scan(&user.Id,&user.Name,&user.Age)

if err == sql.ErrNoRows {

fmt.Printf("not found data by id:%v\n",id)

}

if err != nil {

fmt.Printf("scan faild,err: %v\n",err)

return

}

fmt.Printf("user:%#v\n",user)

}

func Query(Db *sql.DB) {

id := 0

//多行数据查询

rows,err := Db.Query("select id,name,age from user where id>?",id)

//一定要关闭结果集

defer func() {

if rows != nil {

rows.Close()

}

}()

//查询异常捕获

if err == sql.ErrNoRows {

fmt.Printf("not found data by id:%v\n",id)

}

if err != nil {

fmt.Printf("scan faild,err: %v\n",err)

return

}

//遍历所有数据

for rows.Next() {

var user User

err := rows.Scan(&user.Id,&user.Name,&user.Age)

if err == sql.ErrNoRows {

fmt.Printf("not found data by id:%v\n",id)

}

if err != nil {

fmt.Printf("scan faild,err: %v\n",err)

return

}

fmt.Printf("user:%#v\n",user)

}

}

func main() {

connMysql()

}

Mysql插入更新和删除

使用DB.Exec()

import (

"fmt"

_"github.com/go-sql-driver/mysql"

"database/sql"

)

type User struct {

Id int64 `db:"id"`

Name string `db:"name"`

Age int `db:"age"`

}

func Insert(DB *sql.DB) {

username := "alex"

age := 18

result,err := DB.Exec("insert into user(name,age) values(?,?)",username,age)

if err != nil {

fmt.Printf("sql exec insert faild:err:%v\n",err)

return

}

id,err := result.LastInsertId()

if err != nil {

fmt.Printf("last insert id faild,err:%v\n",err)

return

}

affectRows,err := result.RowsAffected()

if err != nil {

fmt.Printf("Rows affects faild,err:%v\n",err)

return

}

fmt.Printf("last insert id:%d, affect rows:%d\n",id,affectRows)

}

func Update(DB *sql.DB) {

username := "bbq"

age := 12

result,err := DB.Exec("update user set name=?,age=? where id=?",username,age,3)

if err != nil {

fmt.Printf("sql exec update faild:err:%v\n",err)

return

}

affectRows,err := result.RowsAffected()

if err != nil {

fmt.Printf("Rows affects faild,err:%v\n",err)

return

}

fmt.Printf("affect rows:%d\n",affectRows)

}

func Delete(DB *sql.DB) {

id := 5

result,err := DB.Exec("delete from user where id=?",id)

if err != nil {

fmt.Printf("sql exec delete faild:err:%v\n",err)

return

}

affectRows,err := result.RowsAffected()

if err != nil {

fmt.Printf("Rows affects faild,err:%v\n",err)

return

}

fmt.Printf("affect rows:%d\n",affectRows)

}

func connMysql() {

dns := "root:123456@tcp(localhost:3306)/test"

conn,err := sql.Open("mysql",dns)

if err != nil {

fmt.Printf("connect mysql err:%v\n",err)

return

}

err = conn.Ping()

if err != nil {

fmt.Printf("ping faild,err :%v\n",err)

}

fmt.Printf("connect mysql successfully!\n")

//QueryRow(conn)

//Query(conn)

//Insert(conn)

//Update(conn)

Delete(conn)

defer conn.Close()

}

mysql预处理

一般sql处理流程

客户端拼接好sql语句

客户端发送sql语句到mysql服务器

mysql服务器解析sql语句并执行,把输出结果返回给客户端

预处理流程

把sql拆分成两部分,命令部分和数据部分

首先把命令部分发送给mysql服务器,mysql进行sql预处理

然后把数据部分发送给mysql服务器,mysql进行占位符替换

mysql执行sql语句并返回结果给客户端

预处理的优势

同一条sql反复执行,性能会很高

避免sql注入问题

预处理实例

查询操作

Db.Prepare(sql string)(*sql.Stmt,error)

Stmt.Query()

func PrepareQuery(DB *sql.DB) {

//第一部分:发送命令和占位符

stmt,err := DB.Prepare("select id,name,age from user where id>?")

if err != nil {

fmt.Printf("prepare faild,error:%v\n",err)

return

}

//第二部分:发数据,并执行sql

id := 1

rows,err := stmt.Query(id)

//一定要关闭结果集

defer func() {

if rows != nil {

rows.Close()

}

if stmt != nil {

stmt.Close()

}

}()

//查询异常捕获

if err == sql.ErrNoRows {

fmt.Printf("not found data by id:%v\n",id)

}

if err != nil {

fmt.Printf("scan faild,err: %v\n",err)

return

}

//遍历所有数据

for rows.Next() {

var user User

err := rows.Scan(&user.Id,&user.Name,&user.Age)

if err == sql.ErrNoRows {

fmt.Printf("not found data by id:%v\n",id)

}

if err != nil {

fmt.Printf("scan faild,err: %v\n",err)

return

}

fmt.Printf("user:%#v\n",user)

}

}

更新操作(插入,更新,delete)

Db.Prepare(sql string)(*sql.Stmt,error)

Stmt.Exec()

func PrepareInsert(DB *sql.DB) {

//第一部分:发送命令和占位符

stmt,err := DB.Prepare("insert into user (name,age) values (?,?);")

if err != nil {

fmt.Printf("prepare faild,error:%v\n",err)

return

}

//第二部分:发数据,并执行sql

username := "zhangqiqi"

age := 29

result,err := stmt.Exec(username,age)

if err != nil {

fmt.Printf("sql exec insert faild:err:%v\n",err)

return

}

id,err := result.LastInsertId()

if err != nil {

fmt.Printf("last insert id faild,err:%v\n",err)

return

}

affectRows,err := result.RowsAffected()

if err != nil {

fmt.Printf("Rows affects faild,err:%v\n",err)

return

}

fmt.Printf("last insert id:%d, affect rows:%d\n",id,affectRows)

}

mysql事务实例

保证数据的一致性

mysql的事务操作

DB.Begin() 开启事务

DB.Commit() 提交事务

DB.Roback() 回滚事务

func Transaction(DB *sql.DB) {

tx,err := DB.Begin()

if err != nil {

fmt.Printf("begin faild,err:%v\n",err)

return

}

_,err = tx.Exec("insert into user (name,age)values (?,?)","jemmy",80)

if err != nil {

tx.Rollback()

return

}

_,err = tx.Exec("update user set name=?,age=? where id=6","jemmxiny",60)

if err != nil {

tx.Rollback()

return

}

err = tx.Commit()

if err != nil {

tx.Rollback() //数据异常就回滚

return

}

}

sqlx库的介绍和使用

sqlx的特点:

使用更简单

支持对数据库,mysql,postgresql,oracle,sqlit

sqlx的使用

查询:sqlx.DB.Get和sqlx.DB.Select

更新,插入和删除: sqlx.DB.Exex()

事务:sqlx.DB.Begin(),sqlx.DB.Commit(),sqlx.DB.Rollback

go get github.com/jmoiron/sqlx

使用实例

import (

"database/sql"

"fmt"

"github.com/jmoiron/sqlx"

_ "github.com/go-sql-driver/mysql"

)

type User struct {

Id int64 `db:"id"`

Name string `db:"name"`

Age int `db:"age"`

}

func connMysql() {

dns := "root:123456@tcp(localhost:3306)/test"

conn,err := sqlx.Connect("mysql",dns)

if err != nil {

fmt.Printf("connect mysql err:%v\n",err)

return

}

//超时测试

err = conn.Ping()

if err != nil {

fmt.Printf("ping faild,err :%v\n",err)

}

fmt.Printf("connect mysql successfully!\n")

//关闭连接

//QueryRow(conn)

//Query(conn)

Insert(conn)

defer conn.Close()

}

func QueryRow(Db *sqlx.DB) {

id := 100

//单行数据查询

var user User

err := Db.Get(&user,"select id,name,age from user where id=?",id)

//空行数据

if err == sql.ErrNoRows {

fmt.Printf("no record to found\n")

return

}

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

return

}

fmt.Printf("user:%#v\n",user)

}

func Query(Db *sqlx.DB) {

var user []*User

id := 1

//多行数据查询

err := Db.Select(&user,"select id, name, age from user where id>?",id)

if err == sql.ErrNoRows {

fmt.Printf("no record found\n")

return

}

if err != nil {

fmt.Printf("select rows faild,err:%v\n",err)

return

}

//输出查询结果

fmt.Printf("user:%#v\n",user)

for _,v := range user {

fmt.Printf("%v\n",v)

}

}

func Insert(Db *sqlx.DB) {

username := "alex"

age := 18

result,err := Db.Exec("insert into user(name,age) values(?,?)",username,age)

if err != nil {

fmt.Printf("sql exec insert faild:err:%v\n",err)

return

}

id,err := result.LastInsertId()

if err != nil {

fmt.Printf("last insert id faild,err:%v\n",err)

return

}

affectRows,err := result.RowsAffected()

if err != nil {

fmt.Printf("Rows affects faild,err:%v\n",err)

return

}

fmt.Printf("last insert id:%d, affect rows:%d\n",id,affectRows)

}

func main() {

connMysql()

}

Redis开发

使用第三方库:github.com/garyburd/redigo/redis

redis的使用

func initRedis() (conn redis.Conn,err error) {

conn,err = redis.Dial("tcp","127.0.0.1:6379")

if err != nil {

fmt.Printf("conn redis error:%v\n",err)

return

}

fmt.Printf("conn redis succ\n")

return

}

func testSetGet(conn redis.Conn) {

key := "abc"

_,err := conn.Do("set",key,"this is a test!")

if err != nil {

fmt.Printf("set value faild,eror:%v\n",err)

return

}

data,err := redis.String(conn.Do("get",key))

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

return

}

fmt.Printf("key:%s, value:%v\n",key,data)

}

func main() {

conn,err := initRedis()

if err != nil {

return

}

testSetGet(conn)

}

Hash表操作

func testSetGet(conn redis.Conn) {

key := "abc"

_,err := conn.Do("hset","books",key,"this is a test!")

if err != nil {

fmt.Printf("set value faild,eror:%v\n",err)

return

}

data,err := redis.String(conn.Do("hget","books",key))

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

return

}

fmt.Printf("key:%s, value:%v\n",key,data)

}

Redis并发操作

func testMSetGet(conn redis.Conn) {

key := "abc"

key1 := "def"

_,err := conn.Do("mset",key,key1)

if err != nil {

fmt.Printf("set value faild,eror:%v\n",err)

return

}

//多值操作返回的数据用strings接收

data,err := redis.Strings(conn.Do("mget",key,key1))

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

return

}

//循环取值

for _,val := range data {

fmt.Printf("key:%s, value:%v\n",key,val)

}

}

设置队列

发布订阅

func testQuenu(conn redis.Conn) {

_,err := conn.Do("lpush","book_list","this is a test!","daadada")

if err != nil {

fmt.Printf("lpush value faild,eror:%v\n",err)

return

}

data,err := redis.String(conn.Do("rpop","book_list"))

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

return

}

fmt.Printf("value:%s\n",data)

}

连接池

func newPool(serverAddr string,passwd string) (pool *redis.Pool) {

return &redis.Pool{

MaxIdle: 16,

MaxActive: 1024,

IdleTimeout: 240,

Dial: func() (redis.Conn,error) {

conn,err := redis.Dial("tcp",serverAddr)

if err != nil {

return nil,err

}

if len(passwd) > 0 {

_,err := conn.Do("auth",passwd)

if err != nil {

return nil,err

}

}

return conn,err

},

TestOnBorrow: func(c redis.Conn,t time.Time) error {

if time.Since(t) < time.Minute {

return nil

}

_,err := c.Do("ping")

return err

},

}

}

func testRedisPool() {

pool := newPool("127.0.0.1:6379","")

conn := pool.Get()

conn.Do("set","abcd","23134534665437372132")

val,err := redis.String(conn.Do("get","abcd"))

if err != nil {

fmt.Printf("get faild,err:%v\n",err)

}

fmt.Printf("val:%v,err:%v\n",val,err)

//把连接归还到连接池

conn.Close()

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值