이번에는 fiber 프레임워크에 MySQL 을 붙여서 동작시켜보자. 윈도우에 MySQL 8.4.x 설치하기 을 참고하여 MySQL을 설치하기 바랍니다. 이 과정을 거치면, DB(test_db)를 만들고, 테이블(TB_ADMIN)도 만들고, 샘플 데이터도 넣게 됩니다.
스토어드 프로시저도 하나 만들어보겠습니다.
DELIMITER $$
CREATE PROCEDURE SP_L_ADMIN()
BEGIN
SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN;
END $$
DELIMITER;
DB에 접속해서 해당 스토어드 프로시져 호출이 잘 되는지도 확인해 봅시다.
CALL SP_L_ADMIN();
여기까지 해서, Database 쪽은 준비가 되었습니다. 이제, fiber 에서 DB 연결부터 조회하는 것까지 해봅시다. ORM 같은 것은 사용하지 않고, 쌩 SQL과 Stored Procedure 를 이용하는 법을 알아봅니다. MySQL 사용을 위해서 github.com/go-sql-driver/mysql 모듈을 사용하겠습니다.
우선 .env 파일에 DB관련 항목들을 추가해줍니다.
PORT = 8000
TEST_DB_CONFIG__HOST = localhost
TEST_DB_CONFIG__PORT = 3306
TEST_DB_CONFIG__DBNAME = test_db
TEST_DB_CONFIG__USERNAME = test_user
TEST_DB_CONFIG__PASSWORD = test123
TEST_DB_CONFIG__MAX_IDLE_CONNS = 10
TEST_DB_CONFIG__MAX_OPEN_CONNS = 10
이제, model 폴더를 만들고, 그 안에 mysql.go 파일을 생성하여 아래와 같이 작성합니다.
package model
import (
"database/sql"
"fmt"
"log"
"os"
"strconv"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/joho/godotenv"
)
var DBConn *sql.DB
func Init() {
var err error
// .env 파일 로드
if err = godotenv.Load(); err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
// 환경 변수에서 DB정보 가져오기
HOST := os.Getenv("TEST_DB_CONFIG__HOST")
PORT := os.Getenv("TEST_DB_CONFIG__PORT")
DBNAME := os.Getenv("TEST_DB_CONFIG__DBNAME")
USERNAME := os.Getenv("TEST_DB_CONFIG__USERNAME")
PASSWORD := os.Getenv("TEST_DB_CONFIG__PASSWORD")
MAX_IDLE_CONNS := os.Getenv("TEST_DB_CONFIG__MAX_IDLE_CONNS")
MAX_OPEN_CONNS := os.Getenv("TEST_DB_CONFIG__MAX_OPEN_CONNS")
DSN := USERNAME + ":" + PASSWORD + "@tcp(" + HOST + ":" + PORT + ")/" + DBNAME
DBConn, _ = sql.Open("mysql", DSN)
// Connection Pool
_MAX_IDLE_CONNS, _ := strconv.Atoi(MAX_IDLE_CONNS)
_MAX_OPEN_CONNS, _ := strconv.Atoi(MAX_OPEN_CONNS)
DBConn.SetMaxIdleConns(_MAX_IDLE_CONNS)
DBConn.SetMaxOpenConns(_MAX_OPEN_CONNS)
DBConn.SetConnMaxLifetime(time.Hour)
}
func GetAdminList() []map[string]interface{} {
var admin_no int
var login_id string
var passwd string
var nick string
var email string
result_slice := []map[string]interface{}{}
rows, err := DBConn.Query("SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN")
if err != nil {
fmt.Println(err)
}
if rows != nil {
defer rows.Close()
}
for rows.Next() {
result_map := map[string]interface{}{}
err := rows.Scan(&admin_no, &login_id, &passwd, &nick, &email)
if err != nil {
fmt.Println(err)
}
result_map["ADMIN_NO"] = admin_no
result_map["LOGIN_ID"] = login_id
result_map["PASSWD"] = passwd
result_map["NICK"] = nick
result_map["EMAIL"] = email
result_slice = append(result_slice, result_map)
}
return result_slice
}
소스에 추가한 mysql 모듈을 설치하기 위해서 go mod tidy를 실행해줍니다.
그리고, main.go 도 DB연결할 수 있도록 수정해줍니다.
package main
import (
"log"
"os"
"github.com/joho/godotenv"
"fapi/model"
"fapi/route"
)
func main() {
// .env 파일 로드
if err := godotenv.Load(); err != nil {
log.Fatalf("Error loading .env file: %v", err)
}
// 환경 변수에서 포트 가져오기
port := os.Getenv("PORT")
if port == "" {
log.Fatal("PORT is not set in the .env file")
}
model.Init()
app := route.Router()
log.Fatal(app.Listen("0.0.0.0:" + port))
}
svc1.go 의 Req1 함수도 수정해줍니다.
package svc1
import (
"fapi/model"
"github.com/gofiber/fiber/v2"
)
func Req1(c *fiber.Ctx) error {
result := model.GetAdminList()
return c.JSON(result)
}
func Req2(c *fiber.Ctx) error {
return c.JSON(&fiber.Map{"SVC1": "REQ2"})
}
웹브라우저에서 http://localhost:8000/svc1/req1 을 호출하면 DB의 내용을 보여줄 거에요.
이제, Stored Procedure 도 적용해보겠습니다. GetAdminList 함수에서 DBConn.Query 부분을 다음처럼 수정합니다.
// rows, err := DBConn.Query("SELECT ADMIN_NO, LOGIN_ID, PASSWD, NICK, EMAIL FROM TB_ADMIN")
rows, err := DBConn.Query("CALL SP_L_ADMIN()")
그리고, 실행하면, 역시 JSON으로 DB내용이 잘 출력 될 거에요. 여기까지 MySQL DB연결하는 방법을 알아보았습니다. 이 외에 인증이라던가 여러가지 작업들을 각자의 입맛에 맞게 추가해보도록 하면 되겠습니다.