在 posts
表中,有如下属性 title
, content
. 我可以得到 *sql.Rows
把它们传给观景台
posts, err := db.Query("SELECT id, title FROM posts WHERE id = 1")
以及
err = tpl.ExecuteTemplate(w, "index.gohtml", posts)
但我无法显示 title
视图中的值。这是我的密码。
索引.go
package main
import (
"net/http"
"fmt"
"log"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func index(w http.ResponseWriter, r *http.Request) {
db, err := sql.Open("mysql", "root:****@/database")
if err != nil {
panic(err.Error())
}
defer db.Close()
posts, err := db.Query("SELECT id, title FROM posts WHERE id = 1")
var id int
var title string
for posts.Next() {
err = posts.Scan(&id, &title)
if err != nil {
panic(err.Error())
}
}
fmt.Println(posts)
defer posts.Close()
err = tpl.ExecuteTemplate(w, "index.gohtml", posts)
if err != nil {
log.Println(err)
}
}
索引.gohtml
<h1>Awesome Posts</h1>
{{$posts := .}}
<p>{{$posts}}</p>
1条答案
按热度按时间vnzz0bqm1#
您的代码中有一些错误,我认为您误解了如何使用
sql
包裹。正如flimzy在评论中所说,您应该传递一个适当的上下文结构,其中包含您的id和title值。
如果您检查文档中的sql.rows,您将看到如何从查询中提取每一行的数据……事实上,您已经知道如何通过使用
Next()
以及Scan()
方法。但是这不应该由html模板中的代码来完成,它应该将结果存储在传递给模板的某个变量中。快速回答
快速回答您的问题的方法是更改如何将值传递到模板中并修改模板。既然你宣布
id
以及title
应将其传递给模板的变量:有个模特儿
更好的解决方案是拥有一个包含post所有属性的结构,并使用它来
Scan
进入。但是,存储查询结果的方式还有另一个问题。您正在使用
db.Query
返回一行-这是一个假设WHERE ID=1
. 如果您只希望返回一个post,那么请使用queryrow方法:(注意,为了简单起见,您可以链接scan方法)但是,如果您希望检索多个post(为了简单起见,您只是添加了where子句),那么您需要
Scan
变成一个Post
结构,并附加到Posts
.其他考虑因素
您不应该在http处理程序中创建到db的连接。一种方法是使用一个全局变量来保存连接。具有嵌入连接的结构可以工作和/或也可以将连接抽象到包中。
/分贝/分贝
/db/posts.go文件
主菜单.go
使用
另一种方法是使用依赖注入,让函数接收db连接,但返回
http.HandlerFunc
. 例如