我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang
第四期 · 将部分数据存储至Mysql,使用axios通过golang搭建的http服务器获取数据。
新建数据库
DROP DATABASE VUE;
create database if not exists vue;
use vue;
JSON TO MYSQL
JSON to MySQL (transform.tools)
DROP DATABASE VUE;
create database if not exists vue;
use vue;
CREATE TABLE gameblog (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
text VARCHAR(255),
img VARCHAR(255)
);
insert into gameblog(title,text,img) values
("Games of the Month: surrealist solitaire puzzles","What’s that? You need more games? I hear you, anonymous hapi fan.We’ve reached the part of the year when games start coming out fast","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102184434_1.jpg"),
("Games of the Month: Puzzles!","Sometimes you need a good puzzle game, just something to throw all of your attention at and ignore anything else going on. Well if that sometime for you is right now, then you’re in luck because in this Games of the Month","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102184434_2.jpg"),
("The next hapi Creator Day is July 29th!","I don’t think I’m allowed to make the entire body of this post “Thenext itch.io Creator Day is taking place on Friday July 29th.” I mean it’s true, we are hosting the next itch.io Creator Day on Friday July 29th but I should probably write more here.","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102184434_3.jpg");
select * from gameblog;
CREATE TABLE game (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
text VARCHAR(255),
img VARCHAR(255),
price decimal(6,2) default 0,
web boolean default 0
# TODO 发布时间
# TODO 浏览量
# TODO 评论量
# TODO 热度综合指标
);
CREATE TABLE tag (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255)
);
CREATE TABLE gametag (
gameid INT,
tagid INT
);
# TODO 外键
insert into game(id,title,text,img,price,web) values
(1,"Late Night Mop","A haunted house cleaning simulator.","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102193135_1.png",0,0),
(2,"an average day at the cat cafe","A haunted house cleaning simulator.","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102193135_2.png",0,1),
(3,"Corebreaker","A fast-paced action-platform shooter game with roguelike elements.","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102193135_3.png",19.99,0),
(4,"Atuel","Traverse a surrealist landscape inspired by the Atuel River in Argentina.","https://xiaonenglife.oss-cn-hangzhou.aliyuncs.com/static/pic/2022/11/20221102193135_5.png",0,0);
insert into tag values
(1,"Difficult"),
(2,"Fast-Paced");
insert into gametag values
(3,1),
(3,2),
(4,1);
DELIMITER $$
CREATE PROCEDURE gamelist()
BEGIN
# TODO
END $$
DELIMITER ;
select a.title,a.text,img,price,web,if(group_concat(c.title separator "#") is null ,"", group_concat(c.title separator "#")) as tag from game a left join gametag b on a.id = b.gameid left join tag c on b.tagid = c.id group by a.id;
本地图片上传OSS图床得到静态资源的持久地址,我使用的是PicGo图床工具。

