golang
有若干常用orm
庫, 如gorm, sqlx等, 在這裏總結一下在生產中遇到的問題:
sqlx:
- 1)對於一些經過中間件處理的mysql數據庫,即直接訪問的實體不是
mysql
本身, 對於這類數據庫實體, 有可能不支持prepare
命令類型。
PREPARE stmt FROM `SELECT * FROM xxx WHERE report_time>=? AND report_time<?`;
ERROR 1149 (42000): 1.1-7: syntax error, unexpected NAME
而sqlx
往往會在大部分接口處實現prepare
命令, 導致在orm發出的普通query查詢等語句中, 往往會先運行prepare
命令, 如下數據庫支持prepare
,其日誌:
| 2019-09-11 15:51:42.080353 | root[root] @ [172.24.73.128] | 1473 | 0 | Prepare | SELECT * FROM task_config WHERE task_id = ? |
| 2019-09-11 15:51:42.080373 | root[root] @ [172.24.73.128] | 1473 | 0 | Execute | SELECT * FROM task_config WHERE task_id = 202 |
因此,對於不支持prepare
的mysql
實體,必須使用此鏈接辦法,才能避免出現數據庫查詢報錯, 報錯類型多爲針對prepare
的?
, 如:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? ......
- 2)
sqlx
支持unsafa
, 其用於用戶只希望將部分結果存於結構體中:
udb := db.Unsafe()
err = udb.Get(&p, "SELECT * FROM person, place LIMIT 1;")
但unsafe
只作用於以上將查詢結果對象作爲參數傳入的情況, 對於Query
等不支持, 這時候需要用Queryx
, 以下示例用於總結1
,2
兩點:
query := fmt.Sprintf("SELECT * FROM xxx WHERE xxx BETWEEN %v AND %v", start, end)
udb := db.Unsafe()
rows, err := udb.Queryx(query)
switch {
case err == sql.ErrNoRows:
return nil, nil
case err != nil:
return nil, err
}
var ms []Ms
if rows != nil {
err = sqlx.StructScan(rows, &ms)
rows.Close()
}