Golang 数据库操作

文章目录

      • 初始化连接
      • 连接池
        • SetMaxOpenConns
        • SetMaxIdleConns
        • SetConnMaxIdleTime
        • SetConnMaxLifetime
      • 查询数据
      • 插入数据
      • 更新数据
      • 删除数据
      • 实现账号密码登录功能
      • sqlx的部分用法

在这里插入图片描述

首先安装包:Install

go get -u github.com/go-sql-driver/mysql // MySQL数据库的包
go get github.com/lib/pq // pg数据库的包

注意:不同数据库,安装的包不同

初始化连接

Open:函数只是验证连接参数是否正确

db.ping():测试是否能够正常连接数据库,返回nil表示可以

全局定义db变量是为了连t接数据库成功之后任意地方都可以进行操作。

引入 MySQL驱动包使用:_ "github.com/go-sql-driver/mysql"

当导入带有空白标识符前缀 _ 的包时,将调用包的 init 函数。该函数注册驱动程序

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

// 定义全局db对象
var db *sql.DB

func InitDB() (err error) {
  // Data Source Name:连接MySQL的格式
	dsn := "root:password@tcp(127.0.0.1:3306)/GoStudy"
  
  // 注意!!!这里不要使用:=,我们是给全局变量赋值,然后在main函数中使用全局变量db
	db, err = sql.Open("mysql", dsn)

	if err != nil {
		return err
	}
	
  // 尝试与数据库建立连接(校验dsn是否正确)
	return db.Ping()
}

func main() {
	if err := InitDB(); err != nil {
		fmt.Println("连接失败")
		return
	}
	
	// 数据库使用完之后关闭连接
	defer db.Close()
}

其中sql.DB是表示连接的数据库对象(结构体实例),它保存了数据库所有信息,内部维护了一个具有0到多个底层数据库连接池,它可以安全的被多个Goroutine使用。因此Open函数应该仅被调用一次,很少需要关闭这个对象

连接池

SetMaxOpenConns
func (db *DB) SetMaxOpenConns(n int)

SetMaxOpenConns设置与数据库建立连接的最大数目。 如果n大于0且小于最大闲置连接数,会将最大闲置连接数减小到匹配最大开启连接数的限制。 如果n<=0,不会限制最大开启连接数,默认为0(无限制)。需要MySQL服务器的max_connections参数值要小,可以用以下SQL查询

show variables like 'max_connections';
SetMaxIdleConns
func (db *DB) SetMaxIdleConns(n int)

SetMaxIdleConns设置连接池中的最大闲置连接数。 如果n大于最大开启连接数,则新的最大闲置连接数会减小到匹配最大开启连接数的限制。 如果n<=0,不会保留闲置连接。需要比maxOpenConns小

SetConnMaxIdleTime

连接池里面的连接最大空闲时长(一个连接不活跃的时长)。

SetConnMaxLifetime

连接池里面的连接最大存活时长。必须要比mysql服务器设置的wait_timeout小,否则会导致golang侧连接池依然保留已被mysql服务器关闭了的连接。

MySQL默认是8小时,可通过以下SQL查询

show variables like 'wait_timeout';

查询数据

单行数据查询

通过QueryRow方法实现

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

type User struct {
	Id   int
	Name string
	Pwd  string
	Age  int
	Sex  string
}

func InitDB() (err error) {
	// Data Source Name:连接MySQL的格式
	dsn := "root:password@tcp(127.0.0.1:3306)/GoStudy"
	db, err = sql.Open("mysql", dsn)

	if err != nil {
		return err
	}
	return db.Ping()
}

// QueryRowData 查询单条数据
func QueryRowData() {
	// 没有条件的SQL,默认查询第一条
	sqlStr := "select id, name, age from User"

	// 携带条件的SQL
	//sqlStr := "select id, name, age from User where id=?"

	var u User

	err := db.QueryRow(sqlStr).Scan(&u.Id, &u.Name, &u.Age)
  
  // 携带条件的SQL查询(2表示补充?占位的数据)
	//err := db.QueryRow(sqlStr, 2).Scan(&u.Id, &u.Name, &u.age)

	if err != nil {
		fmt.Println("查询数据异常:", err)

		return
	}
	fmt.Println(u.Id)
	fmt.Println(u.Name)
	fmt.Println(u.Age)
}

