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

知乎网站建设入门书建网站公司耳机套

知乎网站建设入门书,建网站公司耳机套,wordpress 问答功能,网页加速器推荐以下记录了使用go语言框架Beego#xff0c;Mysql数据库#xff0c;Redis数据库实现一个点菜/菜谱应用API的全过程。 技术方案 github地址 数据库设计 新建数据库#xff1a; CREATE DATABASE menu;新建数据表#xff1a; CREATE TABLE menu ( id int(10) unsigned NOT … 以下记录了使用go语言框架BeegoMysql数据库Redis数据库实现一个点菜/菜谱应用API的全过程。 技术方案 github地址 数据库设计 新建数据库 CREATE DATABASE menu;新建数据表 CREATE TABLE menu ( id int(10) unsigned NOT NULL AUTO_INCREMENT, title varchar(200) NOT NULL DEFAULT , content text NOT NULL, pictures varchar(1000) NOT NULL DEFAULT , tags varchar(1000) NOT NULL DEFAULT , status tinyint(4) NOT NULL DEFAULT 0, create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8; CREATE TABLE data (id int(10) unsigned NOT NULL AUTO_INCREMENT,menu_id int(10) unsigned NOT NULL DEFAULT 0,like_number int(10) NOT NULL DEFAULT 0,visit_number int(10) NOT NULL DEFAULT 0,order_number int(10) NOT NULL DEFAULT 0,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),UNIQUE KEY unique_menu (menu_id) ) ENGINEInnoDB DEFAULT CHARSETutf8 CREATE TABLE order_info (id int(10) unsigned NOT NULL AUTO_INCREMENT,menu_id_list varchar(200) NOT NULL DEFAULT ,status tinyint(4) NOT NULL DEFAULT 0,create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8; 生成models层 进入终端项目执行命令生成数据库表对应的models bee generate appcode -tablesdata -drivermysql -connroot:123456tcp(127.0.0.1:3306)/menu -level1 bee generate appcode -tablesorder_info -drivermysql -connroot:123456tcp(127.0.0.1:3306)/menu -level1 bee generate appcode -tablesmenu -drivermysql -connroot:123456tcp(127.0.0.1:3306)/menu -level1 生成data、menu、order_info对应的model文件 我们数据库设置了创建时间和更新时间的自动更新 配置环境变量连接数据库 conf/app.conf中添加 # Mysql setting mysqluser root mysqlpass root mysqlhost 127.0.0.1 mysqldb liuyan mysqlport 3306新建core文件用于数据库连接的核心代码 package modelsimport (fmtgithub.com/beego/beego/v2/client/ormbeego github.com/beego/beego/v2/server/web_ github.com/go-sql-driver/mysql )func Init() {username, err : beego.AppConfig.String(mysqlname)if err ! nil {fmt.Println(err:, err)}password, err : beego.AppConfig.String(mysqlpass)host, err : beego.AppConfig.String(mysqlhost)database, err : beego.AppConfig.String(mysqldb)port, err : beego.AppConfig.String(mysqlport)dsn : username : password tcp( host : port )/ database ?charsetutf8locLocalerr orm.RegisterDataBase(default, mysql, dsn)if err ! nil {fmt.Println(err::, err)} }之后在main.go中初始化数据库连接 package mainimport (menu_api/models_ menu_api/routersbeego github.com/beego/beego/v2/server/web )func init() {models.Init() }func main() {if beego.BConfig.RunMode dev {beego.BConfig.WebConfig.DirectoryIndex truebeego.BConfig.WebConfig.StaticDir[/swagger] swagger}beego.Run() }bee run . 没有打印错误则说明数据库连接成功  日志设置 新建logs/logs.go文件进行初始化日志 package logsimport (github.com/beego/beego/v2/core/logs )func Init() {// 设置日志模式为文件输出的目录logs.SetLogger(file, {filename:logs/menu.log}) }将日志模式设置为文件格式输出的目录为logs/menu.log(无需手动创建) 在main.go中初始化日志 bee run . 后会发现新建了文件logs/menu.log并且可以在其中发现项目打印的日志关于日志可以参考官方文档Welcome to Beego | Beego 核心逻辑 菜单逻辑 注册路由 新增逻辑 beego.NSNamespace(/menu,beego.NSInclude(controllers.MenuController{},),), models层已经自动构建只需要实现controller即可 新建controller/menu.go 查询列表查询详情增加更新方法 package controllersimport (encoding/jsonerrorsgithub.com/beego/beego/v2/core/logsbeego github.com/beego/beego/v2/server/webmenu_api/modelsstrings )type MenuController struct {beego.Controller }// Title GetList // Description get Menu List // Param query query string false Filter. e.g. col1:v1,col2:v2 ... // Param fields query string false Fields returned. e.g. col1,col2 ... // Param sortby query string false Sorted-by fields. e.g. col1,col2 ... // Param order query string false Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ... // Param limit query string false Limit the size of result set. Must be an integer // Param offset query string false Start position of result set. Must be an integer // Success 200 {object} models.Menu // router / [get] func (m *MenuController) GetList() {var fields []stringvar sortby []stringvar order []stringvar query make(map[string]string)var limit int64 10var offset int64// fields: col1,col2,entity.col3if v : m.GetString(fields); v ! {fields strings.Split(v, ,)}// limit: 10 (default is 10)if v, err : m.GetInt64(limit); err nil {limit v}// offset: 0 (default is 0)if v, err : m.GetInt64(offset); err nil {offset v}// sortby: col1,col2if v : m.GetString(sortby); v ! {sortby strings.Split(v, ,)}// order: desc,ascif v : m.GetString(order); v ! {order strings.Split(v, ,)}// query: k:v,k:vif v : m.GetString(query); v ! {for _, cond : range strings.Split(v, ,) {kv : strings.SplitN(cond, :, 2)if len(kv) ! 2 {m.Data[json] errors.New(Error: invalid query key/value pair)m.ServeJSON()return}k, v : kv[0], kv[1]query[k] v}}menList, err : models.GetAllMenu(query, fields, sortby, order, offset, limit)if err ! nil {logs.Error(Get Database Menu List Error, ERR:, err)m.Data[json] errors.New(Error: Get Database Menu Error)}m.Data[json] menListm.ServeJSON() }// Title Get // Description get menu by id // Param id path int true The key for staticblock // Success 200 {object} models.Menu // Failure 403 :id is empty // router /:id [get] func (m *MenuController) Get() {mid : 0if v, err : m.GetInt(:id); err nil {mid v}if mid ! 0 {menu, err : models.GetMenuById(mid)if err ! nil {logs.Error(Get Database Menu Error, ERR:, err)m.Data[json] err.Error()} else {m.Data[json] menu}}m.ServeJSON() }// Title CreateMenu // Description create menus // Param body body models.Meau true body for user content // Success 200 {int} models.Menu.Id // Failure 403 body is empty // router / [post] func (m *MenuController) Post() {var menu models.Menuerr : json.Unmarshal(m.Ctx.Input.RequestBody, menu)if err ! nil || menu.Title || menu.Content || menu.Pictures {if err ! nil {logs.Error(Add Database Menu Unmarshal Error, ERR:, err)} else {err errors.New(title or content or picture is not empty)}m.Data[json] err.Error()m.ServeJSON()return}mid, err : models.AddMenu(menu)if err ! nil {logs.Error(Add Database Menu Error, ERR:, err)m.Data[json] err.Error()m.ServeJSON()return}m.Data[json] map[string]int64{mid:: mid}m.ServeJSON() }// Title Update // Description update the menu // Param id path string true The menu_id you want to update // Param body body models.Menu true body for user content // Success 200 {object} models.Menu // Failure 403 :id is not int // router /:id [put] func (m *MenuController) Put() {mid, err : m.GetInt(:id)var menu models.Menuerr json.Unmarshal(m.Ctx.Input.RequestBody, menu)if err ! nil {logs.Error(Add Database Menu Error, ERR:, err)m.Data[json] err.Error()m.ServeJSON()return}menu.Id midif mid ! 0 {err : models.UpdateMenuById(menu)if err ! nil {m.Data[json] err.Error()} else {m.Data[json] update success}}m.ServeJSON() }订单逻辑 注册路由 新增逻辑 beego.NSNamespace(/order_info,beego.NSInclude(controllers.OrderInfoController{},),), 新建controller/order_info.go 查询列表查询详情增加更新方法 package controllersimport (encoding/jsonerrorsgithub.com/beego/beego/v2/core/logsbeego github.com/beego/beego/v2/server/webmenu_api/modelsstrings )type OrderInfoController struct {beego.Controller }// Title GetList // Description get OrderInfo List // Param query query string false Filter. e.g. col1:v1,col2:v2 ... // Param fields query string false Fields returned. e.g. col1,col2 ... // Param sortby query string false Sorted-by fields. e.g. col1,col2 ... // Param order query string false Order corresponding to each sortby field, if single value, apply to all sortby fields. e.g. desc,asc ... // Param limit query string false Limit the size of result set. Must be an integer // Param offset query string false Start position of result set. Must be an integer // Success 200 {object} models.OrderInfo // router / [get] func (o *OrderInfoController) GetList() {var fields []stringvar sortby []stringvar order []stringvar query make(map[string]string)var limit int64 10var offset int64// fields: col1,col2,entity.col3if v : o.GetString(fields); v ! {fields strings.Split(v, ,)}// limit: 10 (default is 10)if v, err : o.GetInt64(limit); err nil {limit v}// offset: 0 (default is 0)if v, err : o.GetInt64(offset); err nil {offset v}// sortby: col1,col2if v : o.GetString(sortby); v ! {sortby strings.Split(v, ,)}// order: desc,ascif v : o.GetString(order); v ! {order strings.Split(v, ,)}// query: k:v,k:vif v : o.GetString(query); v ! {for _, cond : range strings.Split(v, ,) {kv : strings.SplitN(cond, :, 2)if len(kv) ! 2 {o.Data[json] errors.New(Error: invalid query key/value pair)o.ServeJSON()return}k, v : kv[0], kv[1]query[k] v}}orderList, err : models.GetAllOrderInfo(query, fields, sortby, order, offset, limit)if err ! nil {logs.Error(Get Database OrderInfo List Error, ERR:, err)o.Data[json] errors.New(Error: Get Database OrderInfo Error)}o.Data[json] orderListo.ServeJSON() }// Title Get // Description get orderInfo by id // Param id path int true The key for staticblock // Success 200 {object} models.OrderInfo // Failure 403 :id is empty // router /:id [get] func (o *OrderInfoController) Get() {oid : 0if v, err : o.GetInt(:id); err nil {oid v}if oid ! 0 {orderInfo, err : models.GetOrderInfoById(oid)if err ! nil {logs.Error(Get Database OrderInfo Error, ERR:, err)o.Data[json] err.Error()} else {o.Data[json] orderInfo}}o.ServeJSON() }// Title CreateOrderInfo // Description create OrderInfo // Param body body models.OrderInfo true body for user content // Success 200 {int} models.OrderInfo.Id // Failure 403 body is empty // router / [post] func (o *OrderInfoController) Post() {var orderInfo models.OrderInfoerr : json.Unmarshal(o.Ctx.Input.RequestBody, orderInfo)if err ! nil || orderInfo.MenuIdList {if err ! nil {logs.Error(Add Database OrderInfo Unmarshal Error, ERR:, err)} else {err errors.New(title or content or picture is not empty)}o.Data[json] err.Error()o.ServeJSON()return}oid, err : models.AddOrderInfo(orderInfo)if err ! nil {logs.Error(Add Database OrderInfo Error, ERR:, err)o.Data[json] err.Error()o.ServeJSON()return}o.Data[json] map[string]int64{oid:: oid}o.ServeJSON() }// Title Update // Description update the OrderInfo // Param id path string true The menu_id you want to update // Param body body models.OrderInfo true body for user content // Success 200 {object} models.OrderInfo // Failure 403 :id is not int // router /:id [put] func (o *OrderInfoController) Put() {mid, err : o.GetInt(:id)var orderInfo models.OrderInfoerr json.Unmarshal(o.Ctx.Input.RequestBody, orderInfo)if err ! nil {logs.Error(Add Database OrderInfo Error, ERR:, err)o.Data[json] err.Error()o.ServeJSON()return}orderInfo.Id midif mid ! 0 {err : models.UpdateOrderInfoById(orderInfo)if err ! nil {o.Data[json] err.Error()} else {o.Data[json] update success}}o.ServeJSON() }​​​​​​ 数据更新 使用redis缓存定时任务的方式维护data数据库先存储在redis中再由定时脚本进行更新同步redis数据到mysql中。 1.安装redis包 go get github.com/gomodule/redigo/redis 2.配置环境变量 redis_host localhost redis_port 6379 redis_password   redis_db 0 3.redis初始化连接 func RedisContent() redis.Conn {redis_host, err : beego.AppConfig.String(redis_host)redis_port, err : beego.AppConfig.String(redis_port)redis_password, err : beego.AppConfig.String(redis_password)redis_db, err : beego.AppConfig.String(redis_db)if err ! nil {logs.Error(database get appConfig err, err)}Redis_pool : redis.Pool{MaxIdle: 1, //最大空闲连接数MaxActive: 10, // 最大连接数IdleTimeout: 180 * time.Second, //空闲连接超时时间Wait: true, // 超过最大连接数的操作:等待Dial: func() (redis.Conn, error) {c, err : redis.Dial(tcp, fmt.Sprintf(%s:%s, redis_host, redis_port))if err ! nil {return nil, err}if redis_password ! {if _, err : c.Do(AUTH, redis_password); err ! nil {c.Close()return nil, err}}if redis_db ! {if _, err : c.Do(SELECT, redis_db); err ! nil {c.Close()return nil, err}}return c, nil},}return Redis_pool.Get() }新建controller/common.go文件 逻辑redis的菜单ID的key加一并且添加到redis的菜单ID列表。 这个文件存放公共的function package controllersimport (beego github.com/beego/beego/v2/server/webmenu_api/modelstime )const (OptLikeNum like_numOptOrderNum order_numOptVisitNum visit_num )func getRedisKey() (string, string, error) {// 获取key配置numKey, err : beego.AppConfig.String(redis_menu_num_key)if err ! nil {return , , err}updateKey, err : beego.AppConfig.String(redis_menu_update_key)if err ! nil {return , , err}return numKey, updateKey, nil }func redisNumUpdate(mid string, operateType string) (error, interface{}) {numKey, updateKey, err : getRedisKey()if err ! nil {return err, nil}// like_numberconn, err : models.RedisContent()if err ! nil {return err, nil}defer conn.Close()newValue, err : conn.Do(HINCRBY, numKeymid, operateType, 1)if err ! nil {return err, nil}// TODO 确定是否为第一次1_, err conn.Do(SADD,updateKeytime.Now().Format(20060102), mid)if err ! nil {return err, nil}return nil, newValue }点赞数量更新redis 注册路由 新增逻辑 beego.NSNamespace(/data,beego.NSInclude(controllers.DataController{},),), 新建controller/data.go文件 实现点赞数量存储 package controllersimport (github.com/beego/beego/v2/core/logsbeego github.com/beego/beego/v2/server/web_ menu_api/models )type DataController struct {beego.Controller }// Title Update // Description update the menu // Param menu_id path string true The menu_id you want to update // Success 200 {int} 1 // Failure 403 :menu_id is not int // router /:menu_id [put] func (d *DataController) Put() {mid : d.GetString(:menu_id)// 更细rediserr, num : redisNumUpdate(mid, OptLikeNum)if err ! nil {logs.Error(Get AppConfig Error, ERR:, err)d.Data[json] err.Error()d.ServeJSON()return}d.Data[json] numd.ServeJSON() }更新订单数量和浏览量 浏览量主要在菜单详情接口中点击一次1 err, _ : redisNumUpdate(strconv.Itoa(mid), OptBrowseNum)if err ! nil {logs.Error(Get AppConfig Error, ERR:, err)// 不影响主流程不return} 订单数量主要在订单添加接口中下单一次1 下单在更新接口中改订单状态为已下单: // Title Update // Description update the OrderInfo // Param id path string true The menu_id you want to update // Param body body models.OrderInfo true body for user content // Success 200 {object} models.OrderInfo // Failure 403 :id is not int // router /:id [put] func (o *OrderInfoController) Put() {oId, err : o.GetInt(:id)var orderInfo models.OrderInfoerr json.Unmarshal(o.Ctx.Input.RequestBody, orderInfo)if err ! nil {logs.Error(Add Database OrderInfo Error, ERR:, err)o.Data[json] err.Error()o.ServeJSON()return}orderInfo.Id oIdif oId ! 0 {err : models.UpdateOrderInfoById(orderInfo)if err ! nil {o.Data[json] err.Error()} else {o.Data[json] update success}}if orderInfo.Status 1 {// 遍历菜单列表对每个菜进行加一操作menuIdList : strings.Split(orderInfo.MenuIdList, ,)for _, menuId : range menuIdList {err, _ redisNumUpdate(menuId, OptOrderNum)if err ! nil {logs.Error(Get AppConfig Error, ERR:, err)// 不影响主流程不return}}}o.ServeJSON() }同步redis数据到数据库 定时任务 func SyncDataFromRedisToMysql() error {numKey, updateKey, err : getRedisKey()if err ! nil {return err}// like_numberconn, err : models.RedisContent()if err ! nil {return err}defer conn.Close()// 获取集合数据menuIds, err : redis.Strings(conn.Do(SMEMBERS, updateKeytime.Now().Format(20060102)))if err ! nil {return err}for _, menuId : range menuIds {// 根据Id获取数据var fields []stringvar sortby []stringvar order []stringvar query map[string]string{MenuId: menuId,}var limit int64 10var offset int64ml, err : models.GetAllData(query, fields, sortby, order, offset, limit)if err ! nil {return err}// 根据menuId获取更新mysql数据values, err : redis.StringMap(conn.Do(HGETALL, numKeymenuId))if err ! nil {return err}// 先marshal再Unmarshalvar data models.Dataif len(ml) 0 ml ! nil {marshal, err : json.Marshal(ml[0])if err ! nil {return err}err json.Unmarshal((marshal), data)}likeNum, err : strconv.Atoi(values[OptLikeNum])orderNum, err : strconv.Atoi(values[OptOrderNum])visitNum, err : strconv.Atoi(values[OptVisitNum])data.LikeNumber likeNumdata.OrderNumber orderNumdata.VisitNumber visitNum// 如果找到则更新找不到则添加if len(ml) 1 || ml nil {mId, _ : strconv.Atoi(menuId)data.MenuId mId_, err models.AddData(data)} else {err models.UpdateDataById(data)}if err ! nil {return err}}return nil }main.go中设置协程五分钟刷新一次 func init() {logs.Init()models.Init()controllers.SyncDataFromRedisToMysql()go func() {for {// 每隔五分钟执行一次同步方法time.Sleep(5 * time.Minute)err : controllers.SyncDataFromRedisToMysql()if err ! nil {beeLogs.Error(Data SyncDataFromRedisToMysql Error:, err)} else {beeLogs.Info(time.Now(), SyncDataFromRedisToMysql Success)}}}() } 文件上传 需要上传图片到服务器 注册路由 新增逻辑 beego.NSNamespace(/common,beego.NSInclude(controllers.CommonController{},),), controller/commpn.go中新增逻辑 // router /upload [post] // Summary 上传图片 // Description 上传图片到服务器 // Accept multipart/form-data // Param image formData file true 图片文件 // Success 200 {string} success 上传成功 // Failure 400 {string} error 上传失败 // router /upload [post] func (c *CommonController) Post() {f, h, err : c.GetFile(image)if err ! nil {c.Ctx.WriteString(File upload failed: err.Error())return}ext : path.Ext(h.Filename)//验证后缀名是否符合要求var AllowExtMap map[string]bool map[string]bool{.jpg: true,.jpeg: true,.png: true,}if _, ok : AllowExtMap[ext]; !ok {c.Ctx.WriteString(后缀名不符合上传要求)return}//创建目录uploadDir : static/upload///构造文件名称rand.Seed(time.Now().UnixNano())randNum : fmt.Sprintf(%d, rand.Intn(9999)1000)hashName : md5.Sum([]byte(time.Now().Format(2006_01_02_15_04_05_) randNum))fileName : fmt.Sprintf(%x, hashName) ext//c.Ctx.WriteString( fileName )fpath : uploadDir fileNamedefer f.Close() //关闭上传的文件不然的话会出现临时文件不能清除的情况err c.SaveToFile(image, fpath)if err ! nil {c.Ctx.WriteString(fmt.Sprintf(%v, err))}}以上就是整体服务端的实现。 运行 生成路由  bee generate routers 生成swagger配置文件并运行 bee run -gendoctrue 访问swagger http://127.0.0.1:8080/swagger/#/ 接口如下
http://www.pierceye.com/news/510329/

