拆箱phper最适合入门的go框架beego

news2024/11/24 12:41:06

beego

beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API、Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,但是结合了 Go 本身的一些特性(interface、struct 嵌入等)而设计的一个框架。

为什么使用框架

上帝不可能让每一个人都满意,同样的,并不是所有人都喜欢框架,大概就是有三点吧,框架重,框架不灵活,框架有坑。其实如果写一个hello world,肯定是用不到框架的。框架并不是有人对自己的一堆代码起了个名字就叫框架了。如其说我们使用框架,不如说我们使用了一种规范,然后所有的开发人员一起遵守,另外一点就是开箱即用,解放开发人员,提高开发效率,还有框架提前弥补一些你可能忽略的或者没想到的漏洞,比如安全问题,日志格式等等。

为什么选择beego

beego作为go语言的框架,其实是很适合phper入门学习的。据说beego的作者也是从PHP跨入go语言行列的,而且参考了PHP的laravel框架的设计思想和目录设计。
同样的,和laravel有一样的通病,框架很重,都是追求大而全的思想,既然追求大而全,必然就舍弃了卓越的性能。我们不如先看一下框架目录
在这里插入图片描述
很典型的MVC架构,最为phper一看就感到亲切而熟悉。有人说,PHP转go,只需要一周,3天看go语法,3天看beego框架,周末休息一天,周一就可以飞速的crud了。

工具模块

就像laravel的artisan,beego也提供了工具,就是bee,先来看一下bee有哪些命令吧

USAGE
    bee command [arguments]

AVAILABLE COMMANDS

    version     Prints the current Bee version 查看版本号
    migrate     Runs database migrations 数据库迁移
    api         Creates a Beego API application 生成api框架
    bale        Transforms non-Go files to Go source files
    fix         Fixes your application by making it compatible with newer versions of Beego
    pro         Source code generator
    dev         Commands which used to help to develop beego and bee
    dlv         Start a debugging session using Delve
    dockerize   Generates a Dockerfile for your Beego application 通过生成Dockerfile文件实现应用docker化
    generate    Source code generator 自动化生成代码
    hprose      Creates an RPC application based on Hprose and Beego frameworks
    new         Creates a Beego application 创建一个项目
    pack        Compresses a Beego application into a single file 用来发布应用的时候打包,会把项目打包成 zip 包 mac上面打包linux 注意bee pack -be GOOS=linux
    rs          Run customized scripts
    run         Run the application by starting a local development server 在项目目录下执行编译项目
    server      serving static content over HTTP on port
    update      Update Bee 升级版本

Use bee help [command] for more information about a command.这就话很重要

快速入门

  • 安装go,下载地址点击下载
  • 设置GOROOT,GOPATH,PATH
 export GOROOT=/usr/local/go
 export GOPATH=/Users/goRoot:/Users/go
 export PATH=/usr/local/go/bin:/Users/goRoot/bin:$PATH
  • 安装好了,看一下版本
 $  go version
go version go1.17.8 darwin/amd64
  • 安装beego
go get -u github.com/astaxie/beego
go get -u github.com/beego/bee
  • 将GOPATH/bin加入$PATH中
$ echo 'export GOPATH="$HOME/go"' >> ~/.profile # 或者 ~/.zshrc, ~/.cshrc, 您所使用的sh对应的配置文件
# 如果您已经添加了 $GOPATH 变量
$ echo 'export PATH="$GOPATH/bin:$PATH"' >> ~/.profile # 或者 ~/.zshrc, ~/.cshrc, 您所使用的sh对应的配置文件
$ exec $SHELL
  • 上面操作完毕,就可以使用bee了,快速创建一个bee-demo的项目
 bee new bee-demo

在这里插入图片描述

动手部分

  • 这里为了更好的让大家了解,我不适用框架默认的,而是创建新的文件
  • 刚才说过,bee generate 是自动生成代码,我们来看看怎么使用吧
  • 先生成一个控制器
$  bee generate controller user
______
| ___ \
| |_/ /  ___   ___
| ___ \ / _ \ / _ \
| |_/ /|  __/|  __/
\____/  \___| \___| v2.0.2
2022/12/08 14:43:23 INFO     ▶ 0001 Using 'User' as controller name
2022/12/08 14:43:23 INFO     ▶ 0002 Using 'controllers' as package name
        create   /Users/zhangguofu/website/bee-demo/controllers/user.go
