当前位置: 首页 > news >正文

GoFrame学习随便记1

用Yii1.1中典型的 blog 项目作为例子来学习Web应用应该不错。数据库 sqlite3,windows下可以下载 sqlite-tools-win-x64-***  (https://www.sqlite.org/download.htm),把下载的几个exe放到  %GOPATH%\bin 目录下,而该目录在 %PATH% 环境变量中,因此,可以直接使用 sqlite3.exe。

安装 GoFrame 框架工具 gf:我们使用编译安装方式,先切换到 %GOPATH%\src,然后执行

git clone https://github.com/gogf/gf && cd gf/cmd/gf && go install

就会把 gf 安装到 %GOPATH%\bin 目录下,可以任意目录输入   gf  -v 验证。

用模板创建项目:先切换到 %GOPATH%\src,然后执行

gf init blogdemo -u

就会生成  %GOPATH%\src\blogdemo 项目目录。可以切换到项目根目录 blogdemo 后运行

gf  run  main.go

编译项目并运行。默认项目中有OpenAPI接口文档、Swagger接口文档和一个 /hello 接口例子。我们将在此基础上添砖加瓦。

我们先需要一个数据库。为了简单,使用 sqlite3 数据库:在项目根目录下执行 

sqlite3  blogdemo.db

在项目根目录生成数据库文件 blogdemo.db (实际应用可能需要仔细考虑将数据库放置在更合适位置),然后在 sqlite3 命令行下执行下述 sql 语句:

CREATE TABLE tbl_lookup
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,name VARCHAR(128) NOT NULL,code INTEGER NOT NULL,type VARCHAR(128) NOT NULL,position INTEGER NOT NULL
);CREATE TABLE tbl_user
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,username VARCHAR(128) NOT NULL,password VARCHAR(128) NOT NULL,email VARCHAR(128) NOT NULL,profile TEXT
);CREATE TABLE tbl_post
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,title VARCHAR(128) NOT NULL,content TEXT NOT NULL,tags TEXT,status INTEGER NOT NULL,create_time INTEGER,update_time INTEGER,author_id INTEGER NOT NULL,CONSTRAINT FK_post_author FOREIGN KEY (author_id)REFERENCES tbl_user (id) ON DELETE CASCADE ON UPDATE RESTRICT
);CREATE TABLE tbl_comment
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,content TEXT NOT NULL,status INTEGER NOT NULL,create_time INTEGER,author VARCHAR(128) NOT NULL,email VARCHAR(128) NOT NULL,url VARCHAR(128),post_id INTEGER NOT NULL,CONSTRAINT FK_comment_post FOREIGN KEY (post_id)REFERENCES tbl_post (id) ON DELETE CASCADE ON UPDATE RESTRICT
);CREATE TABLE tbl_tag
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,name VARCHAR(128) NOT NULL,frequency INTEGER DEFAULT 1
);INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Draft', 'PostStatus', 1, 1);
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Published', 'PostStatus', 2, 2);
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Archived', 'PostStatus', 3, 3);
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Pending Approval', 'CommentStatus', 1, 1);
INSERT INTO tbl_lookup (name, type, code, position) VALUES ('Approved', 'CommentStatus', 2, 2);INSERT INTO tbl_user (username, password, email) VALUES ('demo','$2a$10$JTJf6/XqC94rrOtzuF397OHa4mbmZrVTBOQCmYD9U.obZRUut4BoC','webmaster@example.com');
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('Welcome!','This blog system is developed using Yii. It is meant to demonstrate how to use Yii to build a complete real-world application. Complete source code may be found in the Yii releases.Feel free to try this system by writing new posts and leaving comments.',2,1230952187,1230952187,1,'yii, blog');
INSERT INTO tbl_post (title, content, status, create_time, update_time, author_id, tags) VALUES ('A Test Post', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 2,1230952187,1230952187,1,'test');INSERT INTO tbl_comment (content, status, create_time, author, email, post_id) VALUES ('This is a test comment.', 2, 1230952187, 'Tester', 'tester@example.com', 2);INSERT INTO tbl_tag (name) VALUES ('yii');
INSERT INTO tbl_tag (name) VALUES ('blog');
INSERT INTO tbl_tag (name) VALUES ('test');

可以执行 SELECT  *  FROM  tbl_lookup; 简单验证数据是否已经生成,最后  .quit 退出命令行。

GoFrame 能直接根据数据库表生成一些代码吗?答案是 Yes, it is。GoFrame对于代码生成工具,专门有一个配置文件   hack/config.yaml  (Yii2 中 migrate 使用 console 对应配置文件,而代码生成有专用Web客户端gii,还是要更方便一些),我们在这个文件中添加

