我想从MySQL数据库中检索一个应用程序I数组。我使用了http://go-database-sql.org的示例代码:
func QueryAppList() *[]int64 {
var (
appList []int64
appid int64
)
qry := "SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);"
// cfg.GetDb() supplies the database connection already established
rows, err := cfg.GetDb().Query(qry)
if err != nil {
logg.Error(err)
return &appList
}
defer func(rows *sql.Rows) {
// simple defer does not catch every error: https://www.joeshaw.org/dont-defer-close-on-writable-files/
err := rows.Close()
if err != nil {
logg.Error(err)
}
}(rows)
for rows.Next() {
err := rows.Scan(&appid)
if err != nil {
logg.Error(err)
return &appList
}
appidList = append(appList, appid)
}
err = rows.Err()
if err != nil {
logg.Error(err)
return &appList
}
return &appidList
}我的程序中会有这样的查询。获取结果列表的所有方法以及如何防止失败,使得这个小查询很难理解实际发生了什么。
有办法使查询更简洁吗?
以下是我的想法,以减少代码的冗长性:
的包。
使用像gorm这样的ORM不是一种选择。
我刚开始进行Go编程,所以我缺乏语言方面的经验。
下面是Node.js中具有相同结果的相同查询。它有9行,而围棋的34,即65%,更简洁的长度。这是我理想中想去的地方。
import {query} from "../db/pool"; // connection pool query from https://github.com/sidorares/node-mysql2
export const queryAppList = async () => {
try {
const qry = "SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);";
const [appList] = await query(qry);
return appList;
} catch (err) {
console.error(err)
return [];
}
};发布于 2022-04-10 14:18:14
您可以创建一个具有可重用方法的查询结构。
就像这样:
type Query struct{
conn *sql.DB
rows *sql.Rows
...
}
func NewQuery(conn *sql.DB) *Query {
return &Query{
conn: conn,
rows: nil,
}
}
func (q Query) OpenSQL(sql string) error {
q.rows, err = q.conn.Query(sql)
if err != nil {
log.Error("SQL error during query ("+sql+"). "+err.Error())
return err
}
return nil
}
func (q Query)Close() (error) {
err := q.rows.Close()
if err != nil {
log.Error("Error closing rows. "+err.Error())
return err
}
return nil
}
//You can use generic functions to make the code even smaller
func FetchToSlice[T any](q Query) ([]T, error) {
result := make([]T, 0)
var value T
for q.rows.Next() {
err := q.rows.Scan(&value)
if err != nil {
log.Error("Error during fetching. "+err.Error())
return nil, err
}
result = append(result, value)
}
return result, nil
} 有了这个代码,您的代码将如下所示:
qry := NewQuery(cfg.GetDB())
err := qry.OpenSQL("SELECT a.appid FROM app a WHERE a.app_status IN (1, 2);")
if err != nil {
return err
}
defer qry.Close()
appidList, err := FetchToSlice[int](qry)
if err != nil {
return err
}以后,可以向查询中添加更多方法以处理更复杂的情况,甚至可以使用sync.Pool缓存查询结构等等。
https://stackoverflow.com/questions/71816948
复制相似问题