2022/12/08 14:43:23 SUCCESS  ▶ 0003 Controller successfully generated!

执行命令之后,我们就会发现生成了一个RESTful的controller
在这里插入图片描述
那么我们怎么让请求路由到这个文件呢,我们看一下main入口文件,发现有一行 _ "bee-demo/routers"说明 项目启动的时候会先初始化routers这个包,通过控制器和路由之间的映射关系,在项目启动时完成注册

  • 我们新起一个路由文件,名字叫web.go,并映射到刚才生成的user控制器,如果不指定方法,默认走Get方法
    在这里插入图片描述

项目下使用bee run启动项目,默认是8080端口,我们访问/web/index看看


GET http://localhost:8080/web/index

HTTP/1.1 200 OK
Server: beegoServer:2.0.0
Date: Thu, 08 Dec 2022 08:06:50 GMT
Content-Length: 11
Content-Type: text/plain; charset=utf-8

hello world

Response code: 200 (OK); Time: 25ms; Content length: 11 bytes
  • 路由的第二种方式
    我们刚才看到,在web.go路由文件里,有一行beego.Include(&controllers.UserController{}),那么我们能否在控制器中声明路由呢,因为include方法里面也有一个addWithMethodParams操作,实际上也是注册了路由,比如在控制器中声明Hello方法,使用路由/web/hello访问
// Hello @router /web/hello [get]
func (c *UserController) Hello() {
	c.Ctx.WriteString("i am Hello")

}

模板

如果是一个web应用,我们怎么在模板赋值呢

  • 首先新建一个view
 $ bee generate view /user
create   /Users/zhangguofu/website/bee-demo/views/user/index.tpl
        create   /Users/zhangguofu/website/bee-demo/views/user/show.tpl
        create   /Users/zhangguofu/website/bee-demo/views/user/create.tpl
        create   /Users/zhangguofu/website/bee-demo/views/user/edit.tpl

  • 修改原来的Get方法
    在这里插入图片描述
  • 访问
GET http://localhost:8080/web/index

HTTP/1.1 200 OK
Content-Length: 4
Content-Type: text/html; charset=utf-8
Server: beegoServer:2.0.0
Date: Thu, 08 Dec 2022 08:28:15 GMT

jack

操作数据库

相关配置文件

在操作数据库之前,我们要知道数据库配置在哪里,这里我们就看一下beego的配置文件,在项目目录的conf文件夹下有一个app.conf,通过beego.AppConfig.String("defaultdb")获取相关的配置

$ cat conf/app.conf 
#项目名字
appname = bee-demo
#项目运行端口
httpport = 8080
#指定运行环境 是dev还是prod
runmode = dev
#通过Ctx.Input.RequestBody获取数据
copyrequestbody = true
#开发环境配置文件
[dev]
    defaultdb = root:guofuBlog@tcp(127.0.0.1:3306)/youku?charset=utf8
#生成环境配置文件
[prod]
    defaultdb = root:guofuBlog@tcp(127.0.0.1:3306)/youku?charset=utf8


使用orm操作数据库

  • 我们先来创建一个user表bee generate migration user,或者手写SQL也可以,我这里使用bee命令创建,执行命令之后,生成文件bee-demo/database/migrations/20221209_105701_user.go
  • 接下来我们根据自己的需求补全这个文件的内容
package main

import (
	"github.com/beego/beego/v2/client/orm/migration"
)

// DO NOT MODIFY
type User_20221209_105701 struct {
	migration.Migration
}

// DO NOT MODIFY
func init() {
	m := &User_20221209_105701{}
	m.Created = "20221209_105701"

	migration.Register("User_20221209_105701", m)
}

// Run the migrations
func (m *User_20221209_105701) Up() {
	// use m.SQL("CREATE TABLE ...") to make schema update
	m.CreateTable("user", "innodb", "utf8mb4")
	m.PriCol("id").SetAuto(true).SetDataType("int").SetUnsigned(true)
	m.NewCol("username").SetDataType("varchar(255)")
	m.NewCol("password").SetDataType("varchar(255)")
	m.NewCol("created_at").SetDataType("datetime").SetDefault("NOW()")
	m.NewCol("updated_at").SetDataType("datetime").SetDefault("NOW()")
	m.SQL(m.GetSQL())

}

