go 返回mysql数组_Go基础之--操作Mysql(一)

关于标准库database/sql

database/sql是golang的标准库之一,它提供了一系列接口方法,用于访问关系数据库。它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现。

database/sql库提供了一些type。这些类型对掌握它的用法非常重要。

DB

数据库对象。 sql.DB类型代表了数据库。和其他语言不一样,它并是数据库连接。golang中的连接来自内部实现的连接池,连接的建立是惰性的,当你需要连接的时候,连接池会自动帮你创建。通常你不需要操作连接池。一切都有go来帮你完成。

Results

结果集。数据库查询的时候,都会有结果集。sql.Rows类型表示查询返回多行数据的结果集。sql.Row则表示单行查询结果的结果集。当然,对于插入更新和删除,返回的结果集类型为sql.Result。

Statements

语句。sql.Stmt类型表示sql查询语句,例如DDL,DML等类似的sql语句。可以把当成prepare语句构造查询,也可以直接使用sql.DB的函数对其操作。

而通常工作中我们可能更多的是用https://github.com/jmoiron/sqlx包来操作数据库

sqlx是基于标准库database/sql的扩展,并且我们可以通过sqlx操作各种类型的数据如

和其他语言不通的是,查询数据库的时候需要创建一个连接,对于go而言则是需要创建一个数据库对象,连接将会在查询需要的时候,由连接池创建并维护,使用sql.Open函数创建数据库对象,第一个参数是数据库驱动名,第二个参数是一个连接字符串

关于数据库的增删查改

增加数据

关于增加数据几个小知识点:

关于插入数据的时候占位符是通过问号:?

插入数据的后可以通过LastInsertId可以获取插入数据的id

通过RowsAffected可以获取受影响的行数

执行sql语句是通过exec

一个简单的使用例子:

package main

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

"fmt")

func main() {

Db,err:=sqlx.Open("mysql","root:123456@tcp(192.168.14.7:3306)/godb")if err !=nil{

fmt.Println("connect to mysql failed,",err)

return

}

defer Db.Close()

fmt.Println("connect to mysql success")//执行sql语句,切记这里的占位符是?

result,err := Db.Exec("INSERT INTO user_info(username,sex,email)VALUES (?,?,?)","user01","男","8989@qq.com")if err !=nil{

fmt.Println("insert failed,",err)

}//通过LastInsertId可以获取插入数据的id

userId,err:=result.LastInsertId()//通过RowsAffected可以获取受影响的行数

rowCount,err:=result.RowsAffected()

fmt.Println("user_id:",userId)

fmt.Println("rowCount:",rowCount)

}

通过Exec方法插入数据,返回的结果是一个sql.Result类型

查询数据

下面是一个查询的例子代码:

//执行查询操作

rows,err := Db.Query("SELECT email FROM user_info WHERE user_id>=5")if err !=nil{

fmt.Println("select db failed,err:",err)

return

}// 这里获取的rows是从数据库查的满足user_id>=5的所有行的email信息,rows.Next(),用于循环获取所有

for rows.Next(){

var s string

err= rows.Scan(&s)if err !=nil{

fmt.Println(err)

return

}

fmt.Println(s)

}

rows.Close()

使用了Query方法执行select查询语句,返回的是一个sql.Rows类型的结果集

迭代后者的Next方法,然后使用Scan方法给变量s赋值,以便取出结果。最后再把结果集关闭(释放连接)。

同样的我们还可以通过Exec方式执行查询语句

但是因为Exec返回的是一个sql.Result类型,从官网这里:

https://golang.google.cn/pkg/database/sql/#typeResult

我们可以直接这个接口里只有两个方法:LastInsertId(),RowsAffected()

我们还可以通过Db.Get()方法获取查询的数据,将查询的数据保存到一个结构体中

//Get执行查询操作

type user_info struct {

Username string `db:"username"`

Email string `db:"email"`

}

var userInfo user_info

err= Db.Get(&userInfo,"SELECT username,email FROM user_info WHERE user_id=5")if err !=nil{

fmt.Println(err)

return

}

fmt.Println(userInfo)

这样获取的一个数据,如果我们需要获取多行数据信息还可以通过Db.Select方法获取数据,代码例子为:

var userList []*user_info

err= Db.Select(&userList,"SELECT username,email FROM user_info WHERE user_id>5")if err !=nil{

fmt.Println(err)

return

}

