【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 casew.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
在这里插入图片描述
在这里插入图片描述
点击删除,确定删除
在这里插入图片描述


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

栈队列经典OJ题(详细过程)

1. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 第一题判断有效的括号&#xff0c;这道题我们会用到栈的知识&#xff0c;栈是后进先出的&#xff0c;可以根据这个来解这道题&#xff0c;先看一下题目和示例。 1.1整体思路 我们通过示例可以看出括号匹配就返回true&am…

【JAVA】BOSS系统发版艺术:构建高效、优雅的微服务部署策略

在现代软件开发领域&#xff0c;微服务架构与容器化部署已迅速成为行业新趋势。微服务架构通过将应用拆分成多个小型、自治的服务单元&#xff0c;每个服务承担某项特定的业务功能。而容器化部署则以其轻量级和高度可移植的特性&#xff0c;为这些微服务的有效打包、分发和运行…

科技查新中的工法查新点如何确立与提炼?案例讲解!

按《工程建设工法管理办法》( 建 质&#xff3b;2014&#xff3d;103 号) &#xff0c;工法&#xff0c;是指以工程为对象&#xff0c;以工艺为核心&#xff0c;运用系 统工程原理&#xff0c;把先进技术和科学管理结合起来&#xff0c;经过一定工程实践形成的综合配套的施工方…

探索美国动态IP池:技术赋能下的网络安全新篇章

在数字化飞速发展的今天&#xff0c;网络安全成为了各行各业关注的焦点。特别是在跨国业务中&#xff0c;如何保障数据的安全传输和合规性成为了企业面临的重要挑战。美国动态IP池作为一种新兴的网络技术&#xff0c;正逐渐走进人们的视野&#xff0c;为网络安全提供新的解决方…

黑马甄选离线数仓项目day02(数据采集)

datax介绍 官网&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.md DataX 是阿里云 DataWorks数据集成 的开源版本&#xff0c;在阿里巴巴集团内被广泛使用的离线数据同步工具/平台。 DataX 实现了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre…

计算机Java项目|Springboot学生读书笔记共享

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、Python项目、前端项目、人工智能与大数据、简…

华为设备display查看命令

display version //查看版本信息 display current-configuration //查看配置详情 display this //查看当前视图有效配置 display ip routing-table //查看路由表 display ip routing-table 192.168.3.1 //查看去往3.1的路由 display ip interface brief //查看接口下ip信息 dis…

想跨境出海?云手机提供了一种可能性

全球化时代&#xff0c;越来越多的中国电商开始将目光投向了海外市场。这并不是偶然&#xff0c;而是他们在长期的市场运营中&#xff0c;看到了出海的必要性和潜在的机会。 中国的电商市场无疑是全球最大也最发达的之一。然而&#xff0c;随着市场的不断发展和竞争的日益加剧…

visual studio2022 JNI极简开发流程

文章目录 1 创建java类2 生成JNI头文件3 使用visual studio2022创建DLL项目3.1 选择模板中&#xff08;Windows桌面向导&#xff09;3.2 为项目命名3.3 选择应用程序类型为动态链接库3.4 项目概览 4 导入需要的头文件4.1 导入需要的头文件4.2 修改头文件 5 编写C实现6 生成dll文…

服务器3389端口,服务器3389端口风险提示的应对措施

3389端口是Windows操作系统中远程桌面协议&#xff08;RDP&#xff09;的默认端口。一旦该端口被恶意攻击者利用&#xff0c;可能会导致未经授权的远程访问和数据泄露等严重安全问题。 针对此风险&#xff0c;强烈建议您采取以下措施&#xff1a; 1. 修改默认端口&#xff1a;…

springboot3 集成spring-authorization-server (一 基础篇)

官方文档 Spring Authorization Server 环境介绍 java&#xff1a;17 SpringBoot&#xff1a;3.2.0 SpringCloud&#xff1a;2023.0.0 引入maven配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter…

识别AI论文生成内容,降低论文高AI率

AI写作工具能帮我们在短时间内高效生成一篇毕业论文、开通报告、文献综述、任务书、调研报告、期刊论文、课程论文等等&#xff0c;导致许多人开始使用AI写作工具作为撰写学术论文的辅助手段。而学术界为了杜绝此行为&#xff0c;开始使用AIGC检测系统来判断文章是由AI生成还是…

解锁商业AI,赋能新质生产力发展——思爱普中国峰会探展全纪录

ITValue 钛媒体独家探秘思爱普中国峰会&#xff0c;带你深刻感受SAP助力企业利用以商业AI为代表的数字化技术&#xff0c;实现质的飞跃&#xff0c;通过全数据、全球化、全绿色赋能新型中国企业发展新质生产力。 首发&#xff5c;钛媒体APP ITValue 5月10日&#xff0c;一年一度…

基于NTP服务器获取网络时间的实现

文章目录 1 NTP1.1 简介1.2 包结构1.3 UNIX 时间戳和NTP时间戳 2 代码实现2.1 实现步骤2.2 完整代码 3 结果 在某些场景下&#xff0c;单片机需要通过网络获取准确的时间进行数据同步&#xff0c;例如日志记录、定时任务等。然而&#xff0c;单片机本身无法直接获得准确的标准时…

Vue的学习 —— <vue指令>

目录 前言 正文 内容渲染指令 内容渲染指令的使用方法 v-text v-html 属性绑定指令 双向数据绑定指令 事件绑定指令 条件渲染指令 循环列表渲染指令 侦听器 前言 在完成Vue开发环境的搭建后&#xff0c;若想将Vue应用于实际项目&#xff0c;首要任务是学习Vue的基…

ORA-00932: inconsistent datatypes: expected - got CLOB的分析解决方案

最近在项目中遇到查询数据时报ORA-00932: inconsistent datatypes: expected - got CLOB错误&#xff0c;这个错误很明显是由于查询时类型的不匹配造成的。 问题分析&#xff1a; 一、检查你的查询的实体的类型是否于数据库的保持一致&#xff0c;如果不一致&#xff0c;那么需…

[力扣题解] 96. 不同的二叉搜索树

题目&#xff1a;96. 不同的二叉搜索树 思路 动态规划 f[i]&#xff1a;有i个结点有多少种二叉搜索树 状态转移方程&#xff1a; 以n3为例&#xff1a; 以1为头节点&#xff0c;左子树有0个结点&#xff0c;右子树有2个结点&#xff1b; 以2为头节点&#xff0c;左子树有1个…

安科瑞AIM-D100-ES光伏储能系统直流绝缘监测仪

概述 AIM-D100-ES 型直流绝缘监测仪主要用于在线监测直流不接地系统正负极对地绝缘电阻&#xff0c;当绝缘电阻低于设定值时&#xff0c;能发出预警和报警信号。 产品可测 100-1500V 的直流系统&#xff0c;可应用于储能直流系统、电动汽车充电装置、UPS 供电系统、光伏直流系…

std::ref和std::cref的使用和原理分析

目录 1.用法 2.std::reference_wrapper介绍 3.std::ref原理分析 4.std::cref原理分析 5.总结 1.用法 它的定义如下&#xff1a; std::ref&#xff1a;用于包装按引用传递的值。 std::cref&#xff1a;用户包装按const引用传递的值。 C本身就有引用&#xff08;&&#…

面试题:调整数字顺序,使奇数位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序 使得所有奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分 算法1&#xff1a; 利用快速排序的一次划分思想&#xff0c;从2端往中间遍历 时间复杂度&#x…