Heim >Backend-Entwicklung >Golang >Golang implementiert mehrstufige Kommentare
Mit dem Aufkommen sozialer Medien und Content-Plattformen sind mehrstufige Kommentarsysteme zu einem wichtigen Mittel für die Benutzerinteraktion und Community-Interaktion auf verschiedenen Plattformen geworden. Es ist relativ einfach, ein mehrstufiges Kommentarsystem im Frontend zu implementieren, die Implementierung im Backend ist jedoch relativ kompliziert. In diesem Artikel wird erläutert, wie Sie mit Golang Kommentare auf mehreren Ebenen implementieren.
Mehrstufige Kommentare sind eigentlich eine Anzeige einer Baumstruktur, und jeder Kommentar kann als Knoten verwendet werden. Mehrstufige Überprüfungssysteme können mithilfe von Baum- und Binärbäumen, den grundlegenden Datenstrukturen von Baumstrukturen, implementiert werden. In diesem Artikel entscheiden wir uns für die Implementierung eines baumstrukturierten Binärbaums.
Der Knoten des Binärbaums besteht aus zwei linken und rechten untergeordneten Knoten. Der linke Knoten ist der erste untergeordnete Knoten des aktuellen Knotens und der rechte Knoten ist der zweite untergeordnete Knoten des aktuellen Knotens. Daher müssen wir jedes Mal, wenn wir einen Kommentar hinzufügen, nur auf den übergeordneten Knoten des aktuellen Kommentars und seine linken und rechten untergeordneten Knoten achten.
Um ein mehrstufiges Kommentarsystem zu implementieren, muss die Eltern-Kind-Beziehung jedes Kommentars in der Datenbank gespeichert werden. Im Allgemeinen können wir zwei Möglichkeiten zum Speichern von Baumstrukturen verwenden:
CREATE TABLE `comment` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) DEFAULT NULL COMMENT '父级评论id', `content` varchar(255) DEFAULT NULL COMMENT '评论内容', `created_at` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`), KEY `parent_id` (`parent_id`), CONSTRAINT `comment_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `comment` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='评论表'In der obigen Tabellenstruktur ist
die Erstellungszeit. parent_id
表示当前评论的父节点id,如果当前评论是一级评论,则parent_id
为null。id
为当前评论的id,content
为评论内容,created_at
dsn := "root:123456@tcp(127.0.0.1:3306)/test" db, err := sql.Open("mysql", dsn) if err != nil { fmt.Printf("mysql connect error %s", err.Error()) return }Kommentar einfügenBeim Einfügen eines Kommentars müssen Sie festlegen, ob der aktuelle Kommentar als übergeordneter Knoten oder als untergeordneter Knoten verarbeitet wird. Wenn der aktuelle Kommentar als übergeordneter Knoten verwendet wird, wird er direkt in die Datenbank eingefügt. Wenn der aktuelle Kommentar ein untergeordneter Knoten ist, muss der rechte Knoten des übergeordneten Knotens aktualisiert werden.
// 添加评论 func AddComment(comment Comment) error { if comment.ParentID == 0 { _, err := db.Exec("INSERT INTO comment(parent_id, content, created_at) VALUES(?, ?, ?)", nil, comment.Content, comment.CreatedAt) if err != nil { return err } } else { var rightNode *int err := db.QueryRow("SELECT right_node FROM comment WHERE id = ?", comment.ParentID).Scan(&rightNode) if err != nil { return err } tx, err := db.Begin() if err != nil { return err } // 更新右节点 _, err = tx.Exec("UPDATE comment SET right_node = right_node + 2 WHERE right_node > ?", rightNode) if err != nil { tx.Rollback() return err } _, err = tx.Exec("UPDATE comment SET left_node = left_node + 2 WHERE left_node > ?", rightNode) if err != nil { tx.Rollback() return err } _, err = tx.Exec("INSERT INTO comment(parent_id, left_node, right_node, content, created_at) VALUES(?, ?, ?, ?, ?)", comment.ParentID, rightNode, rightNode+1, comment.Content, comment.CreatedAt) if err != nil { tx.Rollback() return err } tx.Commit() } return nil }Kommentare abfragenBei der Abfrage von Kommentaren müssen Sie diese nach der linken und rechten Reihenfolge der Knoten sortieren, um eine baumstrukturierte Kommentarliste zu erhalten. Da beim Abfragen von Kommentaren der linke und der rechte Knoten zum Sortieren verwendet werden müssen, müssen die linken und rechten Knotenspalten zu den Abfragebedingungen hinzugefügt werden. Darüber hinaus müssen Sie auch ein Ebenenfeld verwenden, um anzugeben, auf welcher Knotenebene sich der aktuelle Knoten befindet, um die Front-End-Anzeige zu erleichtern.
type Comment struct { ID int `json:"id"` ParentID int `json:"parent_id"` Content string `json:"content"` LeftNode int `json:"left_node"` RightNode int `json:"right_node"` Level int `json:"level"` CreatedAt string `json:"created_at"` } // 获取评论列表 func GetComments() ([]Comment, error) { rows, err := db.Query("SELECT id, parent_id, content, created_at, left_node, right_node, (COUNT (parent.id) -1) AS level FROM comment AS node, comment AS parent WHERE node.left_node BETWEEN parent.left_node AND parent.right_node GROUP BY node.id ORDER BY left_node") if err != nil { return nil, err } defer rows.Close() var comments []Comment for rows.Next() { var comment Comment err := rows.Scan(&comment.ID, &comment.ParentID, &comment.Content, &comment.CreatedAt, &comment.LeftNode, &comment.RightNode, &comment.Level) if err != nil { return nil, err } comments = append(comments, comment) } return comments, nil }Kommentar löschenBeim Löschen eines Kommentars müssen Sie feststellen, ob es sich bei dem aktuellen Kommentar um einen übergeordneten Knoten oder einen untergeordneten Knoten handelt um den gesamten Teilbaum zu löschen.
// 删除评论 func DeleteComment(id int) error { tx, err := db.Begin() if err != nil { return err } var leftNode int var rightNode int err = tx.QueryRow("SELECT left_node, right_node FROM comment WHERE id = ?", id).Scan(&leftNode, &rightNode) if err != nil { tx.Rollback() return err } if leftNode == 1 && rightNode > 1 { // 删除子树 _, err = tx.Exec("DELETE FROM comment WHERE left_node >= ? AND right_node <= ?;", leftNode, rightNode) if err != nil { tx.Rollback() return err } err = tx.Commit() if err != nil { tx.Rollback() return err } } else { // 删除单个节点 _, err = tx.Exec("DELETE FROM comment WHERE id = ?", id) if err != nil { tx.Rollback() return err } err = tx.Commit() if err != nil { tx.Rollback() return err } } return nil }FazitDurch die obige Code-Implementierung können wir schnell ein voll funktionsfähiges mehrstufiges Kommentarsystem aufbauen. Dies ist natürlich nur eine grundlegende Implementierungsmethode. In tatsächlichen Szenarien müssen entsprechende Optimierungen und Erweiterungen entsprechend den spezifischen Anforderungen vorgenommen werden.
Das obige ist der detaillierte Inhalt vonGolang implementiert mehrstufige Kommentare. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!