Golang database/sql 패키지 삽질기 - 1편 매개변수 표시자
필자는 주로 자바로 개발해 왔는데 최근 Golang으로 개발하면서 데이터베이스를 다룰 일이 생겼다. Golang에서는 자바의 JDBC와 같은 database/sql 패키지를 제공한다.
이 글은 Golang 초심자로서 필자가 database/sql 패키지를 사용하면서 겪었던 삽질기 중 1편으로 매개변수 표시자Parameter Placeholder에 대한 글이다.
- 매개변수 표시자
- SQLite 메모리 데이터베이스
- 커넥션 풀
Unknown column?
아래는 database/sql 패키지를 사용하여 데이터베이스 parent 테이블에서 id가 '1'인 열의 name 컬럼을 조회하는 코드이다. 데이터베이스로는 SQLite를 사용하고 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
package main import ( "database/sql" _ "github.com/mattn/go-sqlite3" "log" ) func main() { db, err := sql.Open("sqlite3", ":memory:") if err != nil { log.Fatal(err) } defer db.Close() // ... var parentName string row := db.QueryRow("SELECT name FROM parent WHERE id = $1", 1) err = row.Scan(&parentName) if err != nil { log.Fatal(err) } fmt.Println(parentName) }
코드를 실행해 보면 잘 동작하는 것을 확인할 수 있다.
이제 같은 코드를 데이터베이스만 MySQL로 변경해서 실행해 보면 Unknown column 오류를 만난다.
1 2 3 4 5 6 7 8 9 10
package main import ( // ... _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:1111@tcp(127.0.0.1:3306)/article") // ... }
왜 같은 코드임에도 불구하고 SQLite는 동작하고 MySQL은 동작하지 않는 걸까? 답은 database/sql 패키지 문서에서 찾을 수 있다.
매개변수 표시자Parameter Placeholder
Golang에서는 Prepared Statement를 사용할 때 SQL문에 '$1'처럼 대체되는 것을 매개변수 표시자라고 한다. 아래 코드는 '$1' 매개변수 표시자에 실제 값 1로 대체하여 SQL을 실행한다.
1
row := db.QueryRow("SELECT name FROM parent WHERE id = $1", 1)
매개변수 표시자는 문법이 있으니... 데이터베이스마다 다르게 써야 한다는 것이다!
결론
매개변수 표시자를 사용할 때에는 사용하는 데이터베이스마다 다르게 써야 한다. 예시 코드에서는 MySQL로 데이터베이스를 변경했기 때문에 매개변수 표시자를 '?'로 써야 한다. 아래와 같이 변경하고 실행하면 오류 없이 잘 동작한다.
1
row := db.QueryRow("SELECT name FROM parent WHERE id = ?", 1)