func main() {
	if err := InitDB(); err != nil {
		fmt.Println("连接失败")
		return
	}
	defer db.Close()

	fmt.Println("数据库连接成功")
	//QueryRowData()
	QueryData()
	// 数据库使用完之后关闭连接
}

Go语言参数占位需要通过?进行占位 ,在执行SQL时将参数补充进去。

顺序需要一致,例如:

sqlStr := "select id, name, age from User where id=? and age=?"
// 这里1表示传递给第一个?占位的参数(ID),2表示第二个(年龄)
db, err := db.Query(sqlStr, 1, 18)

多行数据查询

// QueryData 查询多条数据
func QueryData() {
  // 这里可以增加条件判断
	sqlStr := "select id, name, age from User"
  
	rows, err := db.Query(sqlStr)
	if err != nil {
		fmt.Println("查询数据异常:", err)
	}
	// 关闭rows持有的数据库连接(一定要加)
	defer rows.Close()

	// 遍历查询的所有数据
	for rows.Next() {
		var u User

		// 获取当前遍历到的数据
		err2 := rows.Scan(&u.Id, &u.Name, &u.Age)

		if err2 != nil {
			fmt.Println("查询数据异常:", err2)
		}

		fmt.Println(u.Id, u.Name, u.Age)
	}

}

插入数据

插入、更新、删除数据都是使用db.Exec方法

func InsertData() {
	sqlStr := "insert into User(name, age, sex) value(?,?,?)"

	ret, err := db.Exec(sqlStr, "james", 18, "male")
	if err != nil {
		fmt.Println("数据库插入异常", err)
		return
	}

	insertId, err2 := ret.LastInsertId()
	if err2 != nil {
		fmt.Println("插入数据ID获取失败:", err2)
		return
	}

	fmt.Println("插入的数据ID:", insertId)

}

更新数据

func UpdateData() {
	sqlStr := "update User set age=? where id=?"
	ret, err := db.Exec(sqlStr, 33, 2)
	if err != nil {
		fmt.Println("数据更新失败", err)
		return
	}
	n, err := ret.RowsAffected()
	if err != nil {
		fmt.Println("获取影响行数失败", err)
	}
	fmt.Println("数据更新成功,实际影响行数", n)
}

删除数据

func DeleteData() {
	sqlStr := "delete from User where id=?"
	ret, err := db.Exec(sqlStr, 2)
	if err != nil {
		fmt.Println("数据删除失败", err)
		return
	}
	n, err := ret.RowsAffected()
	if err != nil {
		fmt.Println("获取影响行数失败", err)
	}
	fmt.Println("数据删除成功,实际影响行数", n)
}

实现账号密码登录功能

MySQL存储账号和密码信息,实现终端输入账号和密码,通过查询MySQL判断账号或者密码是否正确

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

type User struct {
	Id   int
	Name string
}

// 初始化连接数据库
func InitDB() (err error) {
	dsn := "root:password@tcp(127.0.0.1:3306)/GoStudy"

	db, err = sql.Open("mysql", dsn)

	if err != nil {
		fmt.Println("DB link fail:", err)
		return
	}

	return db.Ping()
}

// 查询账号和密码是否正确,返回bool类型
func QueryLogin(username, pwd string) bool {
	sqlStr := "select id from User where `name`=? and `pwd`=?"

	var u User

	err := db.QueryRow(sqlStr, username, pwd).Scan(&u.Id)

	if err != nil {
		return false
	}

	return true

}

func main() {

	if ping := InitDB(); ping != nil {
		fmt.Println("DB ping fail:", ping)
		return
	}

	var username, pwd string

	fmt.Print("请输入账号:")
	_, err := fmt.Scanln(&username)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Print("请输入密码:")
	_, err2 := fmt.Scanln(&pwd)
	if err2 != nil {
		fmt.Println(err)
	}

	isLogin := QueryLogin(username, pwd)
	if isLogin {
		fmt.Println("登录成功!!")
	} else {
		fmt.Println("账号或者密码错误")
	}

}

sqlx的部分用法

安装

go get github.com/jmoiron/sqlx

基本使用:

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

var db *sqlx.DB

func InitDB() (err error) {
	dsn := "root:password@tcp(127.0.0.1:3306)/GoStudy"

	// sqlx:connect相当于 sqlx.open + db.ping
	db, err = sqlx.Connect("mysql", dsn)

	return err
}

