前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言入门(十) Mysql与Redis操作

Go语言入门(十) Mysql与Redis操作

作者头像
alexhuiwang
发布2020-09-24 16:47:51
9740
发布2020-09-24 16:47:51
举报
文章被收录于专栏:运维博客

Mysql与Redis操作

Mysql开发

  • 安装mysql,创建test库
  • 创建表
代码语言:javascript
复制
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
代码语言:javascript
复制
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()
代码语言:javascript
复制
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()
代码语言:javascript
复制
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()
代码语言:javascript
复制
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() 回滚事务
代码语言:javascript
复制
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
代码语言:javascript
复制
go get github.com/jmoiron/sqlx

使用实例

代码语言:javascript
复制
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的使用

代码语言:javascript
复制
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表操作

代码语言:javascript
复制
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并发操作

代码语言:javascript
复制
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)
   }
}

设置队列

发布订阅

代码语言:javascript
复制
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)
}

连接池

代码语言:javascript
复制
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()
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Mysql与Redis操作
    • Mysql开发
      • SQL查询
      • Mysql插入更新和删除
      • mysql预处理
      • mysql事务实例
      • sqlx库的介绍和使用
      • 使用实例
    • Redis开发
      • redis的使用
      • Hash表操作
      • Redis并发操作
      • 设置队列
      • 连接池
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档