SQLite

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

Для работы с SQLite в Go нам потребуется драйвер go-sqlite3. Для использования драйвера вначале установим его, выполнив в командной строке/терминале следующую команду:

go get github.com/mattn/go-sqlite3

Пусть в папке со скриптом программы на Go у нас будет создана база данных SQLite, которая называется store.db, и в ней будет таблица products, которая описывается следующим скриптом:

CREATE TABLE products(
  id INTEGER PRIMARY KEY AUTOINCREMENT, 
  model TEXT,
  company TEXT,
  price INTEGER
);
Работа с базой данных SQLite в Go

Открытие подключения

Для открытия соединения с базой данных в функцию sql.Open() передается имя драйвера "sqlite3" и путь к файлу базы данных:

db, err := sql.Open("sqlite3", "store.db")

В результате установки подлючения метод db.Open возвратить объект *DB, через который можно будет взаимодействовать в базой данных.

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

Для добавления используется метод Exec() объекта DB:

package main
import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
)
func main() { 

	db, err := sql.Open("sqlite3", "store.db")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	result, err := db.Exec("insert into products (model, company, price) values ('iPhone X', $1, $2)", 
		"Apple", 72000)
	if err != nil{
		panic(err)
	}
	fmt.Println(result.LastInsertId())	// id последнего добавленного объекта
	fmt.Println(result.RowsAffected())	// количество добавленных строк
	
}

Через дополнительные параметры метода db.Exec() можно передавать значения выполняемому sql-выражению через плейхолдеры $1, $2 и так далее, вместо которых вставляются значения дополнительных параметров метода db.Exec.

У результата операции есть метод result.LastInsertId(), который возвращает id последнего добавленного объекта, и метод result.RowsAffected(), который позволяет получить количество добавленных строк:

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

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

Для получения данных применяется метод db.Query(), который возвращает набор строк, либо db.QueryRow(), который возвращает одну строку:

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

type product struct{
	id int
	model string
	company string
	price int
}
func main() { 

	db, err := sql.Open("sqlite3", "store.db")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	rows, err := db.Query("select * from 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 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 передается адреса четырех переменных.

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

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

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

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

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

row := db.QueryRow("select * from Products where id = $1", 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/mattn/go-sqlite3"
)
func main() { 

	db, err := sql.Open("sqlite3", "store.db")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	
	// обновляем строку с id=1
	result, err := db.Exec("update Products set price = $1 where id = $2", 69000, 1)
	if err != nil{
		panic(err)
	}
	fmt.Println(result.RowsAffected())	// количество обновленных строк
}

Удаление

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

package main
import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
)
func main() { 

	db, err := sql.Open("sqlite3", "store.db")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	
	// удаляем строку с id=1
	result, err := db.Exec("delete from Products where id = $1", 1)
	if err != nil{
		panic(err)
	}
	fmt.Println(result.RowsAffected())	// количество удаленных строк
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850