gfcli:
.....................................gen:dao:- link: "sqlite::@file(blogdemo.db)"tables: "tbl_lookup,tbl_user,tbl_post,tbl_comment,tbl_tag"jsonCase: "CamelLower"removePrefix: "tbl_"

在项目根目录执行  gf  gen  dao ,就会在 internal/dao、internal/model/entity 和 internal/model/do 三个目录下生成文件。用 yii2 方式来理解,yii2的model 包含了这里的 entity和dao,entity差不多就是字段映射而已,dao 中可以额外添加对表的操作。而 do 和 yii2 的 search model中的字段映射部分比较接近。换句话说,如果没有额外自定义的表操作,这三个部分都是无聊的。

GoFrame 能生成 controller 吗?答案是肯定的。GoFrame 允许根据你设计的 API 来“反向”生成 controller: 我们在 api 目录下创建子目录 lookup,然后在 api/lookup 下创建子目录 v1,最后在 api/lookup/v1 下创建 lookup.go 文件

package v1import ("blogdemo/internal/model/entity""github.com/gogf/gf/v2/frame/g"
)type LookupGetListReq struct {g.Meta   `path:"/lookup" method:"get"`Id       int    `json:"id"       dc:"ID"`   //Name     string `json:"name"     dc:"名称"`   //Code     int    `json:"code"     dc:"代码"`   //Type     string `json:"type"     dc:"类别"`   //Position int    `json:"position" dc:"排序位置"` //
}type LookupGetListRes struct {List []*entity.Lookup `json:"list" dc:"条目列表"`
}

(注意:反引号字符串中最后不能是空格,gf 不能识别此类错误) 为了能自动生成 controller,上述结构体必须按命名规范来命名,即 Xxx + 操作 + Req/Res 。文件中至少要有一个 path 命名(如 /lookup),不然无法生成controller。在项目根目录执行  gf  gen  ctrl 后,不仅会在 internal/controller下创建带3个文件的 lookup 子目录,还会在 api/lookup下创建 lookup.go 接口定义文件。api/lookup/lookup.go接口定义文件定义了 ILookupV1 接口,该接口包含 LookupGetList方法(对应我们设计接口时所用的操作)。internal/controller/lookup下分别是基本空的 lookup.go文件,定义“空”类型 ControllerV1 和工厂方法 NewV1() 的文件 lookup_new.go文件,定义“空”类型所含方法LookupGetList(这个方法是我们需要修改成具体实际实现的) 的 lookup_v1_lookup_get_list.go 文件。

和 API / controller 相关的另一个部分是路由。我们需要在 internal/cmd/cmd.go 中加入

