준비된 문 사용하기
준비된 문 사용하기 (Using prepared statements)
반복해서 쓰려고 준비된 문(prepared statement)을 정의할 수 있어요. 코드가 데이터베이스 연산을 수행할 때마다 문을 다시 만드는 오버헤드를 피할 수 있어서, 코드가 조금 더 빠르게 동작하는 데 도움이 됩니다.
출처: Go 공식 문서
참고: 준비된 문 안의 파라미터 자리 표시자는 사용하는 DBMS와 드라이버에 따라 달라져요. 예를 들어 Postgres용 pq 드라이버는 ? 대신 $1 같은 자리 표시자를 요구합니다.
준비된 문이란?
준비된 문은 DBMS가 파싱해서 저장해 두는 SQL입니다. 대개 자리 표시자를 포함하지만 실제 파라미터 값은 없어요. 나중에 그 문을 파라미터 값 집합과 함께 실행할 수 있습니다.
준비된 문 사용 방법
같은 SQL을 반복해서 실행할 것 같다면, sql.Stmt로 SQL 문을 미리 준비해 두고 필요할 때마다 실행할 수 있어요.
다음 예시는 데이터베이스에서 특정 앨범을 선택하는 준비된 문을 만듭니다. DB.Prepare는 주어진 SQL 텍스트에 대한 준비된 문을 나타내는 sql.Stmt를 반환해요. SQL 문의 파라미터를 Stmt.Exec, Stmt.QueryRow, Stmt.Query에 넘겨 문을 실행할 수 있습니다.
// AlbumByID retrieves the specified album.
func AlbumByID(id int) (Album, error) {
// Define a prepared statement. You'd typically define the statement
// elsewhere and save it for use in functions such as this one.
stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
var album Album
// Execute the prepared statement, passing in an id value for the
// parameter whose placeholder is ?
err := stmt.QueryRow(id).Scan(&album.ID, &album.Title, &album.Artist, &album.Price, &album.Quantity)
if err != nil {
if err == sql.ErrNoRows {
// Handle the case of no rows returned.
}
return album, err
}
return album, nil
}
준비된 문의 동작
준비된 sql.Stmt는 문을 호출하기 위한 일반적인 Exec, QueryRow, Query 메서드를 제공합니다. 이 메서드들의 사용법은 Querying for data와 Executing SQL statements that don't return data에서 더 자세히 볼 수 있어요.
다만 sql.Stmt는 이미 미리 설정된 SQL 문을 나타내므로, 그 Exec, QueryRow, Query 메서드는 SQL 텍스트를 생략하고 자리 표시자에 해당하는 SQL 파라미터 값만 받습니다.
sql.Stmt는 어떻게 사용할지에 따라 여러 방식으로 정의할 수 있어요.
DB.Prepare와DB.PrepareContext는DB.Exec와DB.Query처럼, 트랜잭션 밖에서 단독으로 실행할 수 있는 준비된 문을 만듭니다.Tx.Prepare,Tx.PrepareContext,Tx.Stmt,Tx.StmtContext는 특정 트랜잭션 안에서 사용할 준비된 문을 만듭니다.Prepare와PrepareContext는 SQL 텍스트로 문을 정의하고,Stmt와StmtContext는DB.Prepare나DB.PrepareContext의 결과를 사용합니다. 즉, 트랜잭션용이 아닌sql.Stmt를 이 트랜잭션용sql.Stmt로 변환하는 것이죠.Conn.PrepareContext는 예약된 연결을 나타내는sql.Conn에서 준비된 문을 만듭니다.
코드가 문 사용을 마쳤을 때 stmt.Close가 호출되도록 하세요. 이렇게 하면 그 문과 연관된 데이터베이스 리소스(예: 기본 연결)를 해제합니다. 함수의 지역 변수로만 쓰이는 문이라면 defer stmt.Close()로 충분해요.
준비된 문을 만드는 함수
| 함수 | 설명 |
|---|---|
DB.PrepareDB.PrepareContext |
단독으로 실행하거나 Tx.Stmt로 트랜잭션 내부 문으로 변환할 문을 준비합니다. |
Tx.PrepareTx.PrepareContextTx.StmtTx.StmtContext |
특정 트랜잭션에서 사용할 문을 준비합니다. 자세한 내용은 Executing transactions 참고. |
Conn.PrepareContext |
예약된 연결과 함께 사용합니다. 자세한 내용은 Managing connections 참고. |
더 알아보기 (Learn more)
- Querying for data —
QueryRow·Query로 데이터 조회하기 - Executing SQL statements that don't return data — 데이터를 반환하지 않는 문 실행
- Executing transactions — 트랜잭션 실행
database/sql—sql패키지 전체 레퍼런스