Golang - Mysql연결, 책관리 시스템

Lumi·2022년 2월 22일
0

Golang

목록 보기
34/38
post-thumbnail

🔥 개요

전에 시도해보고자 했던 3티어 아키텍처에 대해서 학습을 하였습니다.

원래 Nosql이 좀더 익숙하지만 mySql로도 작업을 해 보았고

생각보다 많이 어렵고 이해가 안가는 부분이 많이 남는것 같습니다;;

youtube를 참고하여 진행을 하였고 이해가 되는 부분에 한에서 작성을 해 보았습니다.

  • 원래 그런지 모르겠지만 스키마를 따로 작성하지 않았습니다;;

🔨 참고 링크, 사용한 패키지

GORM - https://gorm.io/ko_KR/docs/index.html

Google, Youtube등등

go get github.com/gorilla/mux
- 서버를 여는데에 도움을 주는 패키지

go get github.com/jinzhu/gorm/dialects/mysql
- DB에 연결하기 위해 Driver을 불러 옵니다.

go get github.com/jinzhu/gorm
- DB인스턴스를 할당하기 위해 불러옵니다.
- 이 부분은 확실하지 않습니다. 실질적으로 사용하는 패키지라서 인스턴스를 활용한다고 이해하였습니다.

🔨 기본 구조

src (나의 프로젝트 폴더)
├── main.go
└── config
	 └── app.go
└── controllers
	 └── book-controllers.go
└── models
	 └── book.go
└── routes
	 └── bookstore-routes.go
└── utils
	 └── utils.go

기본 구조는 이와 같습니다.

main.go를 통해서 실행이 되며 필요한 함수는 폴더에 담아 정리를 해놓은 상태입니다.

🔨 app.go

이 부분에서는 db연결을 지원하고 있습니다.

package config

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

var (
	db *gorm.DB
)