// Reverse the migrations
func (m *User_20221209_105701) Down() {
	// use m.SQL("DROP TABLE ...") to reverse schema update
	m.SQL("DROP TABLE IF EXISTS user")

}
  • 执行命令生成数据表bee migrate -driver=mysql -conn="root:guofuBlog@tcp(127.0.0.1:3306)/bee_db"

那么使用migrate有什么好处呢?

  • 我们看一下库,会发现有两个表,一个是我们创建的user表,一个是migrations表,里面记录了我们的建表语句,方便我们快速完成数据迁移

配置数据库

  • 我们在app.conf中加入bee_db库的链接配置beedb = root:guofuBlog@tcp(127.0.0.1:3306)/bee_db
  • 在main函数中完成数据库的初始化
func init() {
	defaultdb, _ := beego.AppConfig.String("beedb")
	fmt.Println(defaultdb)
	orm.RegisterDriver("mysql", orm.DRMySQL)
	orm.RegisterDataBase("default", "mysql", defaultdb)
	orm.Debug = true
}

增删改查

  • 以下操作遵循RESTful风格
添加数据
  • 添加路由,这里我们通过form表单传参的方式
	//获取列表 添加用户
	beego.Router("/user", &controllers.UserController{})
	//get:GetOne 请求方式:请求方法  更新 删除  获取单个用户
	beego.Router("/user/:id", &controllers.UserController{},"get:GetOne")
  • 创建modelbee generate model user -fields="name:string"
  • 修改控制器
type ReturnApi struct {
	//tag:json 表示返回json格式的字段名
	Code int `json:"code"`
	Msg  string `json:"msg"`
	Data interface{} `json:"data"`
}

func SuccessApi() *ReturnApi {
	return &ReturnApi{Code: 200,Data:""}
}
func FailedApi() *ReturnApi {
	return &ReturnApi{Code: 9999,Data:""}
}

func (c *UserController) Post() {

	username := c.GetString("username")
	password := c.GetString("password")
	//定义一个json返回失败和成功的结构体
	if username == "" || password == "" {
		data := FailedApi()
		data.Msg = "参数不全"
		log.Println(data)
		c.Data["json"] = &data
		c.ServeJSON()
		return
	}
	m := models.User{
		Username: username,
		Password: password,
	}
	id, err := models.AddUser(&m)
	if err != nil {
		data := FailedApi()
		data.Msg = "插入数据失败"
		data.Data = ""
		c.Data["json"] = data
		c.ServeJSON()
		return
	}
	data := SuccessApi()
	data.Msg = "插入成功"
	data.Data = id
	c.Data["json"] = data
	c.ServeJSON()
	return
}

在这里插入图片描述

  • 这是我们用bee model生成的model里面自带的方法,接下来我们使用原生sql写一下,分享一下model的代码
func AddUserRaw(username string,password string) (id int64,err error) {
	o := orm.NewOrm()
	res,errRes:=o.Raw("insert into User set username=?,password=? ", username, password).Exec()
	if errRes != nil {
		err=errors.New("插入失败")
		id=0
		return
	}
	err=nil
	id,_=res.LastInsertId()
	return
}
查询一条数据
func (c *UserController) GetOne() {
	id_str := c.Ctx.Input.Param(":id")
	id, _ := strconv.ParseInt(id_str, 10, 64)

	log.Println(id)
	if id < 1  {
		data := FailedApi()
		data.Msg = "该用户不存在"
		log.Println(data)
		c.Data["json"] = &data
		c.ServeJSON()
		return
	}
	data := SuccessApi()
	data.Msg = "获取成功"
	user, err := models.GetUserById(id)
	if err != nil {
		data := FailedApi()
		data.Msg = "该用未注册"
		log.Println(data)
		c.Data["json"] = &data
		c.ServeJSON()
		return
	}
	data.Data = user
	c.Data["json"] = &data
	c.ServeJSON()
	return

}

  • orm和原生写法
