【go项目01_学习记录11】

操作数据库

  • 1 文章列表
  • 2 删除文章

1 文章列表

(1)先保证文章已经有多篇,可以直接在数据库中添加,或者访问链接: localhost:3000/articles/create,增加几篇文章。
在这里插入图片描述
(2)之前设置好了articles.index 路由,访问 localhost:3000/articles 显示文章列表
在这里插入图片描述
(3)完善articlesIndexHandler()使之能够显示数据库中的数据

.
.
.
func articlesIndexHandler(w http.ResponseWriter, r *http.Request) {
    // 1. 执行查询语句,返回一个结果集
    rows, err := db.Query("SELECT * from articles")
    checkError(err)
    defer rows.Close()

    var articles []Article
    //2. 循环读取结果
    for rows.Next() {
        var article Article
        // 2.1 扫描每一行的结果并赋值到一个 article 对象中
        err := rows.Scan(&article.ID, &article.Title, &article.Body)
        checkError(err)
        // 2.2 将 article 追加到 articles 的这个数组中
        articles = append(articles, article)
    }

    // 2.3 检测遍历时是否发生错误
    err = rows.Err()
    checkError(err)

    // 3. 加载模板
    tmpl, err := template.ParseFiles("resources/views/articles/index.gohtml")
    checkError(err)

    // 4. 渲染模板,将所有文章的数据传输进去
    err = tmpl.Execute(w, articles)
    checkError(err)
}
.
.
.

添加模板
resources/views/articles/index.gohtml

<!DOCTYPE html>
<html lang="en">
<head>
    <title>所有文章 —— 我的技术博客</title>
    <style type="text/css">.error {color: red;}</style>
</head>
<body>
    <h1>所有文章</h1>
    <ul>
        {{ range $key, $article := . }}
            <li><a href=""><strong>{{ $article.ID }}</strong>: {{ $article.Title }}</a></li>
        {{ end }}
    </ul>
</body>
</html>

访问 localhost:3000/articles
在这里插入图片描述
为列表里的文章加上链接

.
.
'
// Article  对应一条文章数据
type Article struct {
    .
    .
    .
}

// Link 方法用来生成文章链接
func (a Article) Link() string {
    showURL, err := router.Get("articles.show").URL("id", strconv.FormatInt(a.ID, 10))
    if err != nil {
        checkError(err)
        return ""
    }
    return showURL.String()
}
.
.
.

保存后刷新页面并查看页面源码:

在这里插入图片描述

2 删除文章

先开发后台的删除逻辑,然后在文章详情页里显示删除按钮
(1)注册articles.delete 路由
在这里插入图片描述
(2)添加articlesDeleteHandler()函数

.
.
.
func articlesDeleteHandler(w http.ResponseWriter, r *http.Request) {

    // 1. 获取 URL 参数
    id := getRouteVariable("id", r)

    // 2. 读取对应的文章数据
    article, err := getArticleByID(id)

    // 3. 如果出现错误
    if err != nil {
        if err == sql.ErrNoRows {
            // 3.1 数据未找到
            w.WriteHeader(http.StatusNotFound)
            fmt.Fprint(w, "404 文章未找到")
        } else {
            // 3.2 数据库错误
            checkError(err)
            w.WriteHeader(http.StatusInternalServerError)
            fmt.Fprint(w, "500 服务器内部错误")
        }
    } else {
        // 4. 未出现错误,执行删除操作
        rowsAffected, err := article.Delete()

        // 4.1 发生错误
        if err != nil {
            // 应该是 SQL 报错了
            checkError(err)
            w.WriteHeader(http.StatusInternalServerError)
            fmt.Fprint(w, "500 服务器内部错误")
        } else {
            // 4.2 未发生错误
            if rowsAffected > 0 {
                // 重定向到文章列表页
                indexURL, _ := router.Get("articles.index").URL()
                http.Redirect(w, r, indexURL.String(), http.StatusFound)
            } else {
                // Edge case
                w.WriteHeader(http.StatusNotFound)
                fmt.Fprint(w, "404 文章未找到")
            }
        }
    }
}

添加Article 的 Delete() 方法 ,上面代码块用到了Delete方法


// // 为 Article 添加一个 Delete 方法,删除文章
func (a Article) Delete() (rowsAffected int64, err error) {
    rs, err := db.Exec("DELETE FROM articles WHERE id = " + strconv.FormatInt(a.ID, 10))

    if err != nil {
        return 0, err
    }

    // √ 删除成功
    if n, _ := rs.RowsAffected(); n > 0 {
        return n, nil
    }

    return 0, nil
}


(3)文章详情页面添加删除按钮