var (Main = gcmd.Command{.............Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {s := g.Server()s.Group("/", func(group *ghttp.RouterGroup) {group.Middleware(ghttp.MiddlewareHandlerResponse)group.Bind(hello.NewV1(),lookup.NewV1(),   // 加入这一句)})s.Run()return nil},}
)

意思差不多相当于让控制器 ControllerV1 处理对应路由。

GoFrame还有一个代码生成是根据具体业务逻辑代码生成服务接口代码。一些框架中其实这两个部分是不分的,统一为 service层。对于yii2来说,更是粗粒度的把业务逻辑直接放入model中的。我们在 internal/logic下创建子目录lookup,然后在 internal/logic/lookup下创建 lookup.go文件:

package lookupimport ("blogdemo/internal/dao""blogdemo/internal/model/entity""blogdemo/internal/service""context"
)type sLookup struct{}func init() {service.RegisterLookup(New())
}func New() *sLookup {return &sLookup{}
}func (s *sLookup) GetList(ctx context.Context) (list []*entity.Lookup, err error) {err = dao.Lookup.Ctx(ctx).OrderAsc(dao.Lookup.Columns().Code).OrderAsc(dao.Lookup.Columns().Id).Scan(&list)return
}

(注意:IDE可能会识别有些东西不存在,这是正常的,因为是反向去生成service接口文件的。注意,sLookup类型需要用小写s开头。) sLookup“空”类型拥有 GetList方法,它使用dao来获得数据(这个也是我们需要具体实现的)。init()初始化方法和工厂方法 New() 实现了依赖注入。执行 gf  gen  service,会在 internal/service下创建服务接口文件lookup.go。如果此前从来没有生成过,还会在 internal/logic生成 logic.go 接口实现注册文件(也就是用 import 触发 internal/logic/lookup/lookup.go中的init()。此前如果已经生成logic.go文件,只会更新该文件。)。

有了 logic 中 GetList 的具体实现,我们在 controller 中就可以调用这个实现来返回数据了。修改 internal/controller/lookup/lookup_v1_lookup_get_list.go:

package lookupimport ("context"v1 "blogdemo/api/lookup/v1""blogdemo/internal/service"
)func (c *ControllerV1) LookupGetList(ctx context.Context, req *v1.LookupGetListReq) (res *v1.LookupGetListRes, err error) {//return nil, gerror.NewCode(gcode.CodeNotImplemented)res = &v1.LookupGetListRes{}res.List, err = service.Lookup().GetList(ctx)return
}

到这里,还剩最后一个问题:gf 自身是包含了 sqlite驱动的,因此 hack/config.yaml中配置后就可以生成 dao/entity/do 代码,但我们的应用不会自动识别数据库驱动,需要引入并配置。在 main.go开头引入      _  "github.com/gogf/gf/contrib/drivers/sqlite/v2"   (可能需要 go get 一下,具体参考 https://github.com/gogf/gf/tree/master/contrib/drivers)。修改配置文件 manifest/config/config.yaml

.........................................
database:logger:path:   "temp/logs/sql"level:  "all"stdout: truectxKeys:  ["RequestId"]default:link:   "sqlite::@file(blogdemo.db)"debug:  true

最后,用浏览器访问 http://127.0.0.1:8000/lookup 将返回

{"code":0,"message":"","data":{"list":[{"id":1,"name":"Draft","code":1,"type":"PostStatus","position":1},{"id":4,"name":"Pending Approval","code":1,"type":"CommentStatus","position":1},{"id":2,"name":"Published","code":2,"type":"PostStatus","position":2},{"id":5,"name":"Approved","code":2,"type":"CommentStatus","position":2},{"id":3,"name":"Archived","code":3,"type":"PostStatus","position":3}]}}

相关文章:

GoFrame学习随便记1

用Yii1.1中典型的 blog 项目作为例子来学习Web应用应该不错。数据库 sqlite3,windows下可以下载 sqlite-tools-win-x64-*** (https://www.sqlite.org/download.htm),把下载的几个exe放到 %GOPATH%\bin 目录下,而该目…...

最新自动定位版本付费进群系统源码

更新内容: 1.在网站首页增加了付款轮播功能。 2.新增了城市定位功能,方便用户查找所在城市的相关信息。 3.对域名库及支付设置进行了更新和优化。 4.增加了一种图模板设置模式,简化了后台模板设置流程。 5.此外还进行了前后台的其他优化…...

freeswitch的一个性能问题

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 在fs的使用过程中,会遇到各种各样的问题,各种问题中,性能问题是最头疼的。 最近在测试某些场景的时候,压测会造成fs的内存占用持续升高,并在达到某个临界点的…...

各机构如何加强网络渗透、“渗透”防御

数据渗透,例如黑客攻击和“渗透”,或未经授权的信息传输。 联邦调查局、国家安全局以及网络安全和基础设施安全局最近的联合报告证明,网络安全仍然是当今国防部门面临的两个最大的网络威胁。 所谓的零日攻击尤其有害,因为组织在…...

Docker命令 常用中间件运维部署,方便构建自己服务

Tips:记录了如何安装不同中间件的Docker命令,帮助大家更方便的搭建自己服务,会不定期更新。 MySQL # Mysql 5版本: docker run -d -p 3306:3306 --privilegedtrue \ -v /itholmes/mysql/log:/var/log/mysql \ -v /itholmes/mysql…...

Android——gradle构建知识片-散装版

一、Gradle - Plugins插件库地址 Gradle - Plugins插件库地址https://plugins.gradle.org/ 二、将自己的代码Android Library发布到仓库Bintray、JCenter、JitPack 放弃JitPack,发布Android Library到Bintray、JCenter - 简书Bug:升级到gradle tools …...

3.3 Windows驱动开发:内核MDL读写进程内存

MDL内存读写是一种通过创建MDL结构体来实现跨进程内存读写的方式。在Windows操作系统中,每个进程都有自己独立的虚拟地址空间,不同进程之间的内存空间是隔离的。因此,要在一个进程中读取或写入另一个进程的内存数据,需要先将目标进…...

开源与闭源:驾驭大模型未来的关键决断

在数字化的时代洪流中,开源与闭源的选择不断成为技术界的重要分水岭。随着特斯拉CEO埃隆马斯克的言论及其决策,公开支持开源,并糅合商业理念与技术革新,使得这场辩论再次成为公众关注的焦点。那么,在这场关乎技术发展脉…...

面向对象成员之属性

属性:通过方法改造出来 # 1.编写时 # 方法上方写property # 方法参数:只有一个self # 2.使用时:无需加括号 对象.方法 # 3.应用场景:对于简单的方法,当无需传参且有返回值时,可以使用 property class Foo(object):def _init_(self):...propertydef start(self):return 1pr…...

第六十二周周报

学习目标: 一、实验 二、论文 学习时间: 2023.11.11-2023.11.17 学习产出: 实验 1、CB模块实验效果出来了,加上去效果不太行,后续实验考虑是否将CB模块换到其他地方 2、CiFAR100实验已完成,效果比Vi…...

【机器学习】 特征工程:特征预处理,归一化、标准化、处理缺失值

特征预处理采用的是特定的统计方法(数学方法)将数据转化为算法要求的数字 1. 数值型数据 归一化,将原始数据变换到[0,1]之间 标准化,数据转化到均值为0,方差为1的范围内 缺失值,缺失值处理成均值、中…...

【深度学习实验】网络优化与正则化(七):超参数优化方法——网格搜索、随机搜索、贝叶斯优化、动态资源分配、神经架构搜索

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、优化算法0. 导入必要的库1. 随机梯度下降SGD算法a. PyTorch中的SGD优化器b. 使用SGD优化器的前馈神经网络 2.随机梯度下降的改进方法a. 学习率调整b. 梯度估计修正 3. 梯度估计修正:动量法Momen…...

简单漂亮的首页

效果图 说明 这个首页我也是构思了很久&#xff0c;才想出这个界面&#xff0c;大家喜欢的话&#xff0c;可以拿走去使用 技术的话&#xff0c;采用的就是vue的语法&#xff0c;但是不影响&#xff0c;很多样式我都是直接手敲出来的 代码实现 标语 <!-- 标语 start-->&…...

SSM项目初始化流程与操作概念解释-SpringBoot简化版

文章目录 1.引入概念2.导入依赖3.项目配置4.依照SpringMVC框架构建项目 1.引入概念 例如某一个XX系统&#xff0c;该系统存在前台页面&#xff08;给用户直观看或使用&#xff09;&#xff0c;和后台页面&#xff08;给管理人员调整数据和权限&#xff09;。 这二个页面都通过…...

Angular 路由无缝导航的实现与应用(六)

Angular 是一种流行的前端开发框架&#xff0c;它提供了强大的路由功能&#xff0c;用于构建单页应用程序&#xff08;SPA&#xff09;。本文将介绍 Angular 路由的基本概念和使用方法&#xff0c;并通过具体的代码实例演示如何利用路由实现无缝的页面导航。 什么是 Angular 路…...

quickapp_快应用_tabBar

tabBar 配置项中配置tabBar(版本兼容)使用tabs组件配置tabBar语法示例问题-切换tab没有反应问题-数据渲染问题解决优化 问题-tab的动态配置 第三方组件tabbar 一般首页都会显示几个tab用于进行页面切换&#xff0c;以下是几种tab配置方式。 配置项中配置tabBar(版本兼容) 在m…...

PCL_点云分割_基于法线微分分割

一、概述 PCL_点云分割_基于法线微分分割_点云法向量微分-CSDN博客 利用不同的半径&#xff08;大的半径、小半径&#xff09;来计算同一个点的法向量差值P。判断P的范围&#xff0c;从而进行分割。 看图理解&#xff1a; 二、计算流程 1、计算P点小半径的法向量Ns 2、计…...

计算机毕业论文内容参考|基于深度学习的交通标识智能识别系统的设计与维护

文章目录 导文摘要前言绪论1课题背景2国内外现状与趋势3课题内容相关技术与方法介绍系统分析总结与展望导文 基于深度学习的交通标识智能识别系统是一种利用深度学习模型对交通标识进行识别和解析的系统。它可以帮助驾驶员更好地理解交通规则和安全提示,同时也可以提高道路交通…...

SELinux零知识学习十六、SELinux策略语言之类型强制(1)

接前一篇文章&#xff1a;SELinux零知识学习十五、SELinux策略语言之客体类别和许可&#xff08;9&#xff09; 二、SELinux策略语言之类型强制 SELinux策略大部分内容都是由多条类型强制规则构成的&#xff0c;这些规则控制被允许的使用权&#xff0c;大多数默认转换标志、审…...

轻量封装WebGPU渲染系统示例<34>-数据驱动之Json构建场景

场景和数据之间的互通&#xff1a; 场景数据化或者数据化场景&#xff0c;是当前的主流场景数据构成方式。方便传输方便交换甚至是交互。 内置数据互通机制更有利于用户在各种应用场合下实现具体的3D相关的应用需求。用户只需要关心标准的或者约定好的数据定义及操作方式就能方…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...