Go语言操作MySQL语言基础知识

网友投稿 625 2023-05-24

Go语言操作MySQL语言基础知识

Go语言操作MySQL语言基础知识

前言

通常情况下,我们程序员和数据库打交道是最多的。要然我们怎么会被称为码农呢。

存用户信息需要数据库,存订单需要数据库,等等等等,现在真是数据驱动着发展。

但是数据库种类有很多,有Mysql,***,***。

本篇就示例如何Go操作Mysql。

准备工作

本次使用的是go mod进行包依赖管理,还不会使用的向上爬梯子,找go mod用法。

使用的库是第三方库go-sql-driver/mysql。

准备工作之连接数据库

代码

func main() {     var username = "root"     var password = "rootroot"     var ip = "127.0.0.1"     var port = "3306"     var data = "go_mysql_demo"     var dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", username, password, ip, port, data)     //Open只会验证dsb的格式是否正确,不会验证是否连接成功,同理,密码是否正确也不知道     db, err := sql.Open("mysql", dsn)     if err != nil {         panic(err) }     //关闭连接在 err 之后,因为可能直接就打开不成功,关闭一个没有打开的连接???     defer db.Close()     // 此时尝试连接数据库,会判断用户,密码,ip地址,端口是否正确     err = db.Ping()     if err != nil {         fmt.Println("连接数据库失败,",err)         return }     //设置与数据库建立连接的最大数目,一般不管     db.SetMaxOpenConns(100)     //设置连接池中的最大闲置连接数,一般不管     db.SetMaxIdleConns(50) }

注意

sql.Open只会验证格式是否正确,不会连接数据库。db.Close在err之后,是因为可能打开不成功,关闭一个没有打开的连接。db.Ping会连接数据库,判断用户,密码,ip地址,端口是否正确。

准备工作之创建表

我们创建一个简单的用户表。

CREATE TABLE `userinfo` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `name` varchar(10) DEFAULT NULL,   `phone` char(11) DEFAULT NULL,   `address` varchar(64) DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

准备工作之创建结构体

假设上述工作都完成了啊。

不知道有没有想过,我们查询的数据,存成啥?,字符串?map?切片?,似乎都不是太好。

只有结构体是最清晰的,最好认识的。

结构体

type Userinfo struct {     Id      int64  `json:"id"`     Name    string `json:"name"`     Phone   string `json:"phone"`     Address string `json:"address"` }

查询单条

单条查询使用QueryRow方法。

代码

//查询单条 sqlStr := "SELECT id,`name`,phone,address from userinfo where id = ?;" var user Userinfo /*     QueryRow 第二个参数可以接收多个参数,同理,sqlStr可以有多个 ?占位符 进行匹配     QueryRow 之后必须调用Scan方法进行数据绑定,进行数据库链接释放 */ err = db.QueryRow(sqlStr, 1).Scan(&user.Id, &user.Name, &user.Phone, &user.Address) if err != nil {     fmt.Println("查询失败", err)     return } fmt.Println(user)

执行结果

查询多条

多行查询使用Query。

代码

//查询多条 sqlStr := "SELECT id,`name`,phone,address from userinfo where id >= ?" //参数同 QueryRow rows, err := db.Query(sqlStr, 1) if err != nil {     fmt.Println("查询失败:", err)     return } // 此处使用rows释放所有链接 defer rows.Close() //循环整理所有数据 var userList = make([]Userinfo, 0, 10) for rows.Next() { var user Userinfo err = rows.Scan(&user.Id, &user.Name, &user.Phone, &user.Address) if err != nil {     fmt.Println("绑定数据失败", err)     return } userList = append(userList, user) } fmt.Println(userList)

执行结果

插入数据

插入数据需要用到Exec。

代码

//插入数据 sqlStr := "INSERT into userinfo(name,phone,address) values(?,?,?);" result, err := db.Exec(sqlStr, "吴彦祖", 555, "不知道哪的") if err != nil {     fmt.Println("插入失败", err)     return } //受影响的行数 row_affect, err := result.RowsAffected() if err != nil {     fmt.Println("受影响行数获取失败:", err)     return } fmt.Println("受影响的行数:", row_affect) lastId, err := result.LastInsertId() if err != nil {     fmt.Println("新增行id获取失败:", err)     return } fmt.Println("新增行id:", lastId) fmt.Println("插入成功")

执行结果

Mysql

更新数据

更新和添加差不多,用的都是Exec。

代码

//更新数据 sqlStr := `UPDATE userinfo set name=? where id=?;` result, err := db.Exec(sqlStr, "吴彦祖666", 3) if err != nil {     fmt.Println("更新失败", err)     return } //受影响的行数 row_affect, err := result.RowsAffected() if err != nil {     fmt.Println("受影响行数获取失败:", err)     return } fmt.Println("受影响的行数:", row_affect) fmt.Println("更新成功")

执行结果

Mysql

删除数据

删除数据用的还是Exec。

代码

//删除数据 sqlStr := "delete from userinfo where id = ?;" result, err := db.Exec(sqlStr, 3) if err != nil {     fmt.Println("删除失败", err)     return } //受影响的行数 row_affect, err := result.RowsAffected() if err != nil {     fmt.Println("受影响行数获取失败:", err)     return } fmt.Println("受影响的行数:", row_affect) fmt.Println("删除成功")

执行结果

Mysql

事物

事物,这个用的就比较多了,通常用在关键的场景。

尤其是转账,张三-10块,李四+10块,这个动作动作是要在一起完成的。

如果任何一个失败了,就要恢复上一次的状态。

我们通常也叫这个操作叫做原子操作,要成功,都成功,要完蛋,都完蛋。

新建表

CREATE TABLE `bill` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `name` varchar(8) NOT NULL,   `money` int(11) NOT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

表数据

张三和李四都剩余100块

Go Mysql 关于事物相关方法

Go 关于事物有三个方法

Begin()开始事物。Commit()提交事物。Rollback()失败回滚。

模拟转账:张三-10块,李四+十块

代码

func main() {     //事物     //开启事物     tx, err := db.Begin()     if err != nil {         //释放事物         if tx != nil {             tx.Rollback()         }         fmt.Println("事物开启失败")         return }      张三减10块Sql := `UPDATE bill set money=money - 10 where name = ?;`     result, err := tx.Exec(张三减10块Sql, "张三")     if err != nil {         //有错误表示更是失败,回滚原来状态         tx.Rollback()         fmt.Println(err)         return }     张三受影响行数, err := result.RowsAffected()     if err != nil {         tx.Rollback() // 回滚         return }      李四加10块Sql := `UPDATE bill set money=money + 10 where name = ?;`     result, err = tx.Exec(李四加10块Sql, "李四")     if err != nil {         //有错误表示更是失败,回滚原来状态         tx.Rollback()         fmt.Println(err)         return }     李四受影响行数, err := result.RowsAffected()     if err != nil {         tx.Rollback() // 回滚         return }     //都等于1表示成功,可以提交事务,修改数据     if 张三受影响行数==1 && 李四受影响行数==1{         //提交事务         fmt.Println("提交事务")         tx.Commit()     }else{         //有一个!=1表示没有更新成功,可能用户不存在         fmt.Println("失败了,事物回滚了")         tx.Rollback() }     fmt.Println("事物执行成功") }

执行结果

Mysql

一加一减

假如出错了

Mysql

如果使用事物,出错了数据还是没变。

总结

本次主要讲述了Go如何操作Mysql,如何进行增删改查,最后还讲了以下什么是事物,如何操作事物。

当然,这种是最原始的方法,过程有些繁琐,了解入门就好,后面还有更方便的方法。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:深入了解MySQL主从复制的原理
下一篇:一个真实的案例,一些真实存在的数据库选型误区
相关文章