MySQL is a commonly used relational database in the industry. In normal development, WE often deal with MySQL database. Therefore, how to use Go language to operate MySQL database will be introduced in the next chapter.
Download the MySql connection driver
The DATABASE/SQL package in the Go language provides a generic interface to guarantee SQL or SQL-like databases and does not provide specific database drivers. You must inject (at least) one database driver when using the Database/SQL package.
Most of the databases we use have full third-party implementations. For example, MySQL driver
go get -u github.com/go-sql-driver/mysql
Copy the code
func Open(driverName, dataSourceName string) (*DB, error)
Copy the code
Open Opens a dirverName database, dataSourceName specifies the data source, usually including at least the database file name and other information necessary for connection.
Sample code:
import ( "database/sql" _ "github.com/go-sql-driver/mysql")func main() { // DSN:Data Source Name dsn := "User :password@tcp(127.0.0.1:3306)/dbname" db, err := sql.Open("mysql", DSN) if err! = nil {panic(err)} defer db.close ()Copy the code
Initializing a connection
The Open function may simply verify that its arguments are properly formatted and does not actually create a connection to the database. If you want to check that the name of the data source is valid, you should call the Ping method.
The returned DB object can be safely used concurrently by multiple Goroutines and maintains its own pool of free connections. Therefore, the Open function should only be called once and the DB object should rarely be closed.
Example code is as follows:
// define a function to initialize the database func initDB() (err error) {// DSN:Data Source Name DSN: = User: "@" TCP (127.0.0.1:3306)/sql_test? Charset =utf8mb4&parseTime=True" charset=utf8mb4&parseTime=True Db db, err = sql.Open("mysql", DSN) if err! Err = db.ping () if err! Func main() {err := initDB() // Call the output database function if err! = nil { fmt.Printf("init db failed,err:%v\n", err) return }}Copy the code
Where SQL. DB is the database object (structure instance) representing the connection, which holds all information about the connection to the database. It maintains an internal connection pool with zero to multiple underlying connections, which can safely be used simultaneously by multiple Goroutines.
func (db *DB) SetMaxOpenConns(n int)
Copy the code
SetMaxOpenConns Sets the maximum number of connections to the database. If n is greater than 0 and smaller than the maximum number of idle connections, the maximum number of idle connections is reduced to match the maximum number of open connections. If n<=0, there is no limit to the maximum number of open connections, which defaults to 0 (unrestricted).
func (db *DB) SetMaxIdleConns(n int)
Copy the code
MySql > create table
CREATE DATABASE sql_test;
Copy the code
use sql_test;
Copy the code
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;
Copy the code
MySql > alter database
type user struct { id int age int name string}
Copy the code
func (db *DB) QueryRow(query string, args ... interface{}) *RowCopy the code
Func queryRowDemo() {sqlStr := "select id, name, age from user where id=? Var u user // important: Err := db.queryRow (sqlStr, 1).Scan(&u.id, &u.name, &u.age) if err! = nil { fmt.Printf("scan failed, err:%v\n", err) return } fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)}Copy the code
Db.query () executes a Query that returns multiple Rows of results (that is, Rows), typically used to execute the select command. The args parameter represents the placeholder parameter in query.
func (db *DB) Query(query string, args ... interface{}) (*Rows, error)Copy the code
Sample code:
Func queryMultiRowDemo() {sqlStr := "select id, name, age from user where id >? rows, err := db.Query(sqlStr, 0) if err ! Printf("query failed, err:%v\n", err) return} Defer rows.close () // loop to read the data in the result set for rows.next () {var u user err := rows.scan (&u.id, &u.name, &u.age) if err ! = nil { fmt.Printf("scan failed, err:%v\n", err) return } fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) }}Copy the code
Insert data from MySql
The Exec methods are used for insert, update, and delete operations.
func (db *DB) Exec(query string, args ... interface{}) (Result, error)Copy the code
Exec executes a command (query, delete, update, insert, etc.), and the Result returned is a summary of the SQL commands executed. The args parameter represents the placeholder parameter in query.
Example code for inserting data is as follows:
Func insertRowDemo() {sqlStr := "insert into user(name, age) values (? ,?) "Ret, err := db.Exec(sqlStr, 38) if err! Printf("insert failed, err:%v\n", err) return} theID, err: = ret.lastinsertid () // theID of the newly inserted data if err! = nil { fmt.Printf("get lastinsert ID failed, err:%v\n", err) return } fmt.Printf("insert success, the id is %d.\n", theID)}Copy the code
Operation MySql update data
Example code for updating data is as follows:
Func updateRowDemo() {sqlStr := "Update user set age=? where id = ?" ret, err := db.Exec(sqlStr, 39, 3) if err ! Printf("update failed, err:%v\n", err) return} n, err: = ret.rowsaffected () // If err! = nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("update success, affected rows:%d\n", n)}Copy the code
Delete data from MySql
Example code for deleting data is as follows:
Func deleteRowDemo() {sqlStr := "delete from user where id =?" ret, err := db.Exec(sqlStr, 3) if err ! Printf("delete failed, err:%v\n", err) return} n, err: = ret.rowsaffected () // If err! = nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("delete success, affected rows:%d\n", n)}Copy the code
SQL injection security issues
We should never concatenate SQL statements ourselves!
Select * from user; select * from user; select * from user;
Func sqlInjectDemo(name string) {sqlStr := fmt.Sprintf("select id, name, age from user where name='%s'", name) fmt.Printf("SQL:%s\n", sqlStr) var u user err := db.QueryRow(sqlStr).Scan(&u.id, &u.name, &u.age) if err ! = nil { fmt.Printf("exec failed, err:%v\n", err) return } fmt.Printf("user:%#v\n", u)}Copy the code
Any of the following input strings can cause SQL injection problems:
sqlInjectDemo("xxx' or 1=1#")sqlInjectDemo("xxx' union select * from user #")sqlInjectDemo("xxx' and (select count(*) from user) <10 #")
Copy the code
Complete sample code archived at GitHub
Golang operates MySql database sample code
The above is about the Go language operation of MySql, MySql transactions will be introduced in the future article, thank you for reading, if you have any questions or comments, please timely comment.
Article source “Go keyboard man” public number, welcome to pay attention to exchange learning together!