Go lang 에서 Mysql 연동하기
728x90
golang 에서 mysql 드라이버를 사용하기위해 라이브러리를 사용합니다.
http://github.com/go-sql-driver/mysql
고객 정보를 조회하는 간단한 예제를 만들어 보겠습니다.
먼저 고객에 대한 구조체 와 고객 정보가 담긴 Repository 인터페이스를 만듭니다.
package domain
type Customer struct {
Id string
Name string
City string
Zipcode string
DateofBirth string
Status string
}
type CustomerRepository interface {
FindAll() ([]Customer, error)
}
CustomerRepository 라는 인터페이스 대신 mock 객체를 만들어 test 테스트를 할수도 있습니다.
Golang 에서는 class 와 상속은 없지만 덕타이핑이 가능하도록 리시버 라는 기능을 제공합니다.
package domain
import (
"database/sql"
"log"
"time"
_ "github.com/go-sql-driver/mysql"
)
type CustomerRepositoryDb struct {
client *sql.DB
}
func (d CustomerRepositoryDb) FindAll() ([]Customer, error) {
findAllSql := "select customer_id, name, city, zipcode, date_of_birth, status from customers"
rows, err := d.client.Query(findAllSql)
if err != nil {
log.Println("Error while querying customer table " + err.Error())
return nil, err
}
customers := make([]Customer, 0)
for rows.Next() {
var c Customer
err := rows.Scan(&c.Id, &c.Name, &c.City, &c.Zipcode, &c.DateofBirth, &c.Status)
if err != nil {
log.Println("Error while scanning customer " + err.Error())
return nil, err
}
customers = append(customers, c)
}
return customers, nil
}
func NewCustomerRepositoryDb() CustomerRepositoryDb {
client, err := sql.Open("mysql", "user_id:user_password@tcp(localhost:3306)/database_name")
if err != nil {
panic(err)
}
// See "Important settings" section.
client.SetConnMaxLifetime(time.Minute * 3)
client.SetMaxOpenConns(10)
client.SetMaxIdleConns(10)
return CustomerRepositoryDb{client}
}
go lang에 익숙하지 않으신분들은 구조체 타입을 변수로 선언하여 rows.Next() 를 통해 한줄씩 Scan 하는 방식에 대해서 낯설수도 있을거 같네요 ㅎ
go lang 은 또 예외문을 따로 명시 할수 없어서 에러 처리가 중요합니다.
app/handlers.go
package app
import (
"bangking/service"
"encoding/json"
"net/http"
)
type Customer struct {
Name string `json:"full_name"`
City string `json:"city"`
Zipcode string `json:"zip_code"`
}
type CustomerHandlers struct {
service service.CustomerService
}
func (ch *CustomerHandlers) getAllCustomer(writer http.ResponseWriter, request *http.Request) {
customers, _ := ch.service.GetAllCustomer()
// fprint 와 비슷한 함수
// writer 를 전달하고 encode 함수를 호출하고 모든 고객을 json 형식으로 인코딩 하도록 요청
// 그러나 헤더로 이동하여 콘텐츠 유형을 보면 일반 텍스트로 표시 됩니다.
// 따라서 이 응답은 JSON 처럼 보이지만 실제로는 JSON 이 아니므로 올바른 내용을 설정해야 합니다.
writer.Header().Add("Content-Type", "application/json")
json.NewEncoder(writer).Encode(customers)
}
핸들러에서 모든 고객을 가져오는 리시버를 구현합니다.
app/app.go
package app
import (
"bangking/domain"
"bangking/service"
"log"
"net/http"
"github.com/gorilla/mux"
)
func Start() {
router := mux.NewRouter()
// wiring
//ch := CustomerHandlers{service.NewCustomerService(domain.NewCustomerRepositoryStub())}
ch := CustomerHandlers{service.NewCustomerService(domain.NewCustomerRepositoryDb())}
// define routes
router.HandleFunc("/customers", ch.getAllCustomer).Methods(http.MethodGet)
// starting server
// Listen And serve 는 요류를 반환하고 이를 log Fatal 로 래핑해야 합니다.
// 서버를 시작하는 동안 오류가 발생했는지 알수 있습니다.
log.Fatal(http.ListenAndServe("localhost:8080", router))
}
메인 App에서 핸들러를 등록하고 router 를 통해 GET 메서드로 등록합니다.
main.go
package main
import "bangking/app"
func main() {
app.Start()
}
database 에 더미 데이터를 채워넣었습니다.
insomnia 를 통해 호출한 결과
데이터가 잘 조회 되었네요 !!
golang 에 입문한지 1주일 정도 되어가는데 평소에 파이썬과 c++ 를 가장 좋아했다보니 그 둘을 섞어 놓은 듯한 기분이 들면서 재밌는 언어라는 생각이 드네요 아직은 golang 을 쓰는 기업들이 많이 없지만 더 발전 했으면 좋겠습니다 !! ㅎ
728x90
'Go' 카테고리의 다른 글
Go - 구조화된 로그 남기기 (0) | 2021.09.24 |
---|---|
Golang 으로 맛보는 TDD(테스트 주도 개발) (0) | 2021.09.15 |
구조체 슬라이스 정렬 (0) | 2021.09.07 |
Go - 스택 메모리와 힙메모리 (0) | 2021.09.05 |
번아웃 탈출을 위한 새로운 언어 Go 배워보기 (0) | 2021.09.05 |
댓글
이 글 공유하기
다른 글
-
Go - 구조화된 로그 남기기
Go - 구조화된 로그 남기기
2021.09.24 -
Golang 으로 맛보는 TDD(테스트 주도 개발)
Golang 으로 맛보는 TDD(테스트 주도 개발)
2021.09.15 -
구조체 슬라이스 정렬
구조체 슬라이스 정렬
2021.09.07 -
Go - 스택 메모리와 힙메모리
Go - 스택 메모리와 힙메모리
2021.09.05