Golang 数据库操作

news2024/12/23 9:47:38

文章目录

      • 初始化连接
      • 连接池
        • 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)
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

原型制作的软件 Experience Design mac( XD ) 中文版软件特色

​XD是一个直观、功能强大的UI/UX开发工具&#xff0c;旨在设计、原型、用户之间共享材料以及通过数字技术进行设计交互。Adobe XD提供了开发网站、应用程序、语音界面、游戏界面、电子邮件模板等所需的一切。xd mac软件特色 体验设计的未来。 使用 Adobe XD 中快速直观、即取即…

女儿的睡衣,蕾丝花边蝴蝶结,太好看了吧

分享女儿的睡衣穿搭 大部分女孩子都喜欢 粉粉嫩小公主风格的衣服 我的宝贝也不例外啦 蕾丝花边和蝴蝶结真的会让女生少女心爆棚 非常厚实软糯的珊瑚绒质地&#xff0c;穿上非常暖和 裤脚和袖口都做了收口设计&#xff0c;真的很赞&#xff01; 还有麻麻款呢&#xff0c;…

C算法:使用选择排序实现从(大到小/从小到大)排序数组,且元素交换不可使用第三变量。

需求&#xff1a; 使用选择排序实现从(大到小/从小到大)排序&#xff0c;且元素交换不可使用第三变量 (异或交换法) 代码实现&#xff1a; #include <stdio.h> void maopao(int* array,int len,int(*swap)(int a,int b)) {int i,j;for(i0;i<len-1;i){for(ji1;j<…

如何判断LED透明屏质量好坏?

要判断LED透明屏的质量好坏&#xff0c;您可以考虑以下几个关键因素&#xff1a; 焊点品质。焊点饱满的证明焊接工艺好&#xff0c;亮度高的透明屏&#xff0c;证明焊锡用的好&#xff1b;品质不好的是虚焊&#xff0c;容易出现接触不良现象。 灯珠温度。点亮一段时间后&#x…

如何删除重复文件?简单操作法方法盘点!

“我之前传文件的时候好像传了很多重复的&#xff0c;导致这些文件占用了我大量的内存&#xff0c;有什么方法可以快速删除这些重复的文件吗&#xff1f;感谢&#xff01;” 随着时间的推移&#xff0c;我们的电脑中常常会积累大量的重复文件&#xff0c;这不仅占用宝贵的存储空…

竞赛选题 深度学习人脸表情识别算法 - opencv python 机器视觉

文章目录 0 前言1 技术介绍1.1 技术概括1.2 目前表情识别实现技术 2 实现效果3 深度学习表情识别实现过程3.1 网络架构3.2 数据3.3 实现流程3.4 部分实现代码 4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人脸表情识别系…

Allegro教学:Assembly层和Silkscreen元器件编号如何处理?

在电子工程中&#xff0c;PCB的设计和制造最为关键&#xff0c;而PCB上有多种层&#xff0c;有信号层、电源层、接地层和机械层&#xff0c;今天我们来聊聊Assembly层。来聊聊Silkscreen元器件编号问题&#xff0c;希望本文对小伙伴们有所帮助。 首先在回答这个问题前&#xff…

电脑机械硬盘怎么恢复数据?未备份的话,这几个方法请收好

在当今数字化的时代&#xff0c;数据的重要性不言而喻。然而&#xff0c;当电脑机械硬盘遇到数据丢失问题时&#xff0c;很多用户会感到束手无策。那么&#xff0c;电脑机械硬盘怎么恢复数据&#xff1f;在没有备份数据的情况下&#xff0c;这几个方法请收好。 图片来源于AI制作…

云栖大会?全部免费!!抢先一步看!

2023云栖大会定档10月31日&#xff01; 点击链接免费预约云栖门票&#xff1a; 2023云栖大会-领票页面 2023 云栖大会将于 10.31-11.2 在杭州云栖小镇举办&#xff0c;深度拥抱大数据AI 核心技术&#xff0c;见证阿里云大数据AI产品年度重磅发布及创新。开放融合的科技展示平…

用爬虫代码爬取高音质音频示例

目录 一、准备工作 1、安装Python和相关库 2、确定目标网站和数据结构 二、编写爬虫代码 1、导入库 2、设置代理IP 3、发送HTTP请求并解析HTML页面 4、查找音频文件链接 5、提取音频文件名和下载链接 6、下载音频文件 三、完整代码示例 四、注意事项 1、遵守法律法…

swiper3 无缝滚动 + 鼠标悬停停止/继续

html结构&#xff1a; <div class"peopleSwiper"><div class"swiper-container"><div class"swiper-wrapper"><div class"swiper-slide"><img src"images/people01.png"></div><di…

计算机组成原理——解决了我的一些困惑

这个是复习408时&#xff0c;临时起意&#xff0c;把这些问题记录下来&#xff0c;我现在复习了一半有余&#xff0c;于是把这些发布出来&#xff08;如果后面有新的&#xff0c;我会在这里面进行更新&#xff09; 1、代码中的——类型转换&#xff08;int -> short&#xf…

客户保留是什么意思?

任何一家企业&#xff0c;都需要去思考在销售过程中有多少客户是有效的&#xff1f;又有多少客户是可以保留的&#xff1f;初具规模的企业通过CRM客户管理系统只一味的开发新客户&#xff0c;而忽略客户保留&#xff0c;反而会造成资源的浪费。那么我们常说的客户保留是什么意思…

18 - 如何设置线程池大小?

还记得在 16 讲中说过“线程池的线程数量设置过多会导致线程竞争激烈”吗&#xff1f; 今天再补一句&#xff0c;如果线程数量设置过少的话&#xff0c;还会导致系统无法充分利用计算机资源。那么如何设置才不会影响系统性能呢&#xff1f; 其实线程池的设置是有方法的&#…

出差学小白知识No5:|Ubuntu上关联GitLab账号并下载项目(ssh key配置)

1 注冊自己的gitlab账户 有手就行 2 ubuntu安装git &#xff0c;并查看版本 sudo apt-get install git git --version 3 vim ~/.ssh/config Host gitlab.example.com User your_username Port 22 IdentityFile ~/.ssh/id_rsa PreferredAuthentications publickey 替换gitl…

python实现批量pdf转txt和word

文章目录 背景需求环境安装完整代码效果 背景需求 已经获取到了大量的pdf在download文件夹中&#xff0c;但是我需要的是txt文件和word文件&#xff5e; 环境安装 pip install pdf2docx pdfminer.six完整代码 # pip install pdf2docx pdfminer.siximport os from pdf2docx …

【LeetCode刷题-数组】--27.移除元素

27.移除元素 class Solution {public int removeElement(int[] nums, int val) {int slow 0,fast 0,n nums.length;while(fast < n){if(nums[fast] ! val){nums[slow] nums[fast];slow;}fast;}return slow;} }

Real3D FlipBook jQuery Plugin 3.41 Crack

Real3D FlipBook 和 PDF 查看器 jQuery 插件 - CodeCanyon 待售物品 实时预览 截图 视频预览 Real3D Flipbook jQuery 插件 - 1 Real3D Flipbook jQuery 插件 - 2 Real3D Flipbook jQuery 插件 - 3 新功能 – REAL3D FLIPBOOK JQUERY 插件的 PDF 到图像转换器 一款用于将…

在亚马逊购买产品时怎么选择自动收货方式

在亚马逊购买产品时&#xff0c;通常可以在下单时选择不同的收货方式&#xff0c;包括自动收货方式。以下是一般的购买流程&#xff1a; 登录亚马逊账号&#xff1a;打开网站&#xff0c;登录账号&#xff0c;如果没有账号&#xff0c;可以先创建一个。 浏览和添加商品&#…

Java JSON字符串转换成JSONArray对象,遍历JSONArray

JSON字符串转换成JSONArray对象&#xff0c;遍历JSONArray&#xff1a; // 一个未转化的字符串 String str "[{name:a,value:aa},{name:b,value:bb},{name:c,value:cc},{name:d,value:dd}]" ;// 首先把字符串转成 JSONArray 对象 JSONArray jsonArray JSONArray.p…