少し「賢く」なり、ボイラープレートSQLコードの一部を抽象化しようと思いました(sqlxを使用 - https://github.com/jmoiron/sqlx)。アイデアは、結果を処理するための関数ポインターをコードにフィードし、行を生成する SQL 文字列と引数を渡すことです。たまたま、「sqlArgs インターフェイス」のものを削除すれば、コードは正常に機能しますが、「より賢い」形式ではステートメントでエラーが発生します
sql: Exec 引数 $1 を変換しています タイプ: サポートされていないタイプ []interface {}、インターフェイスのスライス
ここに 2 つのバージョンがあります。最初のバージョンではエラーが発生し、2 番目のバージョンでは機能しますが、パラメーター化されていません。
//GetRows (doesn't work)
func GetRows(parseRows func(*sqlx.Rows), sql string, sqlArgs ...interface{}) {
db := sqlx.MustConnect("mysql", ConnString)
defer db.Close()
rows, err := db.Queryx(sql, sqlArgs)
defer rows.Close()
if err != nil {
panic(err)
}
parseRows(rows)
}
//GetRows ... (works, but doesn't allow parameterization)
func GetRows(fp func(*sqlx.Rows), sql string) {
db := sqlx.MustConnect("mysql", ConnString)
defer db.Close()
rows, err := db.Queryx(sql)
defer rows.Close()
if err != nil {
panic(err)
}
fp(rows)
}
アイデアは、コードを次のように呼び出すことです。
func getUser(userID string) User {
var users []*User
parseRows := func(rows *sqlx.Rows) {
for rows.Next() {
var u User
err := rows.StructScan(&u)
if err != nil {
panic(err)
}
users = append(users, u)
}
}
sql := "SELECT * FROM users WHERE userid = ?;"
sqlutils.GetRows(parseRows, sql, userID)
if len(users) == 1{
return users[0]
}
return User{}
}
私のコードは実際には呼び出しから呼び出しへと userID を通過するのではなく、SQL パッケージが処理できない []interface{} を通過すると思います。しかし、それについてはよくわかりません。いずれにせよ、このアイデアを実現する方法はありますか? ありがとう。