fmt.Println(userList)

for _,v:=range userList{

fmt.Println(v)

}

通过Db.Select方法将查询的多行数据保存在一个切片中,然后就可以通过循环的方式获取每行数据

更新数据

下面是一个更新的例子,这里是通过Exec的方式执行的

//更新数据

results,err := Db.Exec("UPDATE user_info SET username=? where user_id=?","golang",5)if err !=nil{

fmt.Println("update data fail,err:",err)

return

}

fmt.Println(results.RowsAffected())

删除数据

下面是一个删除的例子,同样是通过Exec的方式执行的

//删除数据

results,err := Db.Exec("DELETE from user_info where user_id=?",5)if err !=nil{

fmt.Println("delete data fail,err:",err)

return

}

fmt.Println(results.RowsAffected())

通过上面的简单例子,对golang操作mysql的增删查改,有了一个基本的了解,下面整理一下重点内容

sql.DB

当我们调用sqlx.Open()可以获取一个sql.DB对象,sql.DB是数据库的抽象,切记它不是数据库连接,sqlx.Open()只是验证数据库参数,并没不创建数据库连接。sql.DB提供了和数据库交互的函数,同时也管理维护一个数据库连接池,并且对于多gegoroutines也是安全的

sql.DB表示是数据库抽象,因此你有几个数据库就需要为每一个数据库创建一个sql.DB对象。因为它维护了一个连接池,因此不需要频繁的创建和销毁。

连接池

只用sql.Open函数创建连接池,可是此时只是初始化了连接池,并没有创建任何连接。连接创建都是惰性的,只有当真正使用到连接的时候,连接池才会创建连接。连接池很重要,它直接影响着你的程序行为。

连接池的工作原来却相当简单。当你的函数(例如Exec,Query)调用需要访问底层数据库的时候,函数首先会向连接池请求一个连接。如果连接池有空闲的连接,则返回给函数。否则连接池将会创建一个新的连接给函数。一旦连接给了函数,连接则归属于函数。函数执行完毕后,要不把连接所属权归还给连接池,要么传递给下一个需要连接的(Rows)对象,最后使用完连接的对象也会把连接释放回到连接池。

请求连接的函数有几个,执行完毕处理连接的方式也不同:

db.Ping() 调用完毕后会马上把连接返回给连接池。

db.Exec() 调用完毕后会马上把连接返回给连接池,但是它返回的Result对象还保留这连接的引用,当后面的代码需要处理结果集的时候连接将会被重用。

db.Query() 调用完毕后会将连接传递给sql.Rows类型,当然后者迭代完毕或者显示的调用.Clonse()方法后,连接将会被释放回到连接池。

db.QueryRow()调用完毕后会将连接传递给sql.Row类型,当.Scan()方法调用之后把连接释放回到连接池。

db.Begin() 调用完毕后将连接传递给sql.Tx类型对象,当.Commit()或.Rollback()方法调用后释放连接。

每个连接都是惰性的,如何验证sql.Open调用之后,sql.DB对象可用,通过db.Ping()初始化

代码例子:

package main

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

"fmt")

func main() {

Db, err := sqlx.Open("mysql", "root:123456@tcp(192.168.50.166:3306)/godb")if err !=nil {

fmt.Println("connect to mysql failed,", err)

return

}

defer Db.Close()

fmt.Println("connect to mysql success")

err=Db.Ping()if err !=nil{

fmt.Println(err)

return

}

fmt.Println("ping success")

}

需要知道:当调用了ping之后,连接池一定会初始化一个数据连接

连接失败

database/sql 其实帮我们做了很多事情,我们不用见擦汗连接失败的情况,当我们进行数据库操作的时候,如果连接失败,database/sql 会帮我们处理,它会自动连接2次,这个如果查看源码中我们可以看到如下的代码:

// ExecContext executes a querywithout returning any rows.// The args are for any placeholder parameters in the query.

func (db*DB) ExecContext(ctx context.Context, querystring, args ...interface{}) (Result, error) {

var res Result

var err error

for i := 0; i < maxBadConnRetries; i++{

res, err= db.exec(ctx, query, args, cachedOrNewConn)if err !=driver.ErrBadConn {

break

}

}if err ==driver.ErrBadConn {

return db.exec(ctx,query, args, alwaysNewConn)

}

return res, err

}

上述代码中变量maxBadConnRetries小时如果连接失败尝试的次数,默认是2