.
.
.
func  articlesShowHandler(w http.ResponseWriter, r *http.Request) {
    .
    .
    .
    // 3. 如果出现错误
    if err !=  nil {
        .
        .
        .
    } else {
        // 4. 读取成功,显示文章
        tmpl, err := template.New("show.gohtml").
            Funcs(template.FuncMap{
                "RouteName2URL": RouteName2URL,
                "Int64ToString": Int64ToString,
            }).
            ParseFiles("resources/views/articles/show.gohtml")
        checkError(err)
        err = tmpl.Execute(w, article)
        checkError(err)
    }
}

template.New() 先初始化,然后使用 Funcs() 注册函数,再使用 ParseFiles (),需要注意的是 New() 的参数是模板名称,需要对应 ParseFiles() 中的文件名,否则会无法正确读取到模板,最终显示空白页面。

创建上面代码中的两个函数RouteName2URL 和 Int64ToString

.
.
.
// RouteName2URL 通过路由名称来获取 URL
func RouteName2URL(routeName string, pairs ...string) string {
    url, err := router.Get(routeName).URL(pairs...)
    if err != nil {
        checkError(err)
        return ""
    }

    return url.String()
}

// Int64ToString 将 int64 转换为 string
func Int64ToString(num int64) string {
    return strconv.FormatInt(num, 10)
}

