MySQL

Последнее обновление: 31.01.2018

Для работы с MySQL будем использовать драйвер Go MySQL Driver. Прежде всего нам надо добавить данный драйвер к переменной $GOPATH. Для этого выполним в командной строке/терминале следующую команду:

go get github.com/go-sql-driver/mysql

Вначале создадим на сервере MySQL базу данных productdb и в ней таблицу products. Для этого можно использовать следующие выражений SQL

create database productdb;
use productdb;
create table products (
	id int auto_increment primary key,
	model varchar(30) not null,
	company varchar(30) not null,
	price int not null
)

То есть база данных productdb, в ней есть таблица products, которая будет хранить информацию о товарах, будет 4 столбца: id - идентификатор каждой записи, model - название товара, company - производитель товара и price - цена товара.

Добавление данных

Созданная база данных пуста, поэтому добавим в нее какие-нибудь данные:

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

func main() { 
	db, err := sql.Open("mysql", "root:password@/productdb")
	
	if err != nil {
		panic(err)
	} 
	defer db.Close()
	
	result, err := db.Exec("insert into productdb.Products (model, company, price) values (?, ?, ?)", 
		"iPhone X", "Apple", 72000)
	if err != nil{
		panic(err)
	}
	fmt.Println(result.LastInsertId())	// id добавленного объекта
	fmt.Println(result.RowsAffected())	// количество затронутых строк
}

Вначале подключаем все нужные нам пакеты. Для работы с реляционной базой данных необходим пакет "database/sql". И так как мы используем mysql, то также подключаем пакет "github.com/go-sql-driver/mysql", причем обратите внимание, что перед ним стоит знак подчеркивания. Этот знак позволяет при загрузке пакета инициализировать его с помощью вызова функции init.

Далее открываем подключение функцией Open:

sql.Open("mysql", "root:password@/productdb")

Первый аргумент функции - название драйвера, в данном случае это "mysql". Второй параметр имеет форму "логин:пароль@/база_данных". Логин и пароль должны быть те, которые были указаны для mysql при его установке. В моем случае логин - root, а пароль - password. Название базы данных -productdb - та, которая была создана выше.

Эта функция возвращает объект базы данных - DB. И для добавления данных у этого объекта вызывается метод Exec():

result, err := db.Exec("insert into productdb.Products (model, company, price) values (?, ?, ?)", 
		"iPhone X", "Apple", 72000)

Первый аргумент функции - это sql-выражение, которое добавляет строку в таблицу Products. Знаки вопроса в этом выражении представляют плейсхолдеры, вместо которых вставляются значения, которые передаются через второй, третий и последующие параметры. То есть в таблице Products четыре столбца, но один из них автогенерируемый - id. Поэтому передаем три значения - для столбцов model, company и price. Поэтому в выражении три знака вопроса и соответственно функция принимает три дополнительных параметра. Все дополнительные параметры передаются в sql-выражение на место плейсхолдеров по позиции - первый параметр вместо первого плейсхолдера и так далее.

Результат выполнения функции попадает в переменную result, которая хранит результат выполнения операции в базе данных. В частности, через метод result.LastInsertId() мы можем получить id последнего добавленного объекта, а с помощью метода result.RowsAffected() - количество добавленных строк.

И при выполнении данного скрипта получим следующие результаты:

Добавление в базу данных MySQL в языке Go

При этом необязательно определять все добавляемые данные через параметры, можно ввести их напрямую в sql-выражение:

result, err := db.Exec("insert into productdb.Products (model, company, price) values ('Pixel 2', 'Google', 64000)")

Получение данных

Теперь получим ранее добавленные данные:

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

type product struct{
	id int
	model string
	company string
	price int
}
func main() { 
	db, err := sql.Open("mysql", "root:password@/productdb")
	
	if err != nil {
		panic(err)
	} 
	defer db.Close()
	rows, err := db.Query("select * from productdb.Products")
	if err != nil {
		panic(err)
	}
	defer rows.Close()
	products := []product{}
	
	for rows.Next(){
		p := product{}
		err := rows.Scan(&p.id, &p.model, &p.company, &p.price)
		if err != nil{
			fmt.Println(err)
			continue
		}
		products = append(products, p)
	}
	for _, p := range products{
		fmt.Println(p.id, p.model, p.company, p.price)
	}
}

Для работы с данными здесь определена структура product, которая соответствует данным в таблице Products.

Для получения данных вызывается метод Query():

rows, err := db.Query("select * from productdb.Products")

Этот метод в качестве параметра принимает sql-выражение SELECT на получение всех данных из таблицы Products. Результат выборки попадает в переменную rows, которая представляет указатель на структуру Rows. И с помощью метода rows.Next() мы можем последовательно перебрать все строки в полученном наборе:

for rows.Next(){
	p := product{}
	err := rows.Scan(&p.id, &p.model, &p.company, &p.price)
	if err != nil{
		fmt.Println(err)
		continue
	}
	products = append(products, p)
}

Тип Rows определяет метод Scan, с помощью которого можно считать все полученные данные в переменные. Например, здесь считываем данные в структуру Product и затем добавляем ее в срез. Поскольку мы получаем все данные - все четыре столбца, то соответственно в Scan передается адреса четырех переменных.

После прочтения данных в срез мы можем делать с ними все что угодно, например, вывести на консоль:

Получение данных из базы данных MySQL в языке Go

В методе Query мы можем указывать дополнительные параметры. Например, получим товары, у которых цена больше 70000:

rows, err := db.Query("select * from productdb.Products where price > ?", 70000)

Если надо получить только одну строку, то можно использовать метод QueryRow():

row := db.QueryRow("select * from productdb.Products where id = ?", 2)
prod := product{}
err = row.Scan(&prod.id, &prod.model, &prod.company, &prod.price)
if err != nil{
	panic(err)
}
fmt.Println(prod.id, prod.model, prod.company, prod.price)

Обновление

Для обновления данных применяется метод Exec:

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

func main() { 
	db, err := sql.Open("mysql", "root:password@/productdb")
	
	if err != nil {
		panic(err)
	} 
	defer db.Close()
	// обновляем строку с id=1
	result, err := db.Exec("update productdb.Products set price = ? where id = ?", 69000, 1)
	if err != nil{
		panic(err)
	}
	fmt.Println(result.LastInsertId())
	fmt.Println(result.RowsAffected())
}

Удаление

Для удаления также применяется метод Exec:

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

func main() { 
	db, err := sql.Open("mysql", "root:password@/productdb")
	
	if err != nil {
		panic(err)
	} 
	defer db.Close()
	result, err := db.Exec("delete from productdb.Products where id = 1")
	if err != nil{
		panic(err)
	}
	fmt.Println(result.LastInsertId())	// id последнего удаленого объекта
	fmt.Println(result.RowsAffected())	// количество затронутых строк
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850