2023年6月21日发(作者:)
Golang操作MySql数据库的完整步骤记录前⾔MySQL是业界常⽤的关系型数据库,在平时开发中会经常与MySql数据库打交道,所以在接下来将介绍怎么使⽤Go语⾔操作MySql数据库。下载MySql连接驱动Go语⾔中的database/sql包提供了保证SQL或类SQL数据库的泛⽤接⼝,并不提供具体的数据库驱动。使⽤database/sql包时必须注⼊(⾄少)⼀个数据库驱动。我们常⽤的数据库基本上都有完整的第三⽅实现。⽐如:**下载依赖**go get -u /go-sql-driver/mysql**使⽤MySql驱动**
func Open(driverName, dataSourceName string) (*DB, error)Open打开⼀个dirverName指定的数据库,dataSourceName指定数据源,⼀般⾄少包括数据库⽂件名和其它连接必要的信息。⽰例代码:import ( "database/sql" _ "/go-sql-driver/mysql")func main() { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/dbname" db, err := ("mysql", dsn) if err != nil { panic(err) } defer () // 注意这⾏代码要写在上⾯err判断初始化连接Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调⽤Ping⽅法。返回的DB对象可以安全地被多个goroutine并发使⽤,并且维护其⾃⼰的空闲连接池。因此,Open函数应该仅被调⽤⼀次,很少需要关闭这个DB对象。⽰例代码如下:// 定义⼀个全局对象dbvar db *// 定义⼀个初始化数据库的函数func initDB() (err error) { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" // 不会校验账号密码是否正确 // 注意这⾥不其中是表⽰连接的数据库对象(结构体实例),它保存了连接数据库相关的所有信息。它内部维护着⼀个具有零到多个底层连接的连接池,它可以安全地被多个goroutine同时使⽤。**设置最⼤连接数**func (db *DB) SetMaxOpenConns(n int)SetMaxOpenConns设置与数据库建⽴连接的最⼤数⽬。如果n⼤于0且⼩于最⼤闲置连接数,会将最⼤闲置连接数减⼩到匹配最⼤开启连接数的限制。如果n<=0,不会限制最⼤开启连接数,默认为0(⽆限制)。**设置最⼤闲置连接数**func (db *DB) SetMaxIdleConns(n int)SetMaxIdleConns设置连接池中的最⼤闲置连接数。如果n⼤于最⼤开启连接数,则新的最⼤闲置连接数会减⼩到匹配最⼤开启连接数的限制。如果n<=0,不会保留闲置连接。MySql建库建表我们先在MySQL中创建⼀个名为`sql_test`的数据库:CREATE DATABASE sql_test;进⼊该数据库:use sql_test;执⾏以下命令创建⼀张⽤于测试的数据表:CREATE TABLE `user` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) DEFAULT '', `age` INT(11) DEFAULT '0', PRIMARY KEY(`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;操作MySql查询为了⽅便查询,我们事先定义好⼀个结构体来存储user表的数据。type user struct { id int age int name string}**单⾏查询**单⾏查询`ow()`执⾏⼀次查询,并期望返回最多⼀⾏结果(即Row)。QueryRow总是返回⾮nil的值,直到返回值的Scan⽅法被调⽤时,才会返回被延迟的错误。(如:未找到结果)func (db *DB) QueryRow(query string, args ...interface{}) *Row⽰例代码:
// 查询单条数据⽰例func queryRowDemo() { sqlStr := "select id, name, age from user where id=?" var u user // ⾮常重要:确保QueryRow之后调⽤Scan⽅法,否则持有的数据库链接不会被释放 err := ow(sqlStr, 1).Scan(&, &, &) if err !=**多⾏查询**多⾏查询()执⾏⼀次查询,返回多⾏结果(即Rows),⼀般⽤于执⾏select命令。参数args表⽰query中的占位参数。func (db *DB) Query(query string, args ...interface{}) (*Rows, error)⽰例代码:// 查询多条数据⽰例func queryMultiRowDemo() { sqlStr := "select id, name, age from user where id > ?" rows, err := (sqlStr, 0) if err != nil { ("query failed, err:%vn", err) return } // ⾮常重要:关闭rows释放持有的数据库链接 defer () /操作MySql插⼊数据插⼊、更新和删除操作都使⽤Exec⽅法。func (db *DB) Exec(query string, args ...interface{}) (Result, error)Exec执⾏⼀次命令(包括查询、删除、更新、插⼊等),返回的Result是对已执⾏的SQL命令的总结。参数args表⽰query中的占位参数。具体插⼊数据⽰例代码如下:// 插⼊数据func insertRowDemo() { sqlStr := "insert into user(name, age) values (?,?)" ret, err := (sqlStr, "王五", 38) if err != nil { ("insert failed, err:%vn", err) return } theID, err := sertId() // 新插⼊数据的id if err != nil { ("get las操作MySql更新数据具体更新数据⽰例代码如下:// 更新数据func updateRowDemo() { sqlStr := "update user set age=? where id = ?" ret, err := (sqlStr, 39, 3) if err != nil { ("update failed, err:%vn", err) return } n, err := fected() // 操作影响的⾏数 if err != nil { ("get RowsAffec操作MySql删除数据具体删除数据的⽰例代码如下:// 删除数据func deleteRowDemo() { sqlStr := "delete from user where id = ?" ret, err := (sqlStr, 3) if err != nil { ("delete failed, err:%vn", err) return } n, err := fected() // 操作影响的⾏数 if err != nil { ("get RowsAffected failed, eSQL注⼊安全问题我们任何时候都不应该⾃⼰拼接SQL语句!这⾥我们演⽰⼀个⾃⾏拼接SQL语句的⽰例,编写⼀个根据name字段查询user表的函数如下:// sql注⼊⽰例func sqlInjectDemo(name string) { sqlStr := f("select id, name, age from user where name='%s'", name) ("SQL:%sn", sqlStr) var u user err := ow(sqlStr).Scan(&, &, &) if err != nil { ("exec fail此时以下输⼊字符串都可以引发SQL注⼊问题:sqlInjectDemo("xxx' or 1=1#")sqlInjectDemo("xxx' union select * from user #")sqlInjectDemo("xxx' and (select count(*) from user) <10 #")完整⽰例代码归档GitHub到此这篇关于Golang操作MySql数据库的完整步骤记录的⽂章就介绍到这了,更多相关Golang操作MySql数据库内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
2023年6月21日发(作者:)
Golang操作MySql数据库的完整步骤记录前⾔MySQL是业界常⽤的关系型数据库,在平时开发中会经常与MySql数据库打交道,所以在接下来将介绍怎么使⽤Go语⾔操作MySql数据库。下载MySql连接驱动Go语⾔中的database/sql包提供了保证SQL或类SQL数据库的泛⽤接⼝,并不提供具体的数据库驱动。使⽤database/sql包时必须注⼊(⾄少)⼀个数据库驱动。我们常⽤的数据库基本上都有完整的第三⽅实现。⽐如:**下载依赖**go get -u /go-sql-driver/mysql**使⽤MySql驱动**
func Open(driverName, dataSourceName string) (*DB, error)Open打开⼀个dirverName指定的数据库,dataSourceName指定数据源,⼀般⾄少包括数据库⽂件名和其它连接必要的信息。⽰例代码:import ( "database/sql" _ "/go-sql-driver/mysql")func main() { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/dbname" db, err := ("mysql", dsn) if err != nil { panic(err) } defer () // 注意这⾏代码要写在上⾯err判断初始化连接Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调⽤Ping⽅法。返回的DB对象可以安全地被多个goroutine并发使⽤,并且维护其⾃⼰的空闲连接池。因此,Open函数应该仅被调⽤⼀次,很少需要关闭这个DB对象。⽰例代码如下:// 定义⼀个全局对象dbvar db *// 定义⼀个初始化数据库的函数func initDB() (err error) { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" // 不会校验账号密码是否正确 // 注意这⾥不其中是表⽰连接的数据库对象(结构体实例),它保存了连接数据库相关的所有信息。它内部维护着⼀个具有零到多个底层连接的连接池,它可以安全地被多个goroutine同时使⽤。**设置最⼤连接数**func (db *DB) SetMaxOpenConns(n int)SetMaxOpenConns设置与数据库建⽴连接的最⼤数⽬。如果n⼤于0且⼩于最⼤闲置连接数,会将最⼤闲置连接数减⼩到匹配最⼤开启连接数的限制。如果n<=0,不会限制最⼤开启连接数,默认为0(⽆限制)。**设置最⼤闲置连接数**func (db *DB) SetMaxIdleConns(n int)SetMaxIdleConns设置连接池中的最⼤闲置连接数。如果n⼤于最⼤开启连接数,则新的最⼤闲置连接数会减⼩到匹配最⼤开启连接数的限制。如果n<=0,不会保留闲置连接。MySql建库建表我们先在MySQL中创建⼀个名为`sql_test`的数据库:CREATE DATABASE sql_test;进⼊该数据库:use sql_test;执⾏以下命令创建⼀张⽤于测试的数据表:CREATE TABLE `user` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) DEFAULT '', `age` INT(11) DEFAULT '0', PRIMARY KEY(`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;操作MySql查询为了⽅便查询,我们事先定义好⼀个结构体来存储user表的数据。type user struct { id int age int name string}**单⾏查询**单⾏查询`ow()`执⾏⼀次查询,并期望返回最多⼀⾏结果(即Row)。QueryRow总是返回⾮nil的值,直到返回值的Scan⽅法被调⽤时,才会返回被延迟的错误。(如:未找到结果)func (db *DB) QueryRow(query string, args ...interface{}) *Row⽰例代码:
// 查询单条数据⽰例func queryRowDemo() { sqlStr := "select id, name, age from user where id=?" var u user // ⾮常重要:确保QueryRow之后调⽤Scan⽅法,否则持有的数据库链接不会被释放 err := ow(sqlStr, 1).Scan(&, &, &) if err !=**多⾏查询**多⾏查询()执⾏⼀次查询,返回多⾏结果(即Rows),⼀般⽤于执⾏select命令。参数args表⽰query中的占位参数。func (db *DB) Query(query string, args ...interface{}) (*Rows, error)⽰例代码:// 查询多条数据⽰例func queryMultiRowDemo() { sqlStr := "select id, name, age from user where id > ?" rows, err := (sqlStr, 0) if err != nil { ("query failed, err:%vn", err) return } // ⾮常重要:关闭rows释放持有的数据库链接 defer () /操作MySql插⼊数据插⼊、更新和删除操作都使⽤Exec⽅法。func (db *DB) Exec(query string, args ...interface{}) (Result, error)Exec执⾏⼀次命令(包括查询、删除、更新、插⼊等),返回的Result是对已执⾏的SQL命令的总结。参数args表⽰query中的占位参数。具体插⼊数据⽰例代码如下:// 插⼊数据func insertRowDemo() { sqlStr := "insert into user(name, age) values (?,?)" ret, err := (sqlStr, "王五", 38) if err != nil { ("insert failed, err:%vn", err) return } theID, err := sertId() // 新插⼊数据的id if err != nil { ("get las操作MySql更新数据具体更新数据⽰例代码如下:// 更新数据func updateRowDemo() { sqlStr := "update user set age=? where id = ?" ret, err := (sqlStr, 39, 3) if err != nil { ("update failed, err:%vn", err) return } n, err := fected() // 操作影响的⾏数 if err != nil { ("get RowsAffec操作MySql删除数据具体删除数据的⽰例代码如下:// 删除数据func deleteRowDemo() { sqlStr := "delete from user where id = ?" ret, err := (sqlStr, 3) if err != nil { ("delete failed, err:%vn", err) return } n, err := fected() // 操作影响的⾏数 if err != nil { ("get RowsAffected failed, eSQL注⼊安全问题我们任何时候都不应该⾃⼰拼接SQL语句!这⾥我们演⽰⼀个⾃⾏拼接SQL语句的⽰例,编写⼀个根据name字段查询user表的函数如下:// sql注⼊⽰例func sqlInjectDemo(name string) { sqlStr := f("select id, name, age from user where name='%s'", name) ("SQL:%sn", sqlStr) var u user err := ow(sqlStr).Scan(&, &, &) if err != nil { ("exec fail此时以下输⼊字符串都可以引发SQL注⼊问题:sqlInjectDemo("xxx' or 1=1#")sqlInjectDemo("xxx' union select * from user #")sqlInjectDemo("xxx' and (select count(*) from user) <10 #")完整⽰例代码归档GitHub到此这篇关于Golang操作MySql数据库的完整步骤记录的⽂章就介绍到这了,更多相关Golang操作MySql数据库内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
发布评论