// GetUserById retrieves User by Id. Returns error if
// Id doesn't exist
func GetUserById(id int64) (v *User, err error) {
	o := orm.NewOrm()
	v = &User{Id: id}
	if err = o.QueryTable(new(User)).Filter("Id", id).RelatedSel().One(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetUserByIdRaw(id int64) (v *User, err error) {
	o := orm.NewOrm()
	v = &User{}
	err=o.Raw("select `id`,`username` from user where id=? limit 1",id).QueryRow(&v)
	if err != nil {
		return nil,err
	}
	return v, err
}

查列表

  • 路由beego.Router("/user/list", &controllers.UserController{},"get:GetAll")
  • 控制器

func (c *UserController) GetAll() {
	list:=models.GetAllUser()
	data := SuccessApi()
	data.Msg = "获取成功"
	data.Data=list
	log.Println(data)
	c.Data["json"] = &data
	c.ServeJSON()
	return
}
  • model
func GetAllUser() ([]User) {
	var (
		users []User
	)
	o := orm.NewOrm()
	qs := o.QueryTable(new(User))
	qs = qs.Filter("id__gt", 7)
	qs = qs.Limit(2)
	qs = qs.OrderBy("-id")
	qs.All(&users, "id", "username")
	return users
}

删数据

  • 路由 beego.Router("/user/:id", &controllers.UserController{}, "Delete:Delete")
  • 控制器
func (c *UserController) Delete() {
	id_str := c.Ctx.Input.Param(":id")
	id, _ := strconv.ParseInt(id_str, 10, 64)
	err:=models.DelUserRaw(id)
	if err != nil {
		data := FailedApi()
		data.Msg = "删除失败"
		log.Println(data)
		c.Data["json"] = &data
		c.ServeJSON()
		return
	}
	data := SuccessApi()
	data.Msg = "删除成功"
	log.Println(data)
	c.Data["json"] = &data
	c.ServeJSON()
	return
}
  • model

func DeleteUser(id int64) (err error) {
	o := orm.NewOrm()
	v := User{Id: id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Delete(&User{Id: id}); err == nil {
			fmt.Println("Number of records deleted in database:", num)
		}
	}
	return
}

func DelUserRaw(id int64) (err error) {
	o := orm.NewOrm()
	res, errRes := o.Raw("delete from  User where id=?",id).Exec()
	if errRes != nil {
		err = errors.New("插入失败")
		id = 0
		return
	}
	err = nil
	id, _ = res.LastInsertId()
	return
}

bee的其他命令

  • generate 命令
    这个命令是用来自动化的生成代码的,包含了从数据库一键生成 model,还包含了 scaffold 的,通过这个命令,让大家开发代码不再慢
    bee generate scaffold [scaffoldname] [-fields=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"]   
    // 此处是一个批处理命令,生成model,controller、view、doc以及生成数据迁移文件,并进行数据迁移
    // The generate scaffold command will do a number of things for you.
    // -fields: a list of table fields. Format: field:type, ...
    // -driver: [mysql | postgres | sqlite], the default is mysql
    // -conn:   the connection string used by the driver, the default is root:@tcp(127.0.0.1:3306)/test
    
    例子: bee generate scaffold post -fields="title:string,body:text" -conn="root:root@tcp(127.0.0.1:3306)/beego_api"
    例子中的命令会 根据-fields="title:string,body:text" 来创建model,controller、view、以及生成数据迁移文件,并进行数据迁移(即在数据库中生成对应的数据表)。以上操作都会询问yes或者no

bee generate model [modelname] [-fields=""]     // 根据fields列表来生成model文件
    // generate RESTful model based on fields
    // -fields: a list of table fields. Format: field:type, ...

bee generate controller [controllerfile]       // 生成controller文件(根据对应的model文件)
    // generate RESTful controllers

bee generate view [viewpath]                   // 生成view文件,
    // generate CRUD view in viewpath

bee generate migration [migrationfile] [-fields=""]        // 生成数据迁移文件
    // generate migration file for making database schema update
    // -fields: a list of table fields. Format: field:type, ...

bee generate docs                             // 生成文档
    // generate swagger doc file

bee generate test [routerfile]                // 根据路由生成测试用例(没试过)
    // generate testcase

bee generate appcode [-tables=""] [-driver=mysql] [-conn="root:@tcp(127.0.0.1:3306)/test"] [-level=3]    // 这里就是文章介绍的,根据数据表生成model文件等
    // generate appcode based on an existing database
    // -tables: a list of table names separated by ',', default is empty, indicating all tables
    // -driver: [mysql | postgres | sqlite], the default is mysql
    // -conn:   the connection string used by the driver.
    //         default for mysql:    root:@tcp(127.0.0.1:3306)/test
    //         default for postgres: postgres://postgres:postgres@127.0.0.1:5432/postgres
    // -level:  [1 | 2 | 3], 1 = models; 2 = models,controllers; 3 = models,controllers,router



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/108469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

路由信息协议RIP(计算机网络)

目录 路由选择协议 路由信息协议 RIP中的距离 RIP协议的具体算法 RIP协议路由表的更新 例题 距离向量算法 RIP 协议的要点 路由选择协议 路由器之间要互相不断交换网络拓扑和状态信息&#xff0c;根据信息求出到所有目的网络的最佳路由 用于交换路由信息&#xff0c;进…

软件测试实战教程系列—接口测试用例和报告模板|收藏版

文章目录 接口测试为什么会如此重要呢&#xff1f; 接口测试的必要性 获取接口相关信息 接口测试的流程 接口文档 是接口测试的参照&#xff0c;至少包括&#xff1a; 接口测试用例设计 接口测试用例模板 &#xff08;可根据项目实际情况设计增减&#xff09; 接口测试…

前端基础_组合多个图形

组合多个图形 在前面的实例中&#xff0c;我们看到使用Canvas API可以将一个图形重叠绘制在另一个图形上面&#xff0c;但图形中能够被看到的部分完全取决于以哪种方式进行组合&#xff0c;这时需要使用到Canvas API的图形组合技术。在HTML5中&#xff0c;只要用图形上下文对象…

模数转换器(ADC)

目录 一、简介&#xff1a; 二、主要特征 三、校准&#xff08;CLB&#xff09; 四、ADC时钟 五、ADCON开关 六、规则组和注入组 七、转换模式 八、注入通道管理 九、可编程的采样时间 十、外部触发 十一、温度传感器和内部参考电压 一、简介&#xff1a; 12位ADC是…

CSS -- 使用纯CSS实现旋转木马相册的效果

如果对3D转换不熟悉可以参考&#xff1a;CSS – CSS3中3D转换相关属性讲解&#xff08;translate3d&#xff0c;rotate3d&#xff0c;perspective&#xff0c;transform-style&#xff09; 如果对动画不熟悉可以参考&#xff1a;CSS – CSS3基础动画讲解 旋转木马图片相册 <…

centos 7安装mysql

一.安装之前检测系统是否有自带的MySQL(若是没有安装直接忽略该步骤) rpm -qa | grep mysql #检查是否安装过MySQL rpm -qa | grep mariadb #检查是否存在 mariadb 数据库&#xff08;内置的MySQL数据库&#xff09;&#xff0c;有则强制删除 rpm -e --nodeps mariadb-libs-…

信而泰BGP Flow Spec防攻击测试解决方案

随着互联网行业的迅猛发展&#xff0c;越来越多的业务都从线下走到了线上。互联网在给大家生活带来便利的同时也面临着防护自身安全的各种挑战。 DoS/DDoS攻击是对网络安全的重大威胁&#xff0c;攻击者通过多个控制端控制成千上万的攻击设备对同一个目的地址、网段或服务器同…

【触摸屏功能测试】昆仑通态MCGS——物联网功能测试

测试触摸屏&#xff1a; 型号&#xff1a;TPC7022Ni 测试内容&#xff1a;物联网产品设备的无线通信和远程调试功能 物联网 1、功能概述 物联网产品设备可通过无线通讯的方式&#xff0c;进行远程调试和操作。物联网产品设备支持以下功能&#xff1a; l 4G和WiFi通信 l 远…

m基于kmeans和SVM的网络入侵数据分类算法matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 首先计算整个数据集合的平均值点&#xff0c;作为第一个初始聚类中心C1&#xff1b; 然后分别计算所有对象到C1的欧式距离d&#xff0c;并且计算每个对象在半径R的范围内包含的对象个数W。 此时计…

非零基础自学Golang 第17章 HTTP编程(上) 17.2 HTTP客户端 17.2.3 发起GET请求

非零基础自学Golang 文章目录非零基础自学Golang第17章 HTTP编程(上)17.2 HTTP客户端17.2.3 发起GET请求第17章 HTTP编程(上) 17.2 HTTP客户端 17.2.3 发起GET请求 从现在开始我们将会学习如何使用Go语言模拟浏览器发起HTTP请求。 发起请求前需要创建一个请求对象&#xff…

WINDOWS下安装ORACLE客户端报错:无法访问临时位置

WINDOWS2016&#xff08;虚拟机&#xff09;安装oracle11g碰到“无法访问临时位置”的问题&#xff0c;详细信息如下&#xff1a; INS-30131] 执行安装程序验证所需的初始设置失败。 原因 - 无法访问临时位置。 操作 - 请确保当前用户具有访问临时位置所需的权限。 附加信息: …

【DETR目标检测】关键词:Decoder。Encoder。query向量。注意力机制。

声明:仅学习使用~ 目录 1、目标检测的基本思想2、整体网络架构3、位置信息初始化query向量4、注意力机制的作用方法5、训练过程的策略1、目标检测的基本思想 2015年,faster-rcnn; 2016年,YOLO; NMS:非极大值抑制; 2、整体网络架构 backbone 即先通过CNN 拿到每个pat…

Transformers18~ Diffusion

还是Transformers,来自 UC 伯克利的 William Peebles 以及纽约大学的谢赛宁撰文揭秘扩散模型中架构选择的意义&#xff0c;并为未来的生成模型研究提供经验基线。 近几年&#xff0c;在 Transformer 的推动下&#xff0c;机器学习正在经历复兴。过去五年中&#xff0c;用于自然…

【概述】请求报文在网络各层中的具体传输

请求报文在网络各层中的具体传输电脑中之间的通信&#xff0c;可以看成为两个应用进程之间的通信&#xff1b;一个请求从客户端到服务器端&#xff0c;通常需要经过三个阶段&#xff1a; 客户端路由转发阶段服务器端 客户端请求服务端 请求在客户端中每一层的具体传输数据 应…

LeetCode 322 周赛

2490. 回环句 句子 是由单个空格分隔的一组单词&#xff0c;且不含前导或尾随空格。 例如&#xff0c;"Hello World"、"HELLO"、"hello world hello world" 都是符合要求的句子。 单词 仅 由大写和小写英文字母组成。且大写和小写字母会视作不…

【Call for papers】2023年CCF-A类会议截稿日期(实时更新)

会议简称会议名称类别截稿日期链接S&P-2023IEEE Symposium on Security and Privacy网络与信息安全2022年12月2日Call for papersUSENIX ATC-2023USENIX Annul Technical Conference计算机体系结构/并行与分布计算/存储系统2023年1月12日Call for papersIJCAI-2023Internat…

H5后台读写CAD文件

说明 后台提供mxconvert.js程序&#xff0c;该程序使用JS编程&#xff0c;可以在后台实现读写CAD文件、读取CAD图纸数据等操作。 如何使用mxconvert.js转CAD图纸到梦想格式 1.Windows调用&#xff0c;进入 Bin\Release目录&#xff0c;命令行调用 node.exe mxconvert.js 1.d…

【推荐】动力锂电池及BMS系统介绍资料合集

锂动力电池是20世纪开发成功的新型高能电池。这种电池的负极是金属锂&#xff0c;正极用MnO2&#xff0c;SOCL2&#xff0c;(CFx)n等。70年代进入实用化。因其具有能量高、电池电压高、工作温度范围宽、贮存寿命长等优点&#xff0c;已广泛应用于军事和民用小型电器中&#xff…

部署AI平台 宝马集团正在掀起新一轮数字化改革浪潮

数字化转型作为当代企业创新求变的重要突破口&#xff0c;成为各行各业推进持续发展的大热趋势。但在企业的在数字化征程中&#xff0c;却暗藏多重陷阱&#xff0c;数据孤岛、标准不一、质量太差、治理滞后、安全隐患等挑战&#xff0c;如影随形。 近日&#xff0c;宝马集团宣布…

125页6万字智慧城市系统及智慧城市运营中心建设技术方案

目 录 1. 智慧城市系统概述 1.1 前言 1.2 什么是智慧城市&#xff1f; 1.3 智慧城市的总体目标 1.4 智慧城市如何建设 1.5 智慧城市组成和架构 1.6 智慧城市总体功能 1.6.1 城市运营中心门户 1.6.2 城市事件管理服务 1.6.3 城市运维管理服务 1.6.4 数据挖掘 1.6.4…