Go orm在實際生產中遇到的若干問題

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 |

因此,對於不支持preparemysql實體,必須使用此鏈接辦法,才能避免出現數據庫查詢報錯, 報錯類型多爲針對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, 以下示例用於總結12兩點:

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()
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章