Рассмотрим, как мы можем взаимодействовать с базой данных в веб-приложении. Основные моменты работы с бд с помощью языка программирования Go были рассмотрены в материале Go и базы данных. В данном же случае мы рассмотрим только непосредственно применение этих моментов в рамках веб-приложения.
В качестве системы управления базами данных возьмем 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 - цена товара.
Добавим в нее какие-нибудь начальные данные, например, с помощью следующего скрипта:
insert into productdb.Products (model, company, price) values ('iPhone X', 'Apple', 74000), ('Pixel 2', 'Google', 62000), ('Galaxy S9', 'Samsung', 65000)
Прежде чем начать работать с MySQL, надо добавить драйвер для Go к переменной $GOPATH (если он ранее не был добавлен). Для этого нужно выполнить в командной строке/терминале следующую команду:
go get github.com/go-sql-driver/mysql
После этого определим на сервере следующий код:
package main import ( "fmt" "database/sql" _ "github.com/go-sql-driver/mysql" "net/http" "html/template" "log" ) type Product struct{ Id int Model string Company string Price int } var database *sql.DB func IndexHandler(w http.ResponseWriter, r *http.Request) { rows, err := database.Query("select * from productdb.Products") if err != nil { log.Println(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) } tmpl, _ := template.ParseFiles("templates/index.html") tmpl.Execute(w, products) } func main() { db, err := sql.Open("mysql", "root:password@/productdb") if err != nil { log.Println(err) } database = db defer db.Close() http.HandleFunc("/", IndexHandler) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
Прежде всего здесь определена структура Product, которая соответствует опредению таблицы products в базе данных. А за взаимодействие с базой данных отвечает переменная database.
Для отправки пользователю списка объектов из БД определена функция IndexHandler. В ней с помощью метода database.Query
выполняется запрос "select * from productdb.Products", который извлекает все объекты из таблицы. Затем из полученного набора создается массив структур Product,
который затем передается в шаблон index.html (код шаблона приведен ниже).
В функции main открываем подключение с базой данных с помощью функции sql.Open
:
db, err := sql.Open("mysql", "root:password@/productdb")
Этой функции в качестве первого параметра передается название драйвера - "mysql". Второй параметр представляет настройки подключения, где
root
- название пользователя в MySQL, password - пароль этого пользователя (как правило тот, который устанавливается при установке MySQL),
и productdb - название базы данных. Соответственно в каждом конкретном случае пароль может отличаться.
После открытия подключения устанавливается значение переменной database.
database = db
И далее функция IndexHandler устанавливается в качестве обработчика запросов по корневому адресу:
http.HandleFunc("/", IndexHandler)
Теперь определим в проекте папку templates, а в ней создадим новый файл index.html, который будет представлять шаблон для вывода массива объектов и будет иметь следующий код:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Products</title> </head> <body> <table> <thead><th>Id</th><th>Model</th><th>Company</th><th>Price</th></thead> {{range . }} <tr> <td>{{.Id}}</td> <td>{{.Model}}</td> <td>{{.Company}}</td> <td>{{.Price}}</td> </tr> {{end}} </table> </body> </html>
В итоге после запуска проекта и обращения к корню сайта будет открыто подключение к базе данных, приложение получит все необходимые данные из бд и передаст их в шаблон: