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

东莞微网站建设房屋装修设计培训学校

东莞微网站建设,房屋装修设计培训学校,淘宝购物网站,建设网站需要注意的事项用Yii1.1中典型的 blog 项目作为例子来学习Web应用应该不错。数据库 sqlite3,windows下可以下载 sqlite-tools-win-x64-*** (https://www.sqlite.org/download.htm),把下载的几个exe放到 %GOPATH%\bin 目录下,而该目…

用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}]}}

http://www.yayakq.cn/news/681057/

相关文章:

  • 黄山建设网站公司电话号码买域名的钱最后给了谁
  • 南沙区交通和建设局网站在线测网速
  • 如何在腾讯云做网站企业网站管理系统有哪些
  • 珠海建站论坛wordpress no.7
  • 自己如何创建一个网站关键词优化按天计费
  • 手机网站发展企业为什么做网站系统
  • 苏州绿叶网站建设青岛网站优化公司哪家好
  • 合肥哪家做网站不错软文推广一般发布在哪些平台
  • 郑州网站建设公司排行wordpress主题基本文件配置
  • 电商运营和网站运营对比百度指数可以用来干什么
  • 英语网站大全免费查询域名是否备案?
  • 安平县网站建设南京网站制作域名
  • 网站域名备案查询官网网页设计与网站建设论文
  • 电子规划书商务网站建设国内室内设计师排名
  • 电商网站开发方案wordpress初始设置密码
  • 太原如何做百度的网站wordpress 浮动导航插件
  • 免费ppt模板哪里找黔南seo
  • 专门 做鞋子团购的网站wordpress全站静态页面
  • 成都装修网站建设购物网站建设策划报告
  • 网站建设与数据库维护 pdf网站怎么做移动的图片
  • 东莞网站建设总结wordpress 自带的ajax
  • 如何用eclipse做网站h5网站建设服务
  • 学做网站学什么语言wap网站平台
  • 做网站被网警找wordpress一键关注
  • 上海php做网站定西做网站
  • 建设一个官方网站的费用做网盘搜索网站合法吗
  • 手机网站建设哪家专业济南网站建设飞鸟
  • 88建网站wordpress生成分类目录
  • 自己怎么做网站视频赚钱太原网站制作多少钱
  • 网站搭建模板兴仁市建设局网站