当前位置: 首页 > article >正文

golang操作mysql基础驱动github.com/go-sql-driver/mysql使用

golang中类似java操作mysql的jdbc一样,github.com/go-sql-driver/mysql也为go提供了基础接口,在开发中往往需要写更多的代码来满足自己的定制需求,java在驱动基础上有了扩展,orm框架诞生,mybatis、jpa等都是好用的扩展框架,go也不例外除了知道基础框架的实现和使用外,其他的orm框架也要轻松上手知道他们怎么在基础之上实现的,是否自己实现一套框架,go中的mysql框架比较多,这意味着基础框架github.com/go-sql-driver/mysql做的相当优秀,上层可以i灵活且自由的实现,我们这次主要是复习基础驱动的使用,如下:

package main

import (
	"database/sql"
	"fmt"
	"log"
	"time"

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

//  用户表结构体
type User struct {
	id       int64  `db:"id"`
	name     string `db:"name"`
	password string `db:"password"`
	age      int    `db:"age"`
}

var MysqlDb *sql.DB
var MysqlDbErr error

const (
	USER_NAME = "root"
	PASS_WORD = "fbw123"
	HOST      = "localhost"
	PORT      = "3307"
	DATABASE  = "node"
	CHARSET   = "utf8"
)

func linksql() {
	dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", USER_NAME, PASS_WORD, HOST, PORT, DATABASE, CHARSET)

	// 打开连接失败
	MysqlDb, MysqlDbErr = sql.Open("mysql", dbDSN)
	//defer MysqlDb.Close();
	if MysqlDbErr != nil {
		log.Println("dbDSN: " + dbDSN)
		panic("数据源配置不正确: " + MysqlDbErr.Error())
	}

	// 最大连接数
	MysqlDb.SetMaxOpenConns(100)
	// 闲置连接数
	MysqlDb.SetMaxIdleConns(20)
	// 最大连接周期
	MysqlDb.SetConnMaxLifetime(100 * time.Second)

	if MysqlDbErr = MysqlDb.Ping(); nil != MysqlDbErr {
		panic("数据库链接失败: " + MysqlDbErr.Error())
	} else {
		fmt.Println("数据库连接成功")
	}
}

// 查询数据,指定字段名---完成
func StructQueryField(id int64) {

	user := new(User)
	row := MysqlDb.QueryRow("select id, name, age,password from user where id=?", id)
	if err := row.Scan(&user.id, &user.name, &user.age, &user.password); err != nil {
		fmt.Printf("scan failed, err:%v", err)
		fmt.Println("查询失败")
		return
	}
	fmt.Println(user.id, user.name, user.age, user.password)
}

// 查询数据,取所有字段-----完成
func StructQueryAllField() {

	// 通过切片存储
	users := make([]User, 0)
	//分页查询一次查询2个记录
	rows, _ := MysqlDb.Query("SELECT * FROM `user` limit ?", 2)
	// 遍历
	var user User
	for rows.Next() {
		rows.Scan(&user.id, &user.name, &user.age, &user.password)
		users = append(users, user)
	}

	fmt.Println(users)

}

// 插入数据-----完成
func StructInsert(id int, name string, age int8, password string) {

	ret, _ := MysqlDb.Exec("insert INTO user(id,name,age,password) values(?,?,?,?)", id, name, age, password)

	//插入数据的主键id
	lastInsertID, _ := ret.LastInsertId()
	fmt.Println("LastInsertID:", lastInsertID)

	//影响行数
	rowsaffected, _ := ret.RowsAffected()
	fmt.Println("RowsAffected:", rowsaffected)

}

// 更新数据 -------完成
func StructUpdate(id int64, name string, password string, age int8) {

	ret, _ := MysqlDb.Exec("UPDATE user set name=?,password=?,age=? where id=?", name, password, age, id)
	upd_nums, _ := ret.RowsAffected()

	fmt.Println("RowsAffected:", upd_nums)
}

// 删除数据------完成
func StructDeluserByid(id uint64) {

	ret, _ := MysqlDb.Exec("delete from user where id=?", id)
	del_nums, _ := ret.RowsAffected()

	fmt.Println("RowsAffected:", del_nums)
}

// 事务处理,结合预处理----完成
func StructTx() {

	//事务处理,前面的插入代码没有什么问题,在后面的条件不满足下事务回滚
	tx, _ := MysqlDb.Begin()

	// 新增
	userAddPre, _ := MysqlDb.Prepare("insert into user(name,password,age) values(?, ?,?)")
	addRet, _ := userAddPre.Exec("zhaoliu", "mima", 12)
	ins_nums, _ := addRet.RowsAffected()
	// 更新
	userUpdatePre1, _ := tx.Exec("update user set name = 'zhansan'  where name=?", "张三")
	upd_nums1, _ := userUpdatePre1.RowsAffected()
	userUpdatePre2, _ := tx.Exec("update user set name = 'lisi'  where name=?", "李四")
	upd_nums2, _ := userUpdatePre2.RowsAffected()

	fmt.Println(ins_nums)
	fmt.Println(upd_nums1)
	fmt.Println(upd_nums2)

	if ins_nums > 0 && upd_nums1 > 0 && upd_nums2 > 0 {
		tx.Commit()
	} else {
		tx.Rollback()
	}

}

// 查询数据,指定字段名,不采用结构体 ------完成
func RawQueryField() {

	rows, _ := MysqlDb.Query("select id,name from user")
	if rows == nil {
		return
	}
	id := 0
	name := ""
	fmt.Println(rows)
	for rows.Next() {
		rows.Scan(&id, &name)
		fmt.Println(id, name)
	}
}

// 查询数据,取所有字段,不采用结构体------完成
func RawQueryAllField() {

	//查询数据,取所有字段
	rows2, _ := MysqlDb.Query("select * from user")

	//返回所有列
	cols, _ := rows2.Columns()

	//这里表示一行所有列的值,用[]byte表示
	vals := make([][]byte, len(cols))

	//这里表示一行填充数据
	scans := make([]interface{}, len(cols))
	//这里scans引用vals,把数据填充到[]byte里
	for k, _ := range vals {
		scans[k] = &vals[k]
	}

	i := 0
	result := make(map[int]map[string]string)
	for rows2.Next() {
		//填充数据
		rows2.Scan(scans...)
		//每行数据
		row := make(map[string]string)
		//把vals中的数据复制到row中
		for k, v := range vals {
			key := cols[k]
			//这里把[]byte数据转成string
			row[key] = string(v)
		}
		//放入结果集
		result[i] = row
		i++
	}
	fmt.Println(result)
	for k, v := range result {
		fmt.Println(k, v)
		//每条属性打一遍
		for k, p := range v {
			fmt.Println(k, p)
		}
	}
}

func main() {
	linksql()
	// StructQueryField(2020110131)
	// StructInsert(100,"lv"",23 "wenli")
	// StructQueryAllField()
	// StructUpdate(100,"少年","wjr",20)
	// StructDeluserByid(100)
	// StructTx()
	//查询所有的数据显示指定字段
	// RawQueryField()
	RawQueryAllField()
}


http://www.kler.cn/a/402066.html

相关文章:

  • nginx错误状态码
  • 高防服务器实现防御的方式,高防服务器的优势
  • 小米路由器用外网域名访问管理界面
  • 现代分布式系统新法宝:基于单元的架构
  • Excel数据动态获取与映射
  • Spark RDD 的 combineByKey、cogroup 和 compute 算子的作用
  • A - 123233(atCoder-380刷题笔记)
  • WebView2的踩坑记
  • Pr:音频过渡
  • 深度学习的多主机多GPU协同训练
  • 【C++学习(37)】并发性模式:如生产者-消费者、读写锁等。 架构模式:如MVC、MVVM等。属于23 种设计模式吗? RAII 的关系?
  • 传奇996_23——杀怪掉落,自动捡取,捡取动画
  • Ribbon 与 Feign:微服务调用中的差异探究
  • Linux网络——套接字编程
  • 学习记录:js算法(九十五):被围绕的区域
  • 2019年下半年试题二:论软件系统架构评估及其应用
  • Node.js | Yarn下载安装与环境配置
  • 【JAVA】正则表达式中的正向肯定预查
  • Java安全—log4j日志FastJson序列化JNDI注入
  • 创新租赁APP开发提升用户体验与业务效率
  • 【经典】webpack和vite的区别?
  • D - Strange Mirroring(AtCoder Beginner Contest 380)
  • ServletConfig、ServletContext、HttpServletRequest与HttpServletResponse常见API
  • 记录———封装uni-app+vant(u-upload)上传图片组件
  • windows C#-编写 C# LINQ 查询(上)
  • IPv6 NDP 记录