需要你的帮助。 想要构建简单的api并遇到一些问题。 我选择gin和数据库/ sql与postgres driver
package main
import (
"database/sql"
"fmt"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
func main() {
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
我需要查询DB并使json脱离此请求。
func checkErr(err error) {
if err != nil {
panic(err)
}
}
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
db, err := sql.Open("postgres", "host=8.8.8.8 user= password= dbname=sample")
defer db.Close()
checkErr(err)
rows, err2 := db.Query("SELECT ticket_id,event FROM ....$1, word)
checkErr(err)
for rows.Next() {
var ticket_id int
var event string
err = rows.Scan(&ticket_id, &event)
checkErr(err)
fmt.Printf("%d | %s \n\n", ticket_id, event)
}
}
这种尾声很好用,但是当我需要制作json时。 我需要创建一行结构
type Message struct {
ticket_id int `json:"ticket_id"`
event string `json:"event"`
}
然后我需要创建切片,并附加每个rows.Next()循环而不是使用Json回答浏览器......
c.JSON(200, messages)
但是怎么做......不知道:(
答案 0 :(得分:1)
由于您m := &Message{ticket_id: ticket_id, event: event}
将列数据添加到变量中,因此您应该能够使用其值初始化结构:
s := make([]*Message, 0)
您可以使用
初始化切片 s = append(s, m)
然后在实例化后附加每个消息结构:
rows.Scan
因为我不太熟悉去,有几件我不确定的事情:
使用Message
将数据从查询复制到您的变量后,初始化Message
struct会按预期复制当前迭代值吗?
如果有办法从查询中获取总行数,那么初始化静态长度数组而不是切片可能会更加高效吗?
我认为@inf已删除的答案有关将您的Message
编组到json下线可能需要解决,type Message struct {
Ticket_id int `json:"ticket_id"`
Event string `json:"event"` }
字段可能需要大写
从@inf:
复制您的结构成员的名称需要大写,以便 它们被导出并可以访问。
data:{username: user, password: pass}
答案 1 :(得分:0)
我会在这里作弊,并在此过程中解决一些问题:
首先:在程序启动时打开数据库连接池一次(而不是每次请求都打开)。
第二:我们将使用sqlx来更容易地将我们的数据库行封送到我们的结构中。
package main
var db *sqlx.DB
func main() {
var err error
// sqlx.Connect also checks that the connection works.
// sql.Open only "establishes" a pool, but doesn't ping the DB.
db, err = sqlx.Connect("postgres", "postgres:///...")
if err != nil {
log.Fatal(err)
}
router := gin.Default()
router.GET("/search/:text", SearchWord)
router.Run(":8080")
}
// in_another_file.go
type Message struct {
TicketID int `json:"ticket_id" db:"ticket_id"`
Event string `json:"event" db:"event"`
}
func SearchWord(c *gin.Context) {
word := c.Params.ByName("text")
// We create a slice of structs to marshal our rows into
var messages []*Message{}
// Our DB connection pool is safe to use concurrently from here
err := db.Select(&messages, "SELECT ticket_id,event FROM ....$1, word)
if err != nil {
http.Error(c.Writer, err.Error(), 500)
return
}
// Write it out using gin-gonic's JSON writer.
c.JSON(200, messages)
}
我希望这很清楚。 sqlx
也负责为您调用rows.Close()
,否则将会挂起连接。