[TOC]
一、引言
1.记不住单词的问题
在高中,为了应付考试,不得已不得不去记下单词。然后天天死记硬背,写了不少小小的便利贴作为备份录。
在大学,为了考雅思or四六级,还是得硬着头皮去背单词。
….
(好吧,其实就是自己不想记单词)
其实,单词的记忆是一个至关重要的环节。我是比较鼓励写一个这种备忘录,进行重重复复观看。因为,对于学生时代来说,记不住单词常常成为他们学习的一大障碍。
这不仅影响了他们的四六级成绩,还可能对他们的学习英语兴趣和信心造成负面影响。因此,解决记不住单词的问题对于学生来说至关重要。
2.备忘录的必要性
为了帮助学生解决记不住单词的问题,备忘录成了一个实用的工具。
通过备忘录,学生可以随时记录下重要的单词和短语,并随时查阅,以巩固记忆。此外,备忘录还可以帮助学生规划学习进度,提醒他们按时复习,从而提高学习效率。
以前是用纸写的备忘录,当然市面上还有各种app,层出不穷。但是试想一下,别人终究是别人的,为何自己不写一个备忘录呢?
3.开发一个基于Go + Gin + Gorm + Vue的备忘录
为了更好地满足学生的需求,简单开发一个基于Go + Gin + Gorm + Vue的山寨版备忘录。
- 通过这个备忘录,希望可以更方便地记录和管理单词,解决记单词的痛点
(还是不想记单词怎么办?)。从而提高他们的学习效果。 - 也是对入门golang开发的选手比较友好吧。
源码放置:
二、技术栈介绍
1.Go语言
Go语言具有简洁的语法、强大的并发处理能力和优秀的性能。它非常适合用于开发高效的后端应用。
- 在备忘录项目中的应用
- 使用Go语言编写后端逻辑,处理用户请求,管理备忘录数据等。
2.Gin框架
Gin是一个用Go语言编写的Web框架,具有高性能和易用性。它可以快速构建Web应用程序和API。
在备忘录项目中的作用
- 使用Gin框架处理HTTP请求,提供RESTful API等。
3.Gorm ORM
Gorm是一个用Go语言编写的ORM库,用于与关系型数据库进行交互。它提供了丰富的功能,如CRUD操作、关联查询等。
在备忘录项目中的应用
- 使用Gorm库进行数据库操作,包括创建表、插入数据、查询数据等。
4.Vue.js
简介与功能
- Vue.js是一个流行的前端框架,用于构建用户界面和单页应用程序。它具有响应式数据绑定、组件化等特点。
在备忘录项目中的应用与实现
- 使用Vue.js构建前端界面,实现备忘录的展示、编辑和添加等功能。同时,通过API与后端进行数据交互。
三、备忘录功能设计
这里实现比较简单,直接实现对备忘录的增删改查
添加单词
- 用户在界面输入要添加的单词和状态,比如放弃(abandoned)。
- 应用将输入的单词和状态存储到备忘录的数据结构中,例如一个字典。
- 用户界面更新,显示最新的备忘录内容。
修改单词状态
修改单词状态
- 用户在界面选择要修改的单词。
- 应用找到该单词在备忘录中的位置。
- 用户输入新的状态。
- 应用更新该单词的状态,并更新备忘录。
- 用户界面更新,显示最新的备忘录内容。
删除单词
- 用户在界面选择要删除的单词。
- 应用找到该单词在备忘录中的位置,并将其从备忘录中删除。
- 用户界面更新,显示最新的备忘录内容。
查询所有单词
- 应用将备忘录的内容返回给用户界面。
- 用户界面显示所有的单词和状态。
四、开发过程与实现
1.环境搭建与配置
- 后端环境:安装Go编程语言的开发环境,包括Go编译器和相关工具。选择一个合适的集成开发环境(IDE)如GoLand或Visual Studio Code,并进行适当的配置。
- 前端环境:安装Node.js和npm(Node包管理器),以支持Vue.js的开发。同时,需要配置Webpack或其他前端构建工具。
- 数据库:MySQL。
2.后端开发流程
代码相对简单,后续可以再优化
main.go入口
package main
import (
"bubble/dao"
"bubble/models"
"bubble/routers"
)
func main() {
err := dao.InitMySQL()
if err != nil {
panic(err)
}
defer dao.Close() // 程序退出关闭数据库连接
// 模型绑定
dao.DB.AutoMigrate(&models.Todo{})
// 注册路由
r := routers.RegisterRouter()
r.Run()
}
路由
package routers
import (
"bubble/controller"
"github.com/gin-gonic/gin"
)
func RegisterRouter() *gin.Engine {
r := gin.Default()
r.Static("/static", "static")
r.LoadHTMLGlob("templates/*")
r.GET("/", controller.IndexHandler)
v1Group := r.Group("v1")
{
v1Group.POST("/todo", controller.CreateTodo)
v1Group.GET("/todo", controller.GetTodoList)
v1Group.PUT("/todo/:id", controller.UpdateATodo)
v1Group.DELETE("/todo/:id", controller.DeleteATodo)
}
return r
}
controller
package controller
import (
"bubble/models"
"github.com/gin-gonic/gin"
"net/http"
)
func IndexHandler(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
}
func CreateTodo(c *gin.Context) {
// 1. 从请求中把数据拿出来
var todo models.Todo
c.BindJSON(&todo)
// 2. 存入数据库
err := models.CreateATodo(&todo)
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo)
}
}
func GetTodoList(c *gin.Context) {
// 查询todo这个表里的所有数据
todoList, err := models.GetAllTodo()
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todoList)
}
}
func UpdateATodo(c *gin.Context) {
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
return
}
todo, err := models.GetATodo(id)
if err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
return
}
c.BindJSON(&todo)
if err = models.UpdateATodo(todo); err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo)
}
}
func DeleteATodo(c *gin.Context) {
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
return
}
if err := models.DeleteATodo(id); err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{id: "deleted"})
}
}
Model
package models
import (
"bubble/dao"
)
// Todo Model
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}
// CreateATodo 创建todo
func CreateATodo(todo *Todo) (err error) {
err = dao.DB.Create(&todo).Error
return
}
func GetAllTodo() (todoList []*Todo, err error) {
if err = dao.DB.Find(&todoList).Error; err != nil {
return nil, err
}
return
}
func GetATodo(id string) (todo *Todo, err error) {
todo = new(Todo)
if err = dao.DB.Debug().Where("id=?", id).First(todo).Error; err != nil {
return nil, err
}
return
}
func UpdateATodo(todo *Todo) (err error) {
err = dao.DB.Save(todo).Error
return
}
func DeleteATodo(id string) (err error) {
err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error
return
}
mysql
package dao
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var (
DB *gorm.DB
)
func InitMySQL() (err error) {
dsn := "root:123456@tcp(127.0.0.1:3306)/todo_list?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open("mysql", dsn)
if err != nil {
return
}
return DB.DB().Ping()
}
func Close() {
DB.Close()
}
五、总结与展望
- 项目总结与收获
- 功能实现:通过这个备忘录相对简单项目,实现了备忘录的增删改查功能,基本上也不算很满足了用户的基本需求。
- 技术学习:主要是通过这个项目,掌握了如何在go项目使用某些技术栈,如数据库操作、前端开发等。
- 技术栈的优缺点分析
- 优点:
- 易用性:我们选择的技术栈易于上手,适合初学者。
- 稳定性:所选技术经过了大量应用的考验,稳定可靠。
- 缺点:
- 学习曲线:对于初学者来说,某些高级特性可能学习起来有一定难度。
- 资源消耗:在某些场景下,该技术栈的资源消耗相对较高。
- 对未来备忘录功能的改进与展望
- 多平台支持:未来可以增加对移动端和平板设备的支持,让用户在更多场景下使用备忘录。
- 智能提醒:利用AI技术,为用户提供智能提醒,帮助用户更好地管理备忘事项。
- 模板功能:增加模板功能,让用户可以快速创建常用的备忘录模板。
- 数据安全与隐私保护:加强数据加密和隐私保护措施,确保用户数据的安全吧。
再吐槽一下go吧,有一说一:真香
golang入门简单,想要精通也并非易事,Go是一种静态类型、编译型的编程语言,具有简洁的语法和强大的并发处理能力。
好处方面:
- 简洁的语法:Go语言的语法简洁易懂,使得编写代码更加快速且易于维护。
- 强大的并发处理能力:Go语言内置了协程(goroutine)和通道(channel)等并发原语,使得并发编程更加简单、安全和高效。
- 内置标准库:Go语言内置了丰富的标准库,涵盖了常见的编程需求,使得开发人员可以快速构建各种应用。
- 跨平台编译:Go语言支持跨平台编译,可以在不同的操作系统和硬件平台上编译和运行代码。
- 静态类型检查:Go语言具有静态类型检查功能,可以在编译时发现潜在的错误,提高代码的可靠性。
不好的地方:
- 社区规模相对较小:相对于其他主流编程语言,Go语言的社区规模较小,可能会影响开发人员获取帮助的便利性。
- 错误处理方式限制:Go语言采用明确的错误返回方式来进行错误处理,这使得代码中错误处理的逻辑较为繁琐,同时也限制了一些高级错误处理的场景。