【#44 エンジニア転職学習】GinTutorialのWebApp改造　DB管理追加（GORM）

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

GoのフレームワークであるGinを中心に、
webアプリ開発学習をしていきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
GinのTutorialで作成したAPIを改造して、簡素なWebアプリを作成しようと思います。
本日はアプリ内データのMySQL管理機能を追加しました。

* **GORMを使用したMySQLデータ管理　←Topics!!**


# GORMを使用したMySQLデータ管理
Ginのtutorialではメモリ上でのデータ記録だったため、サーバを切断すると変更したデータが消えてしまいました。
この問題を解決するために、「MySQL」およびGoのORMである「GORM」を導入していきます。

##### WebApp改造で追加する機能等
* APIのPUTとDELETE
* **albumデータのDB管理**
* ブラウザ上での表示（HTMLから）
* キーワード一致のGET

##### タスク
1. PUTとDELETEのコード記述
1. **GORMの基礎学習とMySQLのDBテーブル作成**
1. **GORMを使用したAPI部分とDBの連携**
1. フロントエンド部分のインターフェース作成、Goと連携
1. キーワード一致GET機能の追加、実装

### MySQL・GORMを導入したコード
gorm.Openの第二引数MySQLDSN部分が理解できず色々と調べました。
結局MySQL内でuser追加・編集権限追加をして、そのuserとpasswordを使用することでMySQLに接続できました。
ただ下記のコードでは、テーブルのマイグレーションとgorm.Model部分の記録はできるのですが、
それ以外の自分で設定したstruct部分が空で記録されてしまいます。
（今回はとりあえず先に進めます）
~~~albumdb.go
package models

import (
	"github.com/jinzhu/gorm"
)

// Connstruct Album struct
type Album struct {
	gorm.Model
	Title  string  `json:"title"`
	Artist string  `json:"artist"`
	Price  float64 `json:"price"`
}
~~~
~~~base.go
package models

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

//Initialized DB
func DbInit() *gorm.DB {
	var dsn = "user:password@/dbname?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open("mysql", dsn)
	if err != nil {
		panic("failed connecting DB")
	}
	db.LogMode(true)
	db.AutoMigrate(&Album{})
	return db
}
~~~
~~~webserver.go
package controllers

import (
	"ginapp-albums/app/models"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
)

type AlbumHandler struct {
	Db *gorm.DB
}

//getAlbums responds with the list of all albums as JSON
func (h *AlbumHandler) GetAlbums(c *gin.Context) {
	var albums []models.Album
	h.Db.Find(&albums)
	c.IndentedJSON(http.StatusOK, albums)
}

//postAlbums adds an album from GetPostForm received in the request body.
func (h *AlbumHandler) PostAlbums(c *gin.Context) {
	title, _ := c.GetPostForm("title")
	artist, _ := c.GetPostForm("artist")
	price, _ := c.GetPostForm("price")
	floatprice, _ := strconv.ParseFloat(price, 64)
	h.Db.Create(&models.Album{Title: title, Artist: artist, Price: floatprice})

	c.Redirect(http.StatusMovedPermanently, "/albums")
}

// getAlbumByID locates the album whose ID value matches the id
// parameter sent by the client, then returns that album as a response.
func (h *AlbumHandler) GetAlbumByID(c *gin.Context) {
	id := c.Param("id")
	album := models.Album{}

	h.Db.First(&album, id)
	h.Db.Find(&album)
	c.IndentedJSON(http.StatusOK, album)
}

//UpdateAlbumByID update an album from GetPostForm received in the request body.
func (h *AlbumHandler) UpdateAlbumByID(c *gin.Context) {
	id := c.Param("id")
	album := models.Album{}

	title, _ := c.GetPostForm("title")
	artist, _ := c.GetPostForm("aritst")
	price, _ := c.GetPostForm("price")
	floatprice, _ := strconv.ParseFloat(price, 64)

	h.Db.First(&album, id)
	album.Title = title
	album.Artist = artist
	album.Price = floatprice
	h.Db.Save(&album)
	c.Redirect(http.StatusMovedPermanently, "/albums")
}

//DleteAlbumByID delete an album form JSON received in the request URI.
func (h *AlbumHandler) DeleteAlbumByID(c *gin.Context) {
	id := c.Param("id")
	album := models.Album{}

	h.Db.First(&album, id)
	h.Db.Delete(&album)
	c.Redirect(http.StatusMovedPermanently, "/albums")
}

~~~

##### 使用している教材はこちら↓


https://go.dev/doc/tutorial/web-service-gin


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。