Где воздух гор - там тишина снегов, молчание камней и дремлет сила

Программирование Web

Как сделать web проект CRUD с помощью Golang

2020-01-10 11:25:31







1. Создадим таблицу базы данных проекта:

CREATE TABLE `users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci



2. Далее создаем основной файл «main.go» . В первой строке указываем, что наш файл является исполняемым, а не библиотекой. Для этого мы пишем ключевую фразу «package main» . Затем мы подключаем необходимые стандартные библиотеки, которые нам пригодятся в этом проекте. Это библиотек для работы с базой данных "database/sql", логированием "log", для работы с сетью "net/http", поддержка работы с текстовыми документами и шаблонами "text/template" и также драйвер mysql « _ github.com/go-sql-driver/mysql"


package main

import (
"database/sql"
"log"
"net/http"
"text/template"
_ "github.com/go-sql-driver/mysql"
)




Затем нам нужно создать структуру данных, которая будет взаимодействовать с нашей базой данных:



type Users struct {
Id int
Name string
Email string
}



Дальше мы будем создавать методы, которые у нас будут основой нашего проекта. Первый метод будет устанавливать соединение с базой данных:

func dbConn() (db *sql.DB) {
dbDriver := "mysql"
dbUser := "root"
dbPass := "123"
dbName := "search_dev"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
if err != nil {
panic(err.Error())
}
return db
}

Данный метод служит для установления соединения с базой данных, возвращает вновь созданный объект базы.



Следующий метод будет выводить список всех пользователей. Сначала мы вызываем вышеупомянутый метод « dbConn()». Затем мы создаем запрос к базе. После мы заполняем структуру полученными даными, загружаем их в файл шаблона и разрываем соединение с базой.


func Index(w http.ResponseWriter, r *http.Request) {
db := dbConn()
selDB, err := db.Query("SELECT * FROM users ORDER BY id DESC")
if err != nil {
panic(err.Error())
}
usr := User{}
res := []User{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
res = append(res, usr)
}
tmpl.ExecuteTemplate(w, "Index", res)
defer db.Close()
}

Следующая функция показывает отдельно выбранную запись. Получаем мы ее с помощью http.Request, который получает «id» выбранной записи.Дальше все точно так же: заполняем струтуру данными и выводим их в шаблон.

func Show(w http.ResponseWriter, r *http.Request) {
db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM users WHERE id=?", nId)
if err != nil {
panic(err.Error())
}
usr := User{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
}
tmpl.ExecuteTemplate(w, "Show", emp)
defer db.Close()
}

Новый метод самый короткий. Он загружает шаблон формы создания новой записи:

func New(w http.ResponseWriter, r *http.Request) {
tmpl.ExecuteTemplate(w, "New", nil)
}

Теперь нам необходимо сделать метод, который будет получать и загружать данные в форму для редактирования с помощью «id»:

func Edit(w http.ResponseWriter, r *http.Request) {
db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM users WHERE id=?", nId)
if err != nil {
panic(err.Error())
}

usr := User{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
}
tmpl.ExecuteTemplate(w, "Edit", emp)
defer db.Close()
}


Следующий метод используется для вставки данных в таблицу базы. Он получает данные из формы, помещают в базу и при этом мы создаем запись в логе:



func Insert(w http.ResponseWriter, r *http.Request) {
db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
email := r.FormValue("email")
insForm, err := db.Prepare("INSERT INTO users(name, email) VALUES(?,?)")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, email)
log.Println("INSERT: Name: " + name + " | Email: " + email)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}


Этот метод служит обработчиком формы редактирования. Опять же, используем логированием.

func Update(w http.ResponseWriter, r *http.Request) {
db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
email := r.FormValue("email")
id := r.FormValue("uid")
insForm, err := db.Prepare("UPDATE users SET name=?, email=? WHERE id=?")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, email, id)
log.Println("UPDATE: Name: " + name + " | Email: " + email)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}




Последний метод удаляет избранную запись из базы данных:


func Delete(w http.ResponseWriter, r *http.Request) {
db := dbConn()
usr := r.URL.Query().Get("id")
delForm, err := db.Prepare("DELETE FROM Users WHERE id=?")
if err != nil {
panic(err.Error())
}
delForm.Exec(usr)
log.Println("Record was deleted ok")
defer db.Close()
http.Redirect(w, r, "/", 301)
}


И наконец, метод «main()» исполняет функции роутера.


func main() {
log.Println("server started on: http://localhost:8080")
http.HandleFunc("/", Index)
http.HandleFunc("/show", Show)
http.HandleFunc("/new", New)
http.HandleFunc("/edit", Edit)
http.HandleFunc("/insert", Insert)
http.HandleFunc("/update", Update)
http.HandleFunc("/delete", Delete)
http.ListenAndServe(":8080", nil)
}


Последнее, что осталось, это добавить файлы шаблонов.

Файл Index.tpl:

{{ define "Index" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2> Registered </h2>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Email</td>
<td>View</td>
<td>Edit</td>
<td>Delete</td>
</tr>
</thead>
<tbody>
{{ range . }}
<tr>
<td>{{ .Id }}</td>
<td> {{ .Name }} </td>
<td>{{ .Email }} </td>
<td><a href="/show?id={{ .Id }}">View</a></td>
<td><a href="/edit?id={{ .Id }}">Edit</a></td>
<td><a href="/delete?id={{ .Id }}">Delete</a><td>
</tr>
{{ end }}
</tbody>
</table>
{{ template "Footer" }}
{{ end }}

Файл Menu.tpl:


{{ define "Menu" }}
<a href="/">Index</a> |
<a href="/new">NEW</a>
{{ end }}

Файл Header.tpl:

{{ define "Header" }}
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Golang CRUD</title>
<meta charset="UTF-8" />
</head>
<body>
<h1>Golang CRUD</h1>
{{ end }}


Файл Footer.tpl:

{{ define "Footer" }}
</body>
</html>
{{ end }}

Файл New.tpl:

{{ define "New" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2>New Item</h2>
<form method="POST" action="insert">
<label> Name </label><input type="text" name="name" /><br />
<label> Email </label><input type="text" name="email" /><br />
<input type="submit" value="Save user" />
</form>
{{ template "Footer" }}
{{ end }}

Файл Edit.tpl:

{{ define "Edit" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2>Edit Item</h2>
<form method="POST" action="update">
<input type="hidden" name="uid" value="{{ .Id }}" />
<label> Name </label><input type="text" name="name" value="{{ .Name }}" /><br />
<label> Email </label><input type="text" name="email" value="{{ .Email }}" /><br />
<input type="submit" value="Save user" />
</form><br />
{{ template "Footer" }}
{{ end }}


Файл Show.tpl:

{{ define "Show" }}
{{ template "Header" }}
{{ template "Menu" }}
<h2> Register {{ .Id }} </h2>
<p>Name: {{ .Name }}</p>
<p>Email: {{ .Email }}</p><br /> <a href="/edit?id={{ .Id }}">Edit</a></p>
{{ template "Footer" }}
{{ end }}


Полный код проекта:


package main

import (
"database/sql"
"log"
"net/http"
"text/template"
_ "github.com/go-sql-driver/mysql"
)



type Users struct {
Id int
Name string
Email string
}


var tmpl = template.Must(template.ParseGlob("crud/*"))


func dbConn() (db *sql.DB) {
dbDriver := "mysql"
dbUser := "dbuser"
dbPass := "dbpwd"
dbName := "database"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
if err != nil {
panic(err.Error())
}
return db
}



func Index(w http.ResponseWriter, r *http.Request) {
db := dbConn()
selDB, err := db.Query("SELECT * FROM users ORDER BY id DESC")
if err != nil {
panic(err.Error())
}
usr := User{}
res := []User{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
res = append(res, usr)
}
tmpl.ExecuteTemplate(w, "Index", res)
defer db.Close()
}

func Show(w http.ResponseWriter, r *http.Request) {
db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM users WHERE id=?", nId)
if err != nil {
panic(err.Error())
}
usr := User{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
}
tmpl.ExecuteTemplate(w, "Show", emp)
defer db.Close()
}

func New(w http.ResponseWriter, r *http.Request) {
tmpl.ExecuteTemplate(w, "New", nil)
}

func Edit(w http.ResponseWriter, r *http.Request) {
db := dbConn()
nId := r.URL.Query().Get("id")
selDB, err := db.Query("SELECT * FROM users WHERE id=?", nId)
if err != nil {
panic(err.Error())
}
emp := Employee{}
for selDB.Next() {
var id int
var name, email string
err = selDB.Scan(&id, &name, &email)
if err != nil {
panic(err.Error())
}
usr.Id = id
usr.Name = name
usr.Email = email
}
tmpl.ExecuteTemplate(w, "Edit", emp)
defer db.Close()
}

func Insert(w http.ResponseWriter, r *http.Request) {
db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
email := r.FormValue("email")
insForm, err := db.Prepare("INSERT INTO users(name, email) VALUES(?,?)")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, email)
log.Println("INSERT: Name: " + name + " | Email: " + email)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func Update(w http.ResponseWriter, r *http.Request) {
db := dbConn()
if r.Method == "POST" {
name := r.FormValue("name")
email := r.FormValue("email")
id := r.FormValue("uid")
insForm, err := db.Prepare("UPDATE users SET name=?, email=? WHERE id=?")
if err != nil {
panic(err.Error())
}
insForm.Exec(name, email, id)
log.Println("UPDATE: Name: " + name + " | Email: " + email)
}
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func Delete(w http.ResponseWriter, r *http.Request) {
db := dbConn()
usr := r.URL.Query().Get("id")
delForm, err := db.Prepare("DELETE FROM Users WHERE id=?")
if err != nil {
panic(err.Error())
}
delForm.Exec(usr)
log.Println("DELETE")
defer db.Close()
http.Redirect(w, r, "/", 301)
}

func main() {
log.Println("Server started on: http://localhost:8080")
http.HandleFunc("/", Index)
http.HandleFunc("/show", Show)
http.HandleFunc("/new", New)
http.HandleFunc("/edit", Edit)
http.HandleFunc("/insert", Insert)
http.HandleFunc("/update", Update)
http.HandleFunc("/delete", Delete)
http.ListenAndServe(":8080", nil)
}


На этом все. Как видите, все просто.

Здесь нет комментариев


Новый комментарий:
























Яндекс.Метрика