关于连接池配置

db.SetMaxIdleConns(n int) 设置连接池中的保持连接的最大连接数。默认也是0,表示连接池不会保持释放会连接池中的连接的连接状态:即当连接释放回到连接池的时候,连接将会被关闭。这会导致连接再连接池中频繁的关闭和创建。

db.SetMaxOpenConns(n int) 设置打开数据库的最大连接数。包含正在使用的连接和连接池的连接。如果你的函数调用需要申请一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的函数调用将会被block,直到有可用的连接才会返回。设置这个值可以避免并发太高导致连接mysql出现too many connections的错误。该函数的默认设置是0,表示无限制。

db.SetConnMaxLifetime(d time.Duration) 设置连接可以被使用的最长有效时间,如果过期,连接将被拒绝

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

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

相关文章

Vue CLI 3开发中屏蔽烦人的EsLint错误

问题 Vue开发中&#xff0c;特别是当你阅读分析别人的其中早期版本的Vue代码时往往会遭遇到满屏幕的烦人的EsLint错误。有关EsLint这个工具的作用不再赘述。查阅网上参考文档&#xff0c;大多是针对早起版本Vue CLI工具项目的&#xff0c;在我最新使用的Vue CLI 3生成的工程中根…

pyinstaller---将py文件打包成exe

pyinstaller可将Python脚本打包成可执行程序&#xff0c;使在没有Python环境的机器上运行。 1.pyinstaller在windows下的安装 直接在命令行用pip安装 pyinstaller&#xff0c; 在windows下&#xff0c;pyinstaller需要PyWin32的支持。当用pip安装pyinstaller时未找到PyWin32&am…

老人寻求到一名程序员,用2W行代码给自己打造了一幅肖像画

今天翻墙看了下国外的论坛&#xff0c;看到了一位版主给一位老人描绘肖像画的文章&#xff0c;不得不说这位大佬是真的厉害&#xff0c;近20000行代码&#xff0c;而且还画的很像&#xff0c;像小编我这种手残党&#xff0c;用笔也不能画出来&#xff0c;不得不服&#xff0c;今…

一题多解,ASP.NET Core应用启动初始化的N种方案[下篇]

[接上篇]“天下大势&#xff0c;分久必合&#xff0c;合久必分”&#xff0c;ASP.NET应用通过GenericWebHostService这个承载服务被整合到基于IHostBuilder/IHost的服务承载系统中之后&#xff0c;也许微软还是意识到Web应用和后台服务的承载方式还是应该加以区分&#xff0c;于…

java jpa 模糊查询_JPA 以SQL实现分页不模糊查询(参数可能为空)

repository代码:package com.fancy.miniflow.repository;import java.util.List;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;import org.springframework.data.jpa.repository.Q…

GitHub服务中断24小时11分钟事故分析报告\n

上周&#xff0c;GitHub经历了一次事故&#xff0c;导致服务降级24小时11分钟。虽然平台的某些部分不受事故影响&#xff0c;但仍然有多个内部系统受到了影响&#xff0c;向用户显示了过时且不一致的内容。所幸没有用户数据丢失&#xff0c;但针对几秒钟数据库写入的手动调整工…

8 旋转数组的最小数字

输入一个递增排序数组的一个旋转&#xff0c;输出旋转数组的最小元素例如1,2,3,4,5的一个旋转可以为3,4,5,1,2把一个数组的最开始若干个元素搬到数组的末尾&#xff0c;称之为数组的旋转 输出旋转数组的最小元素 C: 1 class Solution {2 public:3 int minInOrder(vector<…

软考新思维--2017年上半年信息系统项目管理师上午试题分析与答案(试题6-10题)...

2017年上半年信息系统项目管理师上午试题分析与答案&#xff08;试题1-5题&#xff09; 6.&#xff08;&#xff09;不是获取需求的方法。A、问卷调查B、会议讨论C、获取原型D、决策分析【软考新思维】需求是获取的得来的&#xff0c;不是决策得来的。 先是获取需求&#xff0c…

php 合并 字符串_PHP如何去重合并字符串

本篇文章主要给大家介绍PHP如何去重合并字符串。推荐教程&#xff1a;《PHP教程》对于PHP学习者来说&#xff0c;合并多个字符串&#xff0c;应该并不是很难。但是如果这多个字符串中&#xff0c;有相同元素&#xff0c;当我们想要合并他们并且要使其值具有唯一值。也就是说合并…