SQL TO GOLANG STRUCT
在线sql转golang struct - 球儿工具 (qetool.com)
config.go
为了方便mysql服务器的配置,写一个配置文件。
package mysql_vue
import "database/sql"
func GetMySQLDB() (db *sql.DB, err error) {
dbDriver := "mysql"
dbUser := "root"
dbPass := "sql2008"
dbName := "vue"
db, err = sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName)
return
}
gameblog.go
id暂时不需要,后期路由跳转需要用到,可以先注释。
package mysql_vue
import (
"encoding/json"
_ "github.com/go-sql-driver/mysql"
)
type Gameblog struct {
// ID int64 `db:"id" json:"id"`
Title string `db:"title" json:"title"`
Text string `db:"text" json:"text"`
Img string `db:"img" json:"img"`
}
func (Gameblog) TableName() string {
return "gameblog"
}
func (Gameblog) QueryGameblog() (json_ []byte, err error) {
// db, err := sql.Open("mysql", "root:sql2008@tcp(127.0.0.1:3306)/vue")
db, err := GetMySQLDB()
checkError(err)
defer db.Close()
// ^ 必须按照顺序选取,下面的Scan需要一一对应,如果多了或少了字段会导致Scan错误.
results, err := db.Query("SELECT title,text,img FROM gameblog order by id desc")
checkError(err)
var gameBlogs []Gameblog
for results.Next() {
var gameBlog Gameblog
err = results.Scan(&gameBlog.Title, &gameBlog.Text, &gameBlog.Img)
checkError(err)
gameBlogs = append(gameBlogs, gameBlog)
}
json_, err = json.Marshal(gameBlogs)
checkError(err)
return json_, nil
}
http
Simplify server.go
前面我们把评论相关的请求处理代码写在了 server.go,移出到 comment.go,并在init初始化中绑定各个请求路径处理函数。
comment.go
package server
import (
"fmt"
"net/http"
"strconv"
)
type Comment interface {
QueryComment(pid int64) (json_ []byte, err error)
InsertComment(uid, pid int64, text string) (json_ []byte, err error)
DeleteComment(id int64) error
}
func init() {
http.HandleFunc("/insertComment", insertComment)
http.HandleFunc("/deleteComment", deleteComment)
http.HandleFunc("/queryComment", queryComment)
}
func insertComment(w http.ResponseWriter, r *http.Request) {
....
}
func deleteComment(w http.ResponseWriter, r *http.Request) {
....
}
func queryComment(w http.ResponseWriter, r *http.Request) {
....
}
gameblog.go
接口用于确保某个数据库对象实现了处理函数,否则编译不通过。
package server
import (
"fmt"
"net/http"
)
type Gameblog interface {
QueryGameblog() (json_ []byte, err error)
}
func init() {
http.HandleFunc("/queryGameblog", QueryGameblog)
}
func QueryGameblog(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
fmt.Fprintf(w, "Only GET Method")
return
}
json, err := gameblog.QueryGameblog()
if err != nil {
fmt.Fprintf(w, "Error Delete")
return
}
fmt.Fprint(w, string(json))
}
server.go
package server
import (
"log"
"net/http"
mysql_vue "wolflong.com/vue_http/lib/mysql"
sq3_vue "wolflong.com/vue_http/lib/sqlite"
)
var comment Comment = sq3_vue.Comment{}
var gameblog Gameblog = mysql_vue.Gameblog{}
func StartServer() {
err := http.ListenAndServe(":1314", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
postman test api
使用 postman 测试当前接口。

Axios
修改 HomeView.vue 的选项卡api,在 created 钩子函数添加axios请求访问。
created() {
this.axios
.get("queryGameblog")
.then((response) => {
if (!response.data) {
this.gameBlog = [];
return;
}
this.gameBlog = response.data;
})
.catch((err) => {
console.log(err);
});
},

gamelist.go
查询语句使用两次左连接,并用 group_concat 聚合函数,聚合 tag,分解tag的过程可以从服务端迁移到客户端进行降低性能消耗。
package mysql_vue
import (
"encoding/json"
"strings"
)
type Gamelist struct {
// ID int64 `db:"id" json:"id"`
Title string `db:"title" json:"title"`
Text string `db:"text" json:"text"`
Img string `db:"img" json:"img"`
Price float64 `db:"price" json:"price"`
Tag []string `db:"tag" json:"tag"` // 新添加
Web bool `db:"Web" json:"web"`
}
// type Tag struct {
// ID int64 `db:"id" json:"id"`
// Title string `db:"title" json:"title"`
// }
func (Gamelist) QueryGamelist() (json_ []byte, err error) {
db, err := GetMySQLDB()
checkError(err)
defer db.Close()
results, err := db.Query(`select a.title,a.text,img,price,web,if(group_concat(c.title separator "#") is null ,"", group_concat(c.title separator "#")) as tag from game a left join gametag b on a.id = b.gameid left join tag c on b.tagid = c.id group by a.id;`)
checkError(err)
var GameList []Gamelist
for results.Next() {
var g Gamelist
var tag string
err = results.Scan(&g.Title, &g.Text, &g.Img, &g.Price, &g.Web, &tag)
g.Tag = strings.Split(tag, "#") // 这里暂且由服务端完成分解
checkError(err)
GameList = append(GameList, g)
}
json_, err = json.Marshal(GameList)
checkError(err)
return json_, nil
}
HTTP
gamelist.go
package server
import (
"fmt"
"net/http"
)
type Gamelist interface {
QueryGamelist() (json_ []byte, err error)
}
func init() {
http.HandleFunc("/queryGamelist", QueryGamelist)
}
func QueryGamelist(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
fmt.Fprintf(w, "Only GET Method")
return
}
json, err := gamelist.QueryGamelist()
if err != nil {
fmt.Fprintf(w, "Error Delete")
return
}
fmt.Fprint(w, string(json))
}
server.go
添加语句 var gamelist Gamelist = mysql_vue.Gamelist{}

Axios
this.axios
.get("queryGamelist")
.then((response) => {
if (!response.data) {
this.latestGames.games = [];
this.mostFeatureGames.games = [];
return;
}
this.latestGames.games = response.data;
this.mostFeatureGames.games = response.data;
})
.catch((err) => {
console.log(err);
});

我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang的更多相关文章
- 我的Vue之旅 10 Gin重写后端、实现页面详情页 Mysql + Golang + Gin
第三期 · 使用 Vue 3.1 + Axios + Golang + Mysql + Gin 实现页面详情页 使用 Gin 框架重写后端 Gin Web Framework (gin-gonic.c ...
- 亿级用户下的新浪微博平台架构 前端机(提供 API 接口服务),队列机(处理上行业务逻辑,主要是数据写入),存储(mc、mysql、mcq、redis 、HBase等)
https://mp.weixin.qq.com/s/f319mm6QsetwxntvSXpKxg 亿级用户下的新浪微博平台架构 炼数成金前沿推荐 2014-12-04 序言 新浪微博在2014年3月 ...
- MySQL更改数据库表的存储引擎
MySQL更改数据库表的存储引擎 1.查看表的原存储引擎 show create table user; 'user', 'CREATE TABLE `user` (\n `id` int(11) N ...
- Java获取数据库表 字段 存储的部分数据
在浏览器页面,选中图片(可多选) >单击删除按钮. 重点是, 本数据库表TabHeBeiTianQi中 存在 同一id,对应的picLocalPath字段 存储了多张图片,图片地址用 逗号 ...
- 数据库表中MAX ID获取,确保每次调用没有重复工具类(NumberUtil)
下面这个类是获取数据库中一个字段的最大值.配置在数据库中. public class NoFactory { private final static Logger cLogger = Logger. ...
- Vue刷新页面VueX中数据清空了,怎么重新获取?
Vue刷新页面VueX数据清空了,怎么重新获取? 点击打开视频讲解更详细 在vue中刷新页面后,vuex中的数据就没有了,这时我们要想使用就要重新获取数据了, 怎么在刷新后重新获取数据呢??? 这时我 ...
- mysql关于数据库表的水平拆分和垂直拆分
最初知道水平垂直分表的时候是刚参加工作不久的时候,知道了这个概念,但是公司用户量和数据量始终没上来,所以也没用到过,知道有一天到了一家新公司后,这些才被应用到实际开发中,这里我就大概说说关于水平和垂直 ...
- 用MySQL创建数据库和数据库表
1.使用SHOW语句找出在服务器上当前存在什么数据库: mysql> SHOW DATABASES; +----------+ | Database | +----------+ | mysql ...
- MySQL基于左右值编码的树形数据库表结构设计
MySQL基于左右值编码的树形数据库表结构设计 在关系型数据库中设计树形的数据结构一直是一个十分考验开发者能力的,最常用的方案有主从表方案和继承关系(parent_id)方案.主从表方案的最大缺点 ...
随机推荐
- 基于vue的脚手架开发与发布到npm仓库
什么是脚手架 在项目比较多而且杂的环境下,有时候我们想统一一下各个项目技术栈或者一些插件/组件的封装习惯,但是每次从零开发一个新项目的时候,总是会重复做一些类似于复制粘贴的工作,这是一个很头疼的事情, ...
- Excel 统计函数(三):AVERAGE 和 AVERAGEA
AVERAGE 只能计算纯数值,如果引用的单元格是非数值,不会被计入总数:AVERAGEA 可以计算逻辑值.代表数字的文本等. 假如下列有一个表格,分别使用两种算术评价函数计算平均值. [过程]AVE ...
- 【小白必看】Redis手把手教你从零开始下载到安装,再到配置允许图形化工具远程连接(一)
一.Redis安装 本文暂时仅介绍Windows环境下Redis的安装. 由于Windows环境下没有.exe安装文件,这里我们使用"曲线救国"的.msi安装包帮助我们一站式解决安 ...
- 如何使用CSS伪类选择器
总览 CSS选择器允许你通过类型.属性.位于HTML文档中的位置来选择元素.本教程阐述了三个新选项:is().:where()和:has(). 选择器通常在样式表中使用.下面的示例会找到所有<p ...
- DS
树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...
- Typora 最后免费版本也不能用了?简单一招搞定
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 Typora是一款优秀的 Markdown 编辑 ...
- KingbaseES 如何开启并进入数据库
关键字: KingbaseES.sys_ctl.ksql 一.数据库启动前环境检测 1.1 查看kingbase用户环境变量配置 图1-1 查看.bashrc环境变量配置 1.2 应用环境变量 [ki ...
- java 类名后加变量名是什么意思?
回答这个问题我们需要先了解两个事情: A是一个类,我们如果对他进行实例化,需要这样写: A a = new A(); 详细解释一下这个语句,首先等号左边做的事情:在JVM栈内存(stack)中定义了一 ...
- linux使用iptables屏蔽ip地址
一.iptables命令介绍: netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,在安装系统的时 ...
- 《吐血整理》高级系列教程-吃透Fiddler抓包教程(22)-如何使用Fiddler生成Jmeter脚本-下篇
1.简介 今天这篇文章其实和上一篇差不多也是利用一个fiddler的插件进行Jmeter脚本的导出,开始宏哥想要合在一起写一篇文章,可是结果实践的时候,两个插件还是有区别的,因此为了不绕晕小伙伴或者童 ...