go操作MySQL

go操作MySQL

依赖

go get github.com/go-sql-driver/mysql

实例

CREATE DATABASE IF NOT EXISTS `go_db` charset=utf8mb4;
package daily

import (
	"context"
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"  // 数据库驱动
)

var (
	DB          *sql.DB
)

func InitMysqlDB() error {
	var err error
	dsn := "root:python@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := sql.Open("mysql", dsn)
	//defer db.Close()
	if err != nil {
		//panic(errors.New(
		//	"initError:" + err.Error()))
		return err
	}
	if err = db.Ping(); err != nil {
		//panic(errors.New(
		//	"pingError:" + err.Error()))
		return err
	}  // 校验数据库连接可用性
	/**
	SetConnMaxLifetime: 设置一个连接的最长生命周期,因为数据库本身对连接有一个超时时间的设置,如果超时时间到了数据库会单方面断掉连接,此时再用连接池内的连接进行访问就会出错, 因此这个值往往要小于数据库本身的连接超时时间
	SetMaxIdleConns: 连接池里面允许Idel的最大连接数, 这些Idel的连接 就是并发时可以同时获取的连接,也是用完后放回池里面的互用的连接, 从而提升性能。
	SetMaxOpenConns: 设置最大打开的连接数,默认值为0表示不限制。控制应用于数据库建立连接的数量,避免过多连接压垮数据库。
	*/
	db.SetConnMaxLifetime(time.Minute) // 最大连接时间
	db.SetMaxOpenConns(10)             // 最大连接数
	db.SetMaxIdleConns(10)             // 最大空闲连接数
	DB = db
	return err
}

func MysqlOp() {
	/**
	mysql操作
	go-sql 默认使用原生sql操作
	1. 下载依赖:go get github.com/go-sql-driver/mysql
	2. open函数验证其参数是否正确 需要通过ping校验通过连接是否正确 且建议只调用一次open 多个goroutine并发使用db
	3. db连接
		db.Ping() 调用完毕后会马上把连接返回给连接池
		db.Exec() 调用完毕后会马上把连接返回给连接池 但是它返回的Result对象还保留这连接的引用 当后面的代码需要处理结果集的时候连接将会被重用
		db.Query() 调用完毕后会将连接传递给sql.Rows类型 当然后者迭代完毕或者显示的调用.Close()方法后 连接将会被释放回到连接池
		db.QueryRow()调用完毕后会将连接传递给sql.Row类型 当.Scan()方法调用之后把连接释放回到连接池
		db.Begin() 调用完毕后将连接传递给sql.Tx类型对象 当.Commit()或.Rollback()方法调用后释放连接
	*/
	err := InitMysqlDB()
	if err != nil || DB == nil {
		fmt.Println("数据库初始化失败=" + err.Error())
		return
	} else {
		fmt.Println("数据库初始化成功")
	}
	// 1. 新建数据表
	table_delete := `DROP TABLE IF EXISTS user`
	if _, err := DB.Exec(table_delete); err != nil {
		fmt.Println("删除表失败="+ err.Error())
		return
	} else {
		fmt.Println("删除表成功")
	}
	table_create := `CREATE TABLE IF NOT EXISTS user (
	 id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户编号',
	 name VARCHAR(8) NOT NULL COMMENT '用户名称',
	 age TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户年龄',
	 PRIMARY KEY (id))
	 ENGINE = InnoDB
	 DEFAULT CHARACTER SET = utf8
	 COLLATE = utf8_general_ci
	 COMMENT = '用户表'`
	if _, err := DB.Exec(table_create); err != nil {
		fmt.Println("创建表失败=", err.Error())
		return
	} else {
		fmt.Println("创建表成功")
	}

	// 2.1 新增
	stmt, err := DB.Prepare(`insert into user(name, age)values(?,?)`)
	defer stmt.Close()
	if err != nil {
		fmt.Println("新增Pre失败=", err.Error())
		return
	} else {
		if r, err := stmt.Exec("陈一", 10); err != nil {
			fmt.Println("1-新增Exc失败=", err.Error())
		} else {
			if id, err := r.LastInsertId(); err != nil {
				fmt.Println("1-新增失败LastInsertId1=", err.Error())
			} else {
				fmt.Println("1-新增成功id=", id)
			}
		}
	}

	// 2.2 新增
	r, err := DB.Exec(`insert into user(name, age)values(?,?)`, "王二", 12)
	if err != nil {
		fmt.Println("2-新增失败Exec=" + err.Error())
		return
	}
	if id, err := r.LastInsertId(); err != nil {
		fmt.Println("2-新增失败LastInsertId=", err.Error())
	} else {
		fmt.Println("2-新增成功id=", id)
	}

	type myUser struct {
		id   uint
		name string
		age  uint8
	}
	// 3.1 单行查询
	var u myUser
	if err = DB.QueryRow(`select * from user where id=?`, 1).Scan(&u.id, &u.name, &u.age); err != nil {
		fmt.Println("单行查询错误=" + err.Error())
		return
	}
	fmt.Println("单行查询成功=", u)

	// 3.2 多行查询
	rows, err := DB.Query(`SELECT * FROM user`)
	if err != nil {
		fmt.Println("多行查询错误=" + err.Error())
		return
	}
	defer rows.Close()
	for rows.Next() {
		err := rows.Scan(&u.id, &u.name, &u.age)
		if err != nil {
			fmt.Println("多行查询scan错误=" + err.Error())
			return
		}
		fmt.Printf("多行查询(%T)=%v\n", u, u)
	}

	// 4. 更新
	if res, err := DB.Exec(`update user set age=? where id=?`, 22, 2); err != nil {
		fmt.Println("更新失败=", err.Error())
		return
	} else {
		affected, _ := res.RowsAffected()
		fmt.Println("更新成功行数=", affected)
	}
	// 5. 删除
	if res, err := DB.Exec(`delete from user where id=?`, 1); err != nil {
		fmt.Println("删除失败=", err.Error())
		return
	} else {
		affected, _ := res.RowsAffected()
		fmt.Println("删除成功行数=", affected)
	}
	// 6. 事务
	tx := sql.TxOptions{sql.LevelRepeatableRead, false}
	mTx, err := DB.BeginTx(context.Background(), &tx)
	if err != nil {
		fmt.Println("事务开始失败=", err.Error())
		return
	}
	res, err := mTx.Exec(`delete from user`)
	if err != nil {
		fmt.Println("事务执行失败=", err.Error())
	}
	affected, _ := res.RowsAffected()
	fmt.Println("影响行数=", affected)
	if err := mTx.Rollback(); err != nil {
		fmt.Println("事务回滚失败=", err.Error())
		return
	} else {
		fmt.Println("事务回滚成功")
	} // 回滚
	if err := mTx.Commit(); err != nil {
		fmt.Println("事务提交失败=", err.Error())
	} else {
		fmt.Println("事务提交失成功")
	} // 提交(提交和回滚只能存在一个)
}

image

posted @   爱编程_喵  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
jQuery火箭图标返回顶部代码

jQuery火箭图标返回顶部代码

滚动滑动条后,查看右下角查看效果。很炫哦!!

适用浏览器:IE8、360、FireFox、Chrome、Safari、Opera、傲游、搜狗、世界之窗.

点击右上角即可分享
微信分享提示