Golang博客编程中如何展示最新文章
Golang博客编程中如何展示最新文章
eg.GET("/", func(c *gin.Context) {
query := "SELECT id, r_id, p_id, s_id from whole ORDER BY id DESC limit 6"
r, err := db.Query(query)
if err != nil {
log.Fatalln("DB Connetion ERROR occured :", err)
}
data := []PRS_id{}
for r.Next() {
var temp PRS_id
r.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID)
data = append(data, temp)
}
fmt.Println(data)
c.HTML(http.StatusOK, "index.html", data)
})
我正在创建自己的博客,它包含三个类别:项目、回顾、学习。 我在数据库中为每个类别创建了对应的表,同时还创建了一个名为‘whole’的表,该表与每个类别表通过外键关联,目的是为了能够查看‘最近的6篇文章’。 目前总共有9篇文章。 按照我的设想,‘data’结构应该打印出: {9,3,0,0}{8,0,3,0}{7,3,0,0}{6,0,0,3}{5,0,0,3}{4,0,3,0} 但实际上它打印出: {9,3,0,0}{8,0,0,0}{7,3,0,0}{6,0,0,0}{5,0,0,0}{4,0,0,0}
id和PID打印正常,但我不明白为什么RID和SID没有正确打印。 当我在数据库控制台中执行这个查询时,它工作得很好。 有人知道这个问题是怎么回事吗?
更多关于Golang博客编程中如何展示最新文章的实战教程也可以访问 https://www.itying.com/category-94-b0.html
是的,我认为在测试过程中表格被稍微修改了一下,这真的很有帮助!谢谢!
更多关于Golang博客编程中如何展示最新文章的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好 @choigonyok,
PRS_id这个类型是如何定义的?- 列
id、r_id、p_id和s_id的数据类型是什么? - 最重要的是,
r.Scan()返回的错误值是什么?
我添加了 COALESCE 函数,问题解决了!!
我了解到 COALESCE() 以及 Go 无法处理 NULL 值。
这对我真的很有帮助。
非常感谢 @christophberger !! :)
为了确保我们讨论的是同一件事,你是否修改了代码来处理 r.Scan() 返回的错误?并且 r.Scan() 返回的错误始终是 nil 吗?
我之所以这样问,是因为在你的代码中,我看到的唯一错误处理是针对 db.Query() 的。
查看直接的查询结果,我推测这个问题与处理 NULL 值有关。Go 语言没有 SQL NULL 的概念,有多种方法可以弥合这种语义上的差距(例如,可以参考这篇不错的总结:在 Go 中处理 SQL NULL 值的方法 | Ekin Karadeniz)。
或许可以尝试在 SELECT 语句中使用 COALESCE:
SELECT id, COALESCE(r_id, 0), ...
你好!
首先,PRS_id 结构体定义如下:
type PRS_id struct {
ID int // 'whole' table's primary key = id column
PID int // 'projects' table's primary key = p_id column
SID int // 'study' table's primary key = s_id column
RID int // 'review' table's primary key = r_id column
}
→ 我定义这个结构体是为了获取 whole 表的数据。
其次,所有列都是 INT 类型。 这是在终端执行该查询的 MySQL 结果。
+-----+-----+-----+-----+
| id | p_id| r_id| s_id|
+-----+-----+-----+-----+
| 1 | 1 | NULL| NULL|
| 2 | NULL| NULL| 1 |
| 3 | 2 | NULL| NULL|
| 4 | NULL| 1 | NULL|
| 5 | NULL| 2 | NULL|
| 6 | NULL| NULL| 2 |
+-----+-----+-----+-----+
第三点, 虽然没有返回错误,但结果与我预期的完全不同,正如我写的那样。 所以我请求一些帮助!
补充一下 @christophberger 所说的内容,将这段代码:
r.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID)
data = append(data, temp)
……修改为:
if err = r.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID); err != nil {
log.Fatalln("Problem scanning:", err)
}
data = append(data, temp)
另外,我对数据有点困惑,因为在你的第一个评论中,你希望看到的表格和代码中重叠ID的示例是这样的:
{6,0,0,3}{5,0,0,3}{4,0,3,0}
但如果你看一下你发布的表格,你会发现原始查询返回的结果并非如此:
| 4 | NULL | 1 | NULL |
| 5 | NULL | 2 | NULL |
| 6 | NULL | NULL | 2 |
难道你实际上期望看到的是下面这样吗?
{6,0,0,2}{5,0,2,0}{4,0,1,0}
无论如何,我怀疑Christopher是对的,问题出在空值上。一旦你修改了上面的那行代码,我怀疑你会看到一个错误。另一个解决方案是查看 sql.NullInt64:
在我看来,sql.Null 的易用性稍微有些笨拙(特别是在序列化为JSON等操作时),所以我通常自己采用指针的方式。或者为我想要使用的 sql.Null 类型编写自定义的marshal/unmarshal函数。
你的查询语句只从 whole 表中选择了 id, r_id, p_id, s_id 字段,但根据你的描述,这些字段是外键,关联到其他类别表。如果 r_id 和 s_id 在数据库中的值正确,但代码中打印为0,可能是数据类型映射问题或数据扫描错误。
检查 PRS_id 结构体的字段类型是否与数据库中的列类型匹配。例如,如果数据库中 r_id 和 s_id 是整数类型(如 INT),但结构体中对应字段是 string 或其他类型,Scan 可能会失败并赋零值。
以下是修正后的示例代码,确保结构体字段类型正确,并添加错误处理:
type PRS_id struct {
ID int `json:"id"`
RID int `json:"r_id"`
PID int `json:"p_id"`
SID int `json:"s_id"`
}
eg.GET("/", func(c *gin.Context) {
query := "SELECT id, r_id, p_id, s_id FROM whole ORDER BY id DESC LIMIT 6"
rows, err := db.Query(query)
if err != nil {
log.Printf("查询失败: %v", err)
c.HTML(http.StatusInternalServerError, "error.html", nil)
return
}
defer rows.Close()
var data []PRS_id
for rows.Next() {
var temp PRS_id
if err := rows.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID); err != nil {
log.Printf("扫描行失败: %v", err)
continue
}
data = append(data, temp)
}
if err := rows.Err(); err != nil {
log.Printf("遍历行时出错: %v", err)
}
fmt.Println(data)
c.HTML(http.StatusOK, "index.html", data)
})
如果问题仍然存在,直接在代码中打印查询结果,并检查数据库中的实际值。例如,在 Scan 后添加调试输出:
for rows.Next() {
var temp PRS_id
if err := rows.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID); err != nil {
log.Printf("扫描行失败: %v", err)
continue
}
log.Printf("扫描结果: ID=%d, RID=%d, PID=%d, SID=%d", temp.ID, temp.RID, temp.PID, temp.SID)
data = append(data, temp)
}
这有助于确认数据是否从数据库正确读取。如果 RID 和 SID 在数据库中为 NULL,Go 的 Scan 可能会将其映射为0(对于整数类型)。确保数据库中没有 NULL 值,或使用 sql.NullInt64 类型处理可能为 NULL 的列:
type PRS_id struct {
ID int `json:"id"`
RID sql.NullInt64 `json:"r_id"`
PID int `json:"p_id"`
SID sql.NullInt64 `json:"s_id"`
}
然后在扫描后检查值:
for rows.Next() {
var temp PRS_id
if err := rows.Scan(&temp.ID, &temp.RID, &temp.PID, &temp.SID); err != nil {
log.Printf("扫描行失败: %v", err)
continue
}
// 处理可能为 NULL 的值
if temp.RID.Valid {
// 使用 temp.RID.Int64
}
data = append(data, temp)
}