type User struct {
	Id   int
	Name sql.NullString
	Age  sql.NullInt16
  // 避免查询出数据为Null导致的panic
	Sex  sql.NullString
	Pwd  sql.NullString
}

func UserInfoGet(sql string) User {
	var u User
	// 单条数据查询,查询出来的字段放到User结构体内
	err := db.Get(&u, sql)
	if err != nil {
		fmt.Println("数据查询异常:", err)
	}
	return u

}

func UserSelect(sql string) []User {
  // 多条数据查询,需要存放在数组内
	var u []User

	err := db.Select(&u, sql)
	if err != nil {
		fmt.Println("数据查询异常:", err)

	}
	return u
}

func main() {
	if err := InitDB(); err != nil {
		fmt.Println("数据库连接失败 ----")
	} else {
		fmt.Println("数据库连接成功 !!!!")
	}

	//u := UserInfoGet("select * from User")
	//fmt.Println(u.Id)

	u := UserSelect("select * from User")
	for _, data := range u {
		fmt.Println(data.Id, data.Name.String)
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/103599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单片机中的 _nop_() 延时以及其相关的基础扩展

使用 _nop_() 函数做延时遇到的一些问题 以及对此延伸出的一些需要了解的基本概念 ...... by 矜辰所致 完善文章内容结构&#xff0c;补充指令周期、机器周期等一些基本概念 2023/10/25前言 最近还是继续做着项目&#xff0c;因为在某 8051 内核芯片上使用到了 I…

【MySQL】用户与权限管理

文章目录 一、用户管理1、用户信息表2、创建用户3、删除用户4、修改用户密码 二、权限管理1、MySQL 权限2、给用户授权3、回收用户权限 一、用户管理 之前为了方便&#xff0c;我们学习 MySQL 时统一使用的都是 root 账号进行登录&#xff0c;但在实际的开发场景中必然是需要进…

opencalib中lidar2camera安装记录

目录 一、opencalib安装 二、lidar2camera的安装 三、测试运行 四、出现过的问题 一、opencalib安装 代码地址&#xff1a;https://github.com/PJLab-ADG/SensorsCalibration/blob/master/README.md # pull docker image sudo docker pull scllovewkf/opencalib:v1 # Aft…

RISC-V架构——中断委托和中断注入

1、中断委托 1.1、中断委托的作用 &#xff08;1&#xff09;默认情况下&#xff0c;所有的陷入&#xff08;中断和异常&#xff09;都是在M模式下处理&#xff0c;然后再返回到发生陷入前的模式&#xff1b; &#xff08;2&#xff09;所有陷入都在M模式处理会涉及到模式切换…

1个月5次发版:测试人的模块测试策略分类归纳

笔者所在项目经历了一个月开发周期&#xff0c;该项目有5名开发人员&#xff0c;1名项目经理&#xff0c;1名测试人员&#xff0c;涵盖OA系统8个模块&#xff0c;在短短1个月中进行了5次发布。 现进行模块测试策略分类归纳。 已有模块 配置项优化 对于已有模块的配置项优化&…

【JavaEE】线程安全的集合类 -- 多线程篇(9)

线程安全的集合类 多线程环境使用 ArrayList多线程环境使用队列多线程环境使用哈希表 多线程环境使用 ArrayList 自己使用同步机制 (synchronized 或者 ReentrantLock)Collections.synchronizedList(new ArrayList); synchronizedList 是标准库提供的一个基于 synchronized 进…

【深度学习 | Transformer】释放注意力的力量:探索深度学习中的 变形金刚,一文带你读通各个模块 —— 总结篇(三)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

基本指令(2):通配符,重定向,命令行管道

一、通配符 rm -rf ./* # * —— 通配符&#xff0c;指定路径下的所有文件&#xff08;不包括隐藏文件&#xff09;二、重定向 在理解重定向前&#xff0c;先要有一个概念&#xff1a;Linux下一切皆文件&#xff0c;大部分硬件设备都可以看做有读写方法&#xff0c;只不过有些方…

国腾GM8775C完全替代CS5518 MIPIDSI转2 PORT LVDS

集睿致远CS5518描述&#xff1a; CS5518是一款MIPI DSI输入、LVDS输出转换芯片。MIPI DSI 支持多达4个局域网&#xff0c;每条通道以最 大 1Gbps 的速度运行。LVDS支持18位或24位像素&#xff0c;25Mhz至154Mhz&#xff0c;采用VESA或JEIDA格 式。它只能使用单个1.8v电源&am…

化工园区数字孪生可视化管控平台,赋予园区安全环保智慧发展

化工行业作为国民经济的支柱和工业发展的引擎&#xff0c;对安全生产、环保节能、应急管控有着很高的要求。目前国内外化工园区面临安全和环保两大压力。为有效解决这两大难题&#xff0c;巨蟹数科综合运用物联网、数字孪生等新一代信息技术&#xff0c;建设了数字孪生园区智慧…

Echarts多曲线数值与Y周刻度不符合

发现问题&#xff1a; 在展示多曲线图表的时候&#xff0c;发现图表曲线数值相差不大&#xff0c;但是图表展示的曲线相差很大&#xff0c;仔细观察之后发现是展示有问题(其实这并不能算是错误&#xff0c;只是由于忽略&#xff0c;导致的配置与预期不符合)。 问题复现&#x…

【分布式】大模型分布式训练入门与实践 - 04

大模型分布式训练 数据并行-Distributed Data Parallel1.1 背景1.2 PyTorch DDP1&#xff09; DDP训练流程2&#xff09;DistributedSampler3&#xff09;DataLoader: Parallelizing data loading4&#xff09;Data-parallel&#xff08;DP&#xff09;5&#xff09;DDP原理解析…

CrossOver 23.6 让Mac可以运行Windows程序的工具

在当今数字化时代&#xff0c;虚拟机技术被广泛应用于软件开发、系统测试、网络安全等领域。虚拟机提供了一个隔离的虚拟环境&#xff0c;使得我们能够在一台物理计算机上同时运行多个操作系统和应用程序。下面我们就来看虚拟机软件怎么安装&#xff0c;虚拟机怎么使用吧&#…

【Linux】TCP协议

文章目录 &#x1f4d6; 前言1. TCP协议格式2. 确认应答机制3. 16位窗口大小4. 6个标记位4.1 URG紧急指针标记位&#xff1a; 5. 超时重传机制&#xff1a;6. 连接管理机制6.1 TCP三次握手&#xff08;重点&#xff09;&#xff1a;6.1 - 1 三次握手的原因6.1 - 2 RST复位标志位…

javaEE -6(10000详解文件操作)

一&#xff1a;认识文件 我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进行数据保存时&#xff0c;往往不是保存成一个整体&#xff0c;而是独立成一个个的单位进行保存&#xff0c;这个独立的单位就被抽象成文件的概念&#xff0c…

机关事务管理局数字化平台,让数据纵向直报,业务横向打通

机关事务管理局的核心职能是实现对机关事务的管理、保障、服务&#xff0c;是面向政府机关部门的“后勤服务”部门。 主要职能有&#xff1a;推进国有资产管理、公务用车管理、办公用房管理、公共机构节能管理、后勤管理等。党和政府“过紧日子”的要求为机关事务工作提出了更…

光影之梦2:动画渲染前后对比,揭示视觉艺术的惊人转变!

动画渲染是影视艺术中不可或缺的一环&#xff0c;它赋予了角色和场景鲜活的生命。渲染过程中的光影、色彩、材质等元素&#xff0c;像是画家的调色板&#xff0c;将平淡无奇的线条和形状转化为充满韵味与情感的画面。动画角色仿佛拥有了自己的灵魂&#xff0c;无论是一颦一笑&a…

集成学习方法之随机森林-入门

1、 什么是集成学习方法 集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型&#xff0c;各自独立地学习和作出预测。这些预测最后结合成组合预测&#xff0c;因此优于任何一个单分类的做出预测。 2、 什么是随机森林 在机器学习中&…

Parallels Client for Mac:改变您远程控制体验的革命性软件

在当今数字化的世界中&#xff0c;远程控制软件已经成为我们日常生活和工作中不可或缺的一部分。在众多远程控制软件中&#xff0c;Parallels Client for Mac以其独特的功能和出色的性能脱颖而出&#xff0c;让远程控制变得更加简单、高效和灵活。 Parallels Client for Mac是…

Python 面向对象编程:类、对象、初始化和方法详解

Python 是一种面向对象的编程语言。在 Python 中&#xff0c;几乎所有东西都是对象&#xff0c;都具有其属性和方法。 类似于对象构造函数或用于创建对象的“蓝图”的类。 创建一个类 要创建一个类&#xff0c;请使用关键字 class&#xff1a; 示例&#xff0c;创建一个名为…