Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Golang melaksanakan ulasan pelbagai peringkat

Golang melaksanakan ulasan pelbagai peringkat

WBOY
WBOYasal
2023-05-10 12:25:07885semak imbas

Dengan peningkatan media sosial dan platform kandungan, sistem ulasan berbilang peringkat telah menjadi cara penting untuk interaksi pengguna dan interaksi komuniti di pelbagai platform. Ia agak mudah untuk melaksanakan sistem ulasan berbilang peringkat di bahagian hadapan, tetapi agak rumit untuk dilaksanakan di bahagian belakang. Artikel ini akan memperkenalkan cara menggunakan golang untuk melaksanakan ulasan berbilang peringkat.

Idea pelaksanaan

Komen berbilang peringkat sebenarnya ialah paparan struktur pokok dan setiap ulasan boleh digunakan sebagai nod. Sistem semakan pelbagai peringkat boleh dilaksanakan menggunakan pokok pokok dan binari, struktur data asas struktur pokok. Dalam artikel ini, kami memilih untuk menggunakan pokok binari berstruktur pokok untuk pelaksanaan.

Nod pokok binari terdiri daripada dua nod anak kiri dan kanan Nod kiri ialah nod anak pertama nod semasa, dan nod kanan ialah nod anak kedua nod semasa. Oleh itu, setiap kali kami menambah ulasan, kami hanya perlu memberi perhatian kepada nod induk ulasan semasa dan nod anak kiri dan kanannya.

Reka bentuk pangkalan data

Untuk melaksanakan sistem ulasan berbilang peringkat, hubungan ibu bapa-anak bagi setiap ulasan perlu disimpan dalam pangkalan data. Secara umum, kita boleh menggunakan dua cara untuk menyimpan struktur pokok:

  1. Gunakan perkaitan berbilang jadual
  2. Gunakan perhubungan rujukan kendiri dalam satu jadual

Dalam artikel ini, kami memilih untuk menggunakan kaedah kedua, iaitu menggunakan hubungan rujukan kendiri dalam satu jadual.

Struktur jadual ulasan (ulasan) adalah seperti berikut:

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='评论表'

Dalam struktur jadual di atas, parent_id mewakili id ​​nod induk bagi ulasan semasa ulasan peringkat pertama, kemudian parent_id adalah batal. id ialah id ulasan semasa, content ialah kandungan ulasan dan created_at ialah masa penciptaan.

Pelaksanaan kod

Memautkan pangkalan data

Pertama, anda perlu menggunakan pangkalan data/sql dan pemacu mysql dalam golang untuk memaut ke pangkalan data:

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
}

Sisipkan ulasan

Apabila memasukkan ulasan, anda perlu menentukan sama ada ulasan semasa diproses sebagai nod induk atau nod anak.

Jika ulasan semasa digunakan sebagai nod induk, ia dimasukkan terus ke dalam pangkalan data Jika ulasan semasa ialah nod anak, nod kanan nod induk perlu dikemas kini.

// 添加评论
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
}

Menyoal ulasan

Apabila menanyakan ulasan, anda perlu mengisih nod dalam tertib kiri dan kanan untuk mendapatkan senarai ulasan berstruktur pokok. Apabila menanyakan ulasan, memandangkan nod kiri dan kanan perlu digunakan untuk mengisih, lajur nod kiri dan kanan perlu ditambah pada syarat pertanyaan. Selain itu, anda juga perlu menggunakan medan tahap untuk menunjukkan tahap nod mana nod semasa untuk memudahkan paparan bahagian hadapan.

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
}

Padam ulasan

Apabila memadamkan ulasan, anda perlu menentukan sama ada ulasan semasa ialah nod induk atau nod anak Jika ia adalah nod induk, anda perlu memadamkan keseluruhannya pokok pokok.

// 删除评论
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
}

Kesimpulan

Melalui pelaksanaan kod di atas, kami boleh membina sistem ulasan pelbagai peringkat yang berfungsi sepenuhnya dengan pantas. Sudah tentu, ini hanyalah kaedah pelaksanaan asas Dalam senario sebenar, pengoptimuman dan pengembangan yang sepadan perlu dibuat mengikut keperluan khusus.

Atas ialah kandungan terperinci Golang melaksanakan ulasan pelbagai peringkat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:penukaran jenis golang okArtikel seterusnya:penukaran jenis golang ok