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:[email protected](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:[email protected](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:[email protected](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()
}

原文地址:https://blog.51cto.com/13812615/2486436

时间: 2024-10-27 06:16:31

Go语言入门(十) Mysql与Redis操作的相关文章

C语言第十二讲,文件操作.

C语言第十二讲,文件操作. 一丶文件操作概述 在操作系统中,我们的文档都称为文件.操作系统也为我们提供了接口进行操作.不同语言都是使用的相同的接口,只不过封装的上层接口不一样 操作文件的步骤 打开文件->读写文件->关闭文件. 二丶文件流的概述. 文件流称为 输入流和输出流.  其实就是从内存写数据到磁盘.和从磁盘读数据到内存. 内存->磁盘  称为输出流. 输出到磁盘 磁盘->内存 称为输入流.读取到内存. 三丶文件的打开和关闭. 1.操作原型. FILE *fopen(char

python笔记7:mysql、redis操作

模块安装: 数据操作用到的模块pymysql,需要通过pip install pymysql进行安装. redis操作用的模块是redis,需要通过pip install redis进行安装. 检验是否安装成功:进入到Python命令行模式,输入import pymysql. import redis ,无报错代表成功: mysql操作方法如下: 查询数据:fetchone.fetchmany(n).fetchall() import pymysql #建立mysql连接,ip.端口.用户名.密

Go语言入门(九) 文件操作

文件操作 文件的基本操作 读文件 func readFile(){ filename := "./aaa.log" file, err := os.Open(filename) if err != nil { fmt.Printf("open %s is error,error %v\n",filename,err) return } //关闭文件句柄 defer func() { file.Close() }() //读取文件 var buf[4096]byte

C语言入门(二十五)文件操作

文件操作  一.标准文件的读写 1.文件的打开fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程序就可用此FILE指针来实现对指定文件的存取操作了.当使用打开函数时,必须给出文件名.文件操作方式(读.写或读写),如果该文件名不存在,就意味着建立(只对写文件而言,对读文件则出错),并将文件指针指向文件开头.若已有一个同名文件存在,则删除该文件,若无同名文件,则建立该文件,并将文件指针指向文件开头. fopen(char *f

Python之路【第十篇】Python操作Memcache、Redis、RabbitMQ、SQLAlchemy、

Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. 1.Memcached安装配置 #安装倚赖包 yum install libevent-devel #安装软件 yum -y

边记边学PHP-(十四)MySql数据库基础操作1

提到数据库,相信都不陌生.比较常见的是SQL Server . Oracle.Access.SQLite等等.当然还有PHP的黄金搭档,MySql数据库.当然我所写的都是MySql的一些基础,我还没有深入的学习这个数据库.深入学习还需要一段时间.但是现在学的基础基本满足我现在的学习需要. 一.MySQL简介 1.MySQL是什么 MySQL是一款安全.跨平台.高效的,并与PHP.Java等主流编程语言紧密结合的数据库系统.该数据库系统是由瑞典的MySQL AB公司开发.发布并支持,由MySQL初

C语言对mysql数据库的操作

原文:C语言对mysql数据库的操作 这已经是一相当老的话题.不过今天我才首次使用,把今天的一些体会写下来,也许能给一些新手带来一定的帮助,更重要的是供自己今后忘记的怎么使用而进行查阅的! 我们言归正传 1.头文件: #include <stdio.h> #include <stdlib.h> #include <mysql/mysql.h> //这个是必需要包含的,下面对mysql的所有操作函数,都出自这里 2.定义一个MYSQL变量: MYSQL mysql: 这里

python学习道路(day12note)(mysql操作,python链接mysql,redis)

1,针对mysql操作 1 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass'); 设置密码 2 update user set password=passworD("test") where user='root';修改密码 3 flush privileges; 4 grant all on *.* to [email protected]'%' identified by 'your_password'; 5 mysq

06 python操作MySQL和redis(进阶)

python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务! 事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行. 事务用来管理 insert.update.delete 语句 事务必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性).一致性