func Connect() {
	d, err := gorm.Open("mysql", "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	db = d
}

func GetDB() *gorm.DB {
	return db
}

일단 기본적으로 불러와야하는 패키지들을 불러옵니다.

  • github.com/jinzhu/gorm는 인스턴스 할당을 위해 불러옵니다.
  • github.com/jinzhu/gorm/dialects/mysql 단순히 드라이버 이기 떄문에 사용하지 않을 것이며 이러한 부분을 처리하기 위해 _를 선언합니다.
var (
	db *gorm.DB
)
  • mysql에 접근하기 위해 하나의 변수를 선언해 줍니다.

이후 Connect함수를 통해 변수를 초기화 해주고 그후 GetDB함수를 통해 변수에 접근이 가능하게 설정해 줍니다.

gorm.Open

db에 연결을 해주기 위해 옵션들을 설정해 주는 함수 입니다.

gorm에서는 총 4가지의 DB를 지원합니다.

  • MySQL, PostgreSQL, SQLite, SQL Server

안에 들어가는 인자로는 일정한 형태가 있고 이러한 형태는 앞서 적은 링크에서 확인이 가능합니다.

간단하게 설명을 해보자면 mysql이름/비밀번호/tcp주소/db이름 정도는 필수적으로 들어가야 하며 그 이후의 값은 Optional한 부분 입니다.

🔨 routes

Node.js에서와 동일하게 중간 경로를 설정해 주는 부분 입니다.

package routes

import (
	controller "bookStore/controllers"

	"github.com/gorilla/mux"
)

var RegisterBookStoreRoutes = func(router *mux.Router) {
	router.HandleFunc("/book/", controller.CreateBook).Methods("POST")
	router.HandleFunc("/book/", controller.GetBook).Methods("GET")
	router.HandleFunc("/book/{bookId}", controller.GetBookById).Methods("GET")
	router.HandleFunc("/book/{bookId}", controller.UpdateBook).Methods("PUT")
	router.HandleFunc("/book/{bookId}", controller.DeleteBook).Methods("DELETE")
}

이전에 다루어 보았던 것과 동일하게 router설정이 가능하며 후에 maing함수에서 Mux인스턴스를 받아서 실행시킬 함수 입니다.

🔨 Models

controllers에서 다룰 함수들에서 mysql에 연결할 부분을 정의내린 곳 입니다.

package models

import (
	"bookStore/config"

	"github.com/jinzhu/gorm"
)

var db *gorm.DB

type Book struct {
	gorm.Model
	Name        string
	Author      string
	Publication string
}

func init() {
	config.Connect()
	db = config.GetDB()
	db.AutoMigrate(&Book{})
}

func (b *Book) CreateBook() *Book {
	db.NewRecord(b)
	db.Create(&b)
	return b
}

func GetAllBooks() []Book {
	var Books []Book

	db.Find(&Books)

	return Books
}

func GetBookById(Id int64) (*Book, *gorm.DB) {
	var getBook Book

	db := db.Where("Id=?", Id).Find(&getBook)

	return &getBook, db
}

func DeleteBook(ID int64) Book {
	var book Book
	db.Where("ID=?", ID).Delete(book)
	return book
}

기본적으로 Book데이터를 사용해야 하기 떄문에 하나의 구조체를 통해 정의내려 줍니다.

gorm.Model이란 해당 구조체에 ID, CreatedAt, updateAt, DeletedAt을 정의내려 주는 역할을 합니다.

즉 위에 있는 구조체는


type Book struct {
	ID        uint           
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt 
	Name        string
	Author      string
	Publication string
}
  • 이와 동일한 형태 입니다.

init()함수는 처음보는 함수이지만 말 그대로 초기화를 담당하는 함수 입니다.

  • 패키지가 로드될떄 즉 코드가 실행이 될떄 따로 작동시키지 않아도 자동으로 작동을 시키는 함수를 의미합니다.

해당 함수내에서는 config.Connect를 통해서 DB를 연결하고 변수에 할당해 주게 됩니다.

  • 그후 마이그레이션을 통해서 mysql에 해당 구조체를 적용시켜 줍니다.

여기 까지 작업이 끝났다면 저희는 db라는 변수를 통해서 mysql에 있는 데이터에 접근이 가능해 집니다.

CreateBook

이 함수 같은경우에는 단순히 새로운 Book데이터를 만들어 주는 역할을 합니다.

기본적으로 Create함수는 새로운 데이터를 만들어 주는 역할을 하고

NewRecord함수는 단순히 주요키가 있는지를 확인한뒤에 데이터를 집어 넣는 역할을 합니다.

아직 NewRecord부분에 대해서 확실하게 이해를 하고 있지 못하기 떄문에

이 링크에 따르면 create일종의 Insert와 동일하게 작동을 하지만 NewRecord는 Db에 영향을 주지 않는 다고 합니다.

단순히 Boolean값을 주며 주요키의 유무에 따라서 값이 주어지는 것 같습니다.

그러기 떄문에 데이터가 기존에 있는지를 거증하는 역할을 한다고 생각을 하여 코드를 살짝 수정해보면

func (b *Book) CreateBook() *Book {
	bool := db.NewRecord(b)
	if bool == true{
		db.Create(&b)
	}
	return b
}

이런식으로 수정하여 사용을 하였습니다.

GetAllBooks

함수이름에서 알수 있듯이 모든 데이터를 가져오는 역할을 하고 코드 또한 간단하기 떄문에 넘어가도록 하겠습니다.

GetBookById

특정 값에 해당하는 값을 가져오는 역할을 합니다.

  • select * from 스키마 where Id = id와 같은 방식으로 작동을 합니다.

DeleteBook

특정 값에 해당하는 값을 지우는 역할을 합니다.

🔨 utils.go

이 부분에서도 처음사용해보는 패키지가 있어서 이러한 부분에 대해서도 다루어 보았습니다.

package utils

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
)

func ParseBody(r *http.Request, X interface{}) {
	if body, err := ioutil.ReadAll(r.Body); err == nil {
		if err := json.Unmarshal([]byte(body), X); err != nil {
			return
		}
	}
}

음 기본적으로 Post요청에서 사용할 함수 입니다.

일단 기본적으로 들어오는 r.Body의 데이터를 읽게 됩니다.

  • 단순하게 에러가 발생하기 이전까지 읽어주는 역할을 합니다.

만약 에러가 있다면 json.Unmarshal을 사용하여 json데이터를 []byte로 바꿔준다?? 정도로 이해를 하였습니다.

  • 이 부분에서도 아직은 많이 부족한것 같습니다;;

이전에는

err := json.NewDecoder(r.Body).Decode(&data)
	if err != nil {
		log.Fatal(err)
		rd.JSON(w, http.StatusBadRequest, false)
	}

와 같은 방식으로 처리를 했었는데 이 부분에 대해서도 둘의 차이점을 아직 인지하지 못하는 시점입니다;;

🔨 Controller

이 부분은 Youtube에서 다루어 보았습니다.

📖 Github

https://github.com/jjimgo/golang_mysql_bookStore

profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글