相关文章:

  • 西宁微网站建设wordpress更新文章post.php错误
  • 网络营销网站平台有哪些众希网站建设
  • 网站建设营销的技巧公司招聘网站排行榜
  • 长治网站建设收费多少农村自建房设计图 户型图
  • 广州网站建设 骏域网站建设做搜狗网站优化首页软
  • 广州网站设计软件简约大方网站
  • 网站建设与管理专业好吗做国际贸易如何建网站
  • 小说百度风云榜上海seo网络推广渠道
  • 建设局网站打不开是什么原因wordpress客户端插件
  • 农业 网站源码网站制作产品优化
  • 企业公司网站制作建设怎么区分营销型网站
  • 如何选择顺德网站建设网站开发源代码
  • 北京城乡建设部网站网站页面是自己做还是使用模板
  • 网新企业网站管理系统厦门好景科技做网站
  • 手机网站开发语言深圳网站建设培训
  • wordpress做的视听网站怎么用ftp清空网站
  • 网站建设能干什么网页设计代码模板人物介绍
  • 桂阳网站设计做p2p投资理财的网站
  • 做学术论文的网站从化专业做网站
  • 从化网站制作狮山公司网站建设
  • 网站开发验证码图片不显示php 自动做网站点击量
  • 大连网站开发费多少钱合肥企业网站建设工作室
  • 小企业网站建设的基础知识wap网站 开发
  • 地方门户网站赚钱吗沈阳黑酷做网站建设优化公司怎么样
  • 佛山市seo网站设计工具内部网站建设软件下载
  • 深圳网站建设高端设计网站建设 补充协议
  • 枣阳网站建设 枣阳山水数码自己建网站备案
  • 网站网站制作多少钱共享看世界新域名
  • 网站空间 阿里云wordpress多站点403
  • 下载网站备案的核验单免费ppt模板下载红色