10.31T4 HAOI2010最长公共子序列 计数+容斥原理

2775 -- 【HAOI2010】最长公共子序列 Description 字符序列的子序列是指从给定字符序列中随意地&#xff08;不一定连续&#xff09;去掉若干个字符&#xff08;可能一个也不去掉&#xff09;后所形成的字符序列。令给定的字符序列X“x0&#xff0c;x1&#xff0c;…&#xff0…

软概(lesson 2):课堂测试

一、测试题目 二、完成过程 1.设计思想 ①连接mysql数据库 ②设计user类&#xff0c;增加参数 ③设计add类&#xff0c;向数据库内增加内容 ④设计addInput页面&#xff0c;完成录入操作 ⑤设计add页面&#xff0c;接收录入的参数&#xff0c;并调用add类函数 2.源代码 user.ja…

谷歌Gboard输入法新增“无痕模式”:仅在Chrome隐身窗口中适用

据外媒Android Police报道&#xff0c;如大家所知道的&#xff0c;Chrome浏览器中的“隐身模式”是为了防止你的私密浏览记录被其他人看到&#xff0c;但是&#xff0c;在这种模式下&#xff0c;你的输入法键盘依然会记住你输入的短语&#xff0c;为了阻止你的键盘在Chrome隐身…

php两个数组融合,php合并两个数组的方式有哪些

1、arrary_merge示例代码&#xff1a;$arr1 array(1, 2, 3, 4, 5);$arr2 array(1, 2, 6, 7, 8, 9, 10);$result1 array_merge($arr1, $arr2);$arr3 array("name" > "itbsl", "age" > 13, "sex" > "Male");$arr…

最近对latin-1这个字符集产生了不少好感

【简介】 最近我要解析一个数据库中间件的日志、这个中间件会在日志中记录SQL发往的后台DB ,执行耗时&#xff0c;对应的SQL&#xff1b;中间件直接把SQL写到 了日志中去&#xff0c;并没有对SQL进行适当的编码转换&#xff1b;理想情况下这个也不会有什么问题&#xff0c;不幸…

面象对象设计原则之六:迪米特原则(LeastKnowledge Principle, LKP)

迪米特法则来自于1987年美国东北大学(Northeastern University)一个名为“Demeter”的研究项目。迪米特法则又称为最少知识原则(LeastKnowledge Principle, LKP)&#xff0c;其定义如下&#xff1a; 迪米特法则(Law of Demeter, LoD)&#xff1a;一个软件实体应当尽可能少地与…

php symfony urlmatcher-gt;match,symfony路由组件(The Routing Component)

The Routing component 把HTTP request转换为一系列的配置参数.安装你有两种方式来安装这个组件:通过 Composer (symfony/routing on Packagist);使用官方的 Git repository (https://github.com/symfony/Routing)。然后, 需要Composer把vendor/autoload.php 这个文件提供 给 a…

R升级和包更新

1.R升级 # 安装包"installr" install.packages("installr") # 导入包 library(installr) # 升级 updateR() 2.包升级 # 包升级 update.packages() 3.安装包 # 选择镜像 options(reposstructure(c(CRAN"https://cran.cnr.berkeley.edu/"))) # 安装…

其他对象的表单

1.textarea&#xff1a; textarea对象就想是input对象中的text样式的表单&#xff0c;只不过是扩展过的text样式表单。它可以通过行&#xff08;rows&#xff09;属性和列&#xff08;cols&#xff09;属性来编辑文本域的大小。最常见于留言板、论坛时回帖时的文本框等。 <h…

WinForm(十三)WebView2

WebView是WinForm框架中一个控件&#xff0c;用来对网页信息交互&#xff0c;有时Web自己开发的&#xff0c;有时Web是三方的。下面通过一个例子来看看WebView2的使用。首先看Web的逻辑&#xff0c;是一个商品添加页面&#xff0c;用AlpineJS和BootStrap来开发的&#xff0c;业…

Fluent UDF【4】:C语言

Fluent UDF利用的是C语言&#xff0c;本文简单介绍在UDF中经常会用到的C语言常识。 本文部分内容来自UDF手册。 1 C语言中的注释 C语言中的注释利用/*及*/来实现。例如: /*这是一个注释*/ 注释也可以跨行实现&#xff0c;如: /*这是一个 跨行注释*/ 注意:在编写UDF的过程中&…