func (a Article) Delete() (rowsAffected int64, err error) {
.
.
.

修改模板 show.gohtml

<!DOCTYPE html>
<html lang="en">

<head>
    <title>{{ .Title }} —— 我的技术博客</title>
    <style type="text/css">
        .error {
            color: red;
        }
    </style>
</head>

<body>
    <p>ID: {{ .ID }}</p>
    <p>标题: {{ .Title }}</p>
    <p>内容:{{ .Body }}</p>

    {{/* 构建删除按钮  */}}
    {{ $idString := Int64ToString .ID  }}
    <form action="{{ RouteName2URL "articles.delete" "id" $idString }}" method="post">
        <button type="submit" onclick="return confirm('删除动作不可逆,请确定是否继续')">删除</button>
    </form>

</body>

</html>

在这里插入图片描述
打开articles.show文章详情页localhost:3000/articles/4
在这里插入图片描述
在这里插入图片描述
点击删除,确定删除
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/622805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第87题扰乱字符串

题目&#xff1a; 题解&#xff1a; struct HashTable {int key;int val;UT_hash_handle hh; };void modifyHashTable(struct HashTable** hashTable, int x, int inc) {struct HashTable* tmp;HASH_FIND_INT(*hashTable, &x, tmp);if (tmp NULL) {tmp malloc(sizeof(st…

树莓派对FPGA板子上的流水灯程序的控制

文章目录 一 树莓派使用教程二 树莓派串口代码三 Verilog代码四 quartus引脚绑定五 运行效果总结 分别在DE2-115开发板和树莓派上编写串口通信程序&#xff0c; 实现树莓派串口指令对FPGA板子上的流水灯程序的控制&#xff0c;控制方式自定。 一 树莓派使用教程 参考&#xff…

第187题| 快速学会“阿贝尔定理”| 无穷级数(十五)|武忠祥老师每日一题

解题思路&#xff1a;这道题没有告诉我们是多少&#xff0c;没办法求出收敛半径&#xff0c;所以我们只能根据题目给的两个条件来解题&#xff08;选项代入法&#xff09;。 1.x-1&#xff0c;说明收敛的中心点是1&#xff0c;观察下列选项&#xff0c;显然答案在C和D之中。 …

Linux中的网络隔离功能 netns

Network Namespace&#xff08;netns&#xff09; 是Linux内核提供的一项实现网络隔离的功能&#xff0c;它能隔离多个不同的网络空间&#xff0c;并且各自拥有独立的网络协议栈。通过 namespace 可以隔离容器的进程 PID、文件系统挂载点、主机名等多种资源&#xff0c;它可以为…

基于门控的循环神经网络:LSTM

之前我们介绍了循环神经网络的原理以及实现。但是循环神经网络有一个问题&#xff0c;也就是长期依赖问题。我们之前的01序列预测案例中可以看到&#xff0c;当序列长度到达10以上之后错误就会增多&#xff0c;说明简单的RNN记忆容量较小&#xff0c;当长度更大时就不怎么适用了…

可重构柔性装配产线:为工业制造领域注入了新的活力

随着科技的飞速发展&#xff0c;智能制造正逐渐成为引领工业革新的重要力量。在这一浪潮中&#xff0c;可重构柔性装配产线以其独特的技术优势和创新理念&#xff0c;为工业制造领域注入了新的活力&#xff0c;开启了创新驱动的智能制造新篇章。 可重构柔性装配产线是基于富唯智…

2024年一些值得关注的边缘计算招投标!中国移动、中国联通、中国铁塔大单来了!...

1.大单来了&#xff01;中国移动湖北公司算力设备采购(移动边缘云四期扩容)招标公告&#xff0c;3079万&#xff01; 项目名称&#xff1a;中国移动湖北公司算力设备采购(移动边缘云四期扩容)招标公告 本招标项目为(中国移动湖北公司算力设备采购(移动边缘云四期扩容)&#xff…

Cweek1

C语言学习 一.初识C语言 1.如何写C代码 ①创建工程 ②添加源文件&#xff1a;c文件&#xff1a;源文件&#xff0c;h文件&#xff1a;头文件 代码实例&#xff1a; main函数是程序的入口&#xff0c;有且仅有一个 在C语言中&#xff0c;#include <stdio.h> 是一个预…

Windows 11 下 kafka 的安装踩坑

安装 windows系统kafka小白入门篇——下载安装&#xff0c;环境配置&#xff0c;入门代码书写&#xff08;推荐&#xff09; kafka在windows下安装和使用入门教程 问题1 参考链接 运行kafka集成的zookeeper时&#xff0c;命令&#xff1a;bin\windows\zookeeper-server-star…

JavaEE初阶-多线程5

文章目录 一、线程池1.1 线程池相关概念1.2 线程池标准类1.3 线程池工厂类1.4 实现自己的线程池 二、定时器2.1 java标准库中的定时器使用2.2 实现一个自己的定时器2.2.1 定义任务类2.2.2 定义定时器 一、线程池 1.1 线程池相关概念 池这个概念在计算机中比较常见&#xff0c…

PXE+Kickstart无人值守安装安装Centos7.9

文章目录 一、什么是PXE1、简介2、工作模式3、工作流程 二、什么是Kickstart1、简介2、触发方式 三、无人值守安装系统工作流程四、实验部署1、环境准备2、服务端&#xff1a;关闭防火墙和selinux3、添加一张仅主机的网卡4、配置仅主机的网卡4.1、修改网络连接名4.2、配IP地址4…

​​​【收录 Hello 算法】5.3 双向队列

目录 5.3 双向队列 5.3.1 双向队列常用操作 5.3.2 双向队列实现 1. 基于双向链表的实现 2. 基于数组的实现 5.3.3 双向队列应用 5.3 双向队列 在队列中&#xff0c;我们仅能删除头部元素或在尾部添加元素。如图 5-7 所示&#xff0c;双向队列&#xff08…

校园志愿者管理系统带万字文档

文章目录 校园志愿者管理系统一、项目演示二、项目介绍三、10000字论文参考四、部分功能页面五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 校园志愿者管理系统 一、项目演示 校园志愿者管理系统 二、项目介绍 基于Spring…

【数据结构】-- 相交链表-环形链表

交叉链表 . - 力扣&#xff08;LeetCode&#xff09; 如果链表的两条链的长度一样&#xff0c;链表两端对齐&#xff0c;解决这个问题将会变得非常简单&#xff0c;直接分别遍历两个链表&#xff0c;想等时的节点即为所求。我们想办法让链表对齐--分别从a和b遍历链表&#xff…

centos7中如何全局搜索一下nginx的配置文件?

在CentOS 7中搜索Nginx的配置文件&#xff0c;你可以使用一些常用的命令行工具&#xff0c;比如find、grep等。这些工具可以帮助你在文件系统中查找文件&#xff0c;也可以用来查找Docker容器内部的文件&#xff0c;只要你知道如何访问容器的文件系统。 1. 搜索系统中的Nginx配…

nowcoder——回文结构

链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 我们来分析该题&#xff1a;我们首先要清楚什么是回文结构&#xff1f;其实就是对称结构。如果一个链表呈对称结构就说明该链表具有回文结构。 下面给上一些例子&#xff1a; 那我们怎么判断该链表是否属于回文结构呢&#xf…

Web3 Tools - Base58

Base58编码 Base58编码是一种用于表示数字的非常见的编码方法。它通常用于加密货币领域&#xff0c;例如比特币和其他加密货币的地址表示。 什么是Base58编码&#xff1f; Base58编码是一种将数字转换为人类可读形式的编码方法。与常见的Base64编码不同&#xff0c;Base58编码…

AI智能体|我把Kimi接入了个人微信

大家好&#xff0c;我是无界生长。 最近加入AI学习交流群的小伙伴越来越多&#xff0c;我打算在微信群接入一个聊天机器人&#xff0c;让它协助管理微信群&#xff0c;同时也帮忙给群友解答一些问题。普通的群聊机器人肯定是不能满足需求的&#xff0c;得上AI大模型&#xff0c…

使用 Python 中的 TensorFlow 检测垃圾短信

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

绘唐3启动器怎么启动一键追爆款3正式版

绘唐3启动器怎么启动一键追爆款3正式版 工具入口 一.文案助手&#xff1a; 【注意&#xff01;&#xff01;】如果图片无显示&#xff0c;一般情况下被杀毒拦截&#xff0c;需关闭杀毒软件或者信任文件路径。 win10设置排除文件&#xff1a; 1.【新建工程】使用前先新建工程…