Go的Gin比java的Springboot更加的开箱即用?
前言
隔壁组的云计算零零后女同事,后文简称 云女士 ,非说 Go 的 Gin 框架比 Springboot 更加的开箱即用,我心想在 Java 里面 Springboot 已经打遍天下无敌手,这份底蕴岂是 Gin 能比。
但是云女士突出一个执拗,非我要 PK 一把, PK 内容就是她使用 Gin,而我使用 Springboot 快速搭建一个简单的 Crud 工程,最后让其他同事来评判哪个更开箱即用。我毫不犹豫就答应了,作为搭建 Springboot 学习工程的资深 Crud 选手,咱这份底气还是有的。
云女士选择使用 Gin + Gorm 来搭建,而我原本想选择 Springboot + MyBatis,后面转念一想,这 MyBatis 要写 XML 文件,指不定就因为这个被云女士嘲笑了,所以我把 MyBatis 替换为了 MyBatis-Plus,这就足够的简洁了吧。
正文
准备事项
既然是 Crud 工程,自然要准备好操作的表,我和云女士通过如下语句在各自的数据库中创建好了如下两张表。
CREATE TABLE people (id INT(11) PRIMARY KEY AUTO_INCREMENT,p_name VARCHAR(255) NOT NULL,p_age INT(11) NOT NULL
)CREATE TABLE book (id INT(11) PRIMARY KEY AUTO_INCREMENT,b_name VARCHAR(255) NOT NULL,b_price FLOAT NOT NULL
)
Gin快速搭建Crud工程
云女士的工程结构如下所示。

云女士的 go.mod 文件内容如下所示。
module gobasego 1.17require (github.com/gin-gonic/gin v1.6.0github.com/jinzhu/gorm v1.9.16github.com/sirupsen/logrus v1.9.3github.com/spf13/cast v1.5.1
)
云女士定义了两个结构体作为模型( Model ),book.go 文件内容如下所示。
package modelconst (BookTableName = "book"
)type Book struct {ID int64 `gorm:"column:id"`BookName string `gorm:"column:b_name"`BookPrice float64 `gorm:"column:b_price"`
}func (b *Book) TableName() string {return BookTableName
}
people.go 文件内容如下所示。
package modelconst (PeopleTableName = "people"
)type People struct {ID int64 `gorm:"column:id"`PeopleName string `gorm:"column:p_name"`PeopleAge int64 `gorm:"column:p_age"`
}func (p *People) TableName() string {return PeopleTableName
}
云女士补充道,TableName()方法是为模型指定对应的表名。
云女士为 book 表和 people 表分别定义了 Dao 接口,dao.go 文件内容如下所示。
package daoimport "gobase/model"type BookDao interface {AddBook(book *model.Book) errorUpdateBook(book *model.Book) errorDeleteBook(book *model.Book) errorListBookById(id uint) (*model.Book, error)
}type PeopleDao interface {AddPeople(book *model.People) errorUpdatePeople(book *model.People) errorDeletePeople(book *model.People) errorListPeopleById(id uint) (*model.People, error)
}
BookDao 接口对应的实现在book_dao_impl.go文件中,实现如下。
package daoimport ("github.com/jinzhu/gorm""gobase/model"
)type BookDaoImpl struct {DB *gorm.DB
}func (b *BookDaoImpl) AddBook(book *model.Book) error {if createResult := b.DB.Create(book); createResult.Error != nil {return createResult.Error}return nil
}func (b *BookDaoImpl) UpdateBook(book *model.Book) error {if saveResult := b.DB.Save(book); saveResult.Error != nil {return saveResult.Error}return nil
}func (b *BookDaoImpl) DeleteBook(book *model.Book) error {if deleteResult := b.DB.Delete(book); deleteResult.Error != nil {return deleteResult.Error}return nil
}func (b *BookDaoImpl) ListBookById(id uint) (*model.Book, error) {var book model.Bookif listResult := b.DB.Where("id = ?", id).First(&book); listResult.Error != nil {return nil, listResult.Error}return &book, nil
}
PeopleDao 接口对应的实现在people_dao_impl.go文件中,实现如下。
package daoimport ("github.com/jinzhu/gorm""gobase/model"
)type PeopleDaoImpl struct {DB *gorm.DB
}func (b *PeopleDaoImpl) AddPeople(people *model.People) error {if createResult := b.DB.Create(people); createResult.Error != nil {return createResult.Error}return nil
}func (b *PeopleDaoImpl) UpdatePeople(people *model.People) error {if saveResult := b.DB.Save(people); saveResult.Error != nil {return saveResult.Error}return nil
}func (b *PeopleDaoImpl) DeletePeople(people *model.People) error {if deleteResult := b.DB.Delete(people); deleteResult.Error != nil {return deleteResult.Error}return nil
}func (b *PeopleDaoImpl) ListPeopleById(id uint) (*model.People, error) {var people model.Peopleif listResult := b.DB.Where("id = ?", id).First(&people); listResult.Error != nil {return nil, listResult.Error}return &people, nil
}
要操作数据库,肯定需要数据库连接,云女士将数据库连接的管理实现在了mysql_connection_pool.go文件中,内容如下所示。
package mysqlimport ("fmt""github.com/jinzhu/gorm""gobase/dao""log""time"
)const (UserName = "root"PassWord = "root"Host = "192.168.101.8"Port = 3306Database = "gotest"MaxLifetime = 60 * time.SecondMaxIdletime = 30 * time.SecondMaxOpenconns = 6MaxIdleconns = 2Dialect = "mysql"
)type DataSouce struct {db *gorm.DB
}func NewDataSource() *DataSouce {var db *gorm.DBdsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Asia%%2FShanghai",UserName, PassWord, Host, Port, Database)db, err := gorm.Open(Dialect, dsn)if err != nil {log.Fatal(err.Error())}db.DB().SetConnMaxLifetime(MaxLifetime)db.DB().SetConnMaxIdleTime(MaxIdletime)db.DB().SetMaxOpenConns(MaxOpenconns)db.DB().SetMaxOpenConns(MaxIdleconns)return &DataSouce{db: db,}
}// BookDao 操作book表
func (d *DataSouce) BookDao() dao.BookDao {return &dao.BookDaoImpl{DB: d.db,}
}// PeopleDao 操作people表
func (d *DataSouce) PeopleDao() dao.PeopleDao {return &dao.PeopleDaoImpl{DB: d.db,}
}
云女士将路由写在了webservice.go文件中,内容如下。
package adapterimport ("github.com/gin-gonic/gin""gobase/mysql"
)func Init() error {dataSouce := mysql.NewDataSource()bookController := NewBookController(dataSouce)propleController := NewPropleController(dataSouce)engine := gin.Default()routerGroupBook := engine.Group("/book")routerGroupBook.POST("/add", bookController.AddBook)routerGroupBook.POST("/update", bookController.UpdateBook)routerGroupBook.POST("/delete", bookController.DeleteBook)routerGroupBook.POST("/list", bookController.ListBookById)routerGroupPeople := engine.Group("/people")routerGroupPeople.POST("/add", propleController.AddPeople)routerGroupPeople.POST("/update", propleController.UpdatePeople)routerGroupPeople.POST("/delete", propleController.DeletePeople)routerGroupPeople.POST("/list", propleController.ListPeopleById)return engine.Run()
}
其实除了绑定路由,云女士还在Init()函数中进行了简单的服务注入,也就是创建数据库连接池,然后将数据库连接池给到对应的 web 服务。
云女士将操作 book 表对应的 web 服务写在了book_controller.go文件中,其实现如下所示。
package adapterimport ("github.com/gin-gonic/gin""github.com/sirupsen/logrus""github.com/spf13/cast""gobase/model""gobase/mysql""net/http"
)type BookController struct {dataSource *mysql.DataSouce
}func NewBookController(dataSource *mysql.DataSouce) BookController {return BookController{dataSource: dataSource,}
}func (b *BookController) AddBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.AddBook(&book)if err != nil {logrus.Error("添加Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) UpdateBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.UpdateBook(&book)if err != nil {logrus.Error("更新Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) DeleteBook(ctx *gin.Context) {var book model.Bookif err := ctx.ShouldBind(&book); err != nil {logrus.Error("读取Book信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}bookDao := b.dataSource.BookDao()err := bookDao.DeleteBook(&book)if err != nil {logrus.Error("删除Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (b *BookController) ListBookById(ctx *gin.Context) {id := cast.ToUint(ctx.Query("id"))bookDao := b.dataSource.BookDao()book, err := bookDao.ListBookById(id)if err != nil {logrus.Error("查询Book失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, book)
}
云女士将操作 people 表对应的 web 服务写在了people_controller.go文件中,其实现如下所示。
package adapterimport ("github.com/gin-gonic/gin""github.com/sirupsen/logrus""github.com/spf13/cast""gobase/model""gobase/mysql""net/http"
)type PeopleController struct {dataSource *mysql.DataSouce
}func NewPropleController(dataSource *mysql.DataSouce) PeopleController {return PeopleController{dataSource: dataSource,}
}func (p *PeopleController) AddPeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.AddPeople(&people)if err != nil {logrus.Error("添加People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) UpdatePeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.UpdatePeople(&people)if err != nil {logrus.Error("更新People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) DeletePeople(ctx *gin.Context) {var people model.Peopleif err := ctx.ShouldBind(&people); err != nil {logrus.Error("读取People信息失败")ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}peopleDao := p.dataSource.PeopleDao()err := peopleDao.DeletePeople(&people)if err != nil {logrus.Error("删除People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, gin.H{"message": "success",})
}func (p *PeopleController) ListPeopleById(ctx *gin.Context) {id := cast.ToUint(ctx.Query("id"))peopleDao := p.dataSource.PeopleDao()people, err := peopleDao.ListPeopleById(id)if err != nil {logrus.Error("查询People失败", err)ctx.JSON(http.StatusInternalServerError, gin.H{"message": "failed",})return}ctx.JSON(http.StatusOK, people)
}
最后,云女士简单的展示了一下对 book 表和 prople 表的 Crud 操作。
book 表和 people 表的增删改成功时返回内容如下所示。

book 表和 people 表的查询成功时返回内容如下所示。


Spring boot 快速搭建Crud工程
Spring Boot 基础就不介绍了
云女士基于 Gin 和 Gorm 搭建的 Crud 工程,我看完后内心扑哧一笑:不过如此。
那现在该轮到我表演了。首先给出整个工程结构图如下所示。

POM 文件内容如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.1</version></parent><groupId>com.lee.javabase</groupId><artifactId>javabase</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.1.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies></project>
同样,定义 book 表和 people 表对应的实体类 Book 和 People,如下所示。
@Getter
@Setter
public class Book {@TableField("id")private int id;@TableField("b_name")private String bookName;@TableField("b_price")private float bookPrice;}@Getter
@Setter
public class People {@TableField("id")private int id;@TableField("p_name")private String peopleName;@TableField("p_age")private int peopleAge;}
然后定义定义接口,如下所示。
@Mapper
public interface BookMapper extends BaseMapper<Book> {
}@Mapper
public interface PeopleMapper extends BaseMapper<People> {
}
最后是对应的 Controller 实现, BookController 实现如下。
@Slf4j
@RestController
@RequestMapping("/book")
public class BookController {@Autowiredprivate BookMapper bookMapper;@PostMapping("/add")public ResponseEntity<String> addBook(@RequestBody Book book) {try {bookMapper.insert(book);return new ResponseEntity<>("添加图书成功", HttpStatus.OK);} catch (Exception e) {log.error("添加图书失败", e);return new ResponseEntity<>("添加图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/update")public ResponseEntity<String> updateBook(@RequestBody Book book) {try {bookMapper.updateById(book);return new ResponseEntity<>("更新图书成功", HttpStatus.OK);} catch (Exception e) {log.error("更新图书失败", e);return new ResponseEntity<>("更新图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/delete")public ResponseEntity<String> deleteBook(@RequestParam("id") int id) {try {bookMapper.deleteById(id);return new ResponseEntity<>("删除图书成功", HttpStatus.OK);} catch (Exception e) {log.error("删除图书失败", e);return new ResponseEntity<>("删除图书失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/list")public ResponseEntity<Book> listBook(@RequestParam("id") int id) {try {Book book = bookMapper.selectById(id);return new ResponseEntity<>(book, HttpStatus.OK);} catch (Exception e) {log.error("查询图书失败", e);return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);}}
}
PeopleController 实现如下所示。
@Slf4j
@RestController
@RequestMapping("/people")
public class PeopleController {@Autowiredprivate PeopleMapper peopleMapper;@PostMapping("/add")public ResponseEntity<String> addPeople(@RequestBody People people) {try {peopleMapper.insert(people);return new ResponseEntity<>("添加人物成功", HttpStatus.OK);} catch (Exception e) {log.error("添加人物失败", e);return new ResponseEntity<>("添加人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/update")public ResponseEntity<String> updatePeople(@RequestBody People people) {try {peopleMapper.updateById(people);return new ResponseEntity<>("更新人物成功", HttpStatus.OK);} catch (Exception e) {log.error("更新人物失败", e);return new ResponseEntity<>("更新人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/delete")public ResponseEntity<String> deletePeople(@RequestParam("id") int id) {try {peopleMapper.deleteById(id);return new ResponseEntity<>("删除人物成功", HttpStatus.OK);} catch (Exception e) {log.error("删除人物失败", e);return new ResponseEntity<>("删除人物失败", HttpStatus.INTERNAL_SERVER_ERROR);}}@PostMapping("/list")public ResponseEntity<People> listPeople(@RequestParam("id") int id) {try {People people = peopleMapper.selectById(id);return new ResponseEntity<>(people, HttpStatus.OK);} catch (Exception e) {log.error("查询人物失败", e);return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);}}
}
启动应用程序, book 表的 Crud 操作结果如下所示。

prople 表的 Crud 操作结果如下所示。

总结
我宣布,Springboot 就是快速搭建 Crud 工程的神。
其实,在基于 Gin 和 Gorm 搭建 Crud 工程时,云女士还是写得复杂了一点,但是我有幸看过她们云平台的项目的代码,云女士写得也没毛病,虽然是个简化版,但也是严格遵从她们项目的代码结构来实现的。
说回 Springboot,毫无疑问,无论是天然自带 Tomcat 或 Jetty ,还是和三方框架整合的各种 Starter 包,Springboot 都将开箱即用做到了极致,但是转念又一想,其实 Springboot 和 Gin 严格来说做比较没啥意义,就像 Java 和 Go 的比较一样,我觉得也没啥意义,各自的优势区间不一样,并且各自也都在相关的领域叱咤风云。
各位看官,你们觉得呢。
相关文章:
Go的Gin比java的Springboot更加的开箱即用?
前言 隔壁组的云计算零零后女同事,后文简称 云女士 ,非说 Go 的 Gin 框架比 Springboot 更加的开箱即用,我心想在 Java 里面 Springboot 已经打遍天下无敌手,这份底蕴岂是 Gin 能比。 但是云女士突出一个执拗,非我要…...
pickle常见Error解决
1. pickle OverflowError: cannot serialize a bytes object larger than 4 GiB 进行pickle.dump时出现上述错误,可以加上“protocol4”参数。依据:https://docs.python.org/3/library/pickle.html#data-stream-format 2. pickle EOFError: Ran out of…...
认识Java数据类型和变量
数据类型分类 基本数据类型(8个): 整数型 byte 8位 short 16位 int 32位 long 64位 默认整数类型是int类型 小数型/浮点型 float【单精度32位】 double【双进度64位】 字符型 char 16位 只能表示单个字符 布尔型 boolean 1位 只能有两个值 true 【真】 false 【…...
Qt开发技巧(二十四)滚动部件的滑动问题,Qt设置时区问题,自定义窗体样式不生效问题,编码格式问题,给按钮左边加个图,最小化后的卡死假象
继续记录一些Qt开发中的技巧操作: 1.滚动部件的滑动问题 再Linux嵌入式设备上,有时候一个页面的子部件太多,一屏放不下是需要做页面滑动,可以使用“QScrollArea”控件,拖来一个“QScrollArea”控件,将子部件…...
SHELL----正则表达式
一、文本搜索工具——grep grep -参数 条件 文件名 其中参数有以下: -i 忽略大小写 -c 统计匹配的行数 -v 取反,不显示匹配的行 -w 匹配单词 -E 等价于 egrep ,即启用扩展正则表达式 -n 显示行号 -rl 将指定目录内的文件打…...
44.5.【C语言】辨析“数组指针”和“指针数组”
目录 1.数组指针 2.指针数组 执行结果 底层分析 1.数组指针 从语文的角度理解,"数组"修饰"指针".因此数组指针是指针 例如以下代码 #include <stdio.h> int main() {char a[5] { "ABCDE" };return 0;} 其中a就是数组指针,因为数…...
node.js基础学习-express框架-路由及中间件(十)
一、前言 Express 是一个简洁、灵活的 Node.js Web 应用框架。它基于 Node.js 的内置 HTTP 模块构建,提供了一系列用于构建 Web 应用程序和 API 的功能,使开发者能够更高效地处理 HTTP 请求和响应,专注于业务逻辑的实现。 其特点包括简单易用…...
使用MSYS搭建linux开发环境踩坑笔记
前言: 使用linux系统或虚拟机进行嵌入式linux开发是常规方法; 使用MSYS是用于尝鲜和研究。 由于windows和linux的差异,使用MSYS代替Linux虚拟机会遇到很多坑。 主要原因在于: 1. windows和linux文件系统的差异:win不…...
vue3+ts+vite+ElementPlus上传进度条实时更新(UPLoad和progress)。
需求: 上传文件时,展示进度条实时更新: 下面是代码片段: <!-- 添加媒体弹窗 -- 上传 --><el-dialog v-model"centerDialogVisible" title"媒体信息" width"700" :close-on-click-modal"false&qu…...
AspNet WebAPI 模型绑定问题
继承System.Web.Http.ApiController的Action的Model如果被[Serializable]定义,会导致Model的字段无法绑定。 Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll [Serializable] public class Model {public string id { get; set; } }public MyA…...
Android 图形系统之七:SurfaceFlinger
一. 引言 什么是 SurfaceFlinger?SurfaceFlinger 的核心作用和地位?为什么需要了解 SurfaceFlinger? 二. SurfaceFlinger 的基本概念 Surface 和 SurfaceFlinger 的关系SurfaceFlinger 与图形渲染(OpenGL ES 和 Vulkan…...
14、鸿蒙学习——管理通知角标
针对未读的通知,系统提供了角标设置接口,将未读通知个数显示在桌面图标的右上角角标上。 通知增加时,角标上显示的未读通知个数需要增加。 通知被查看后,角标上显示的未读通知个数需要减少,没有未读通知时࿰…...
TongRDS分布式内存数据缓存中间件
命令 优势 支持高达10亿级的数据缓冲,内存优化管理,避免GC性能劣化。 高并发系统设计,可充分利用多CPU资源实现并行处理。 数据采用key-value多索引方式存储,字段类型和长度可配置。 支持多台服务并行运行,服务之间可互…...
[在线实验]-RabbitMQ镜像的下载与部署
镜像下载 docker的rabbitmq镜像资源-CSDN文库 加载镜像 docker load --input rabbitmq.tar 给镜像打标签 这里发现镜像名为none,需要给镜像重命名下 docker tag [镜像id] [新镜像名称]:[新镜像标签] docker tag ebaf409ffbe2 rabbitmq:management 运行镜像…...
Linux 系统文件描述符(File Descriptor)小白级介绍
1. 概述 Linux 遵循"一切皆文件"的理念。在 Linux 系统中,文件描述符是一个索引值(非负整数),指向内核为每个进程所维护的该进程打开文件的记录表。 如上所述,每个进程都维护着一张文件描述符表。 文件描述…...
【Verilog】实验二 数据选择器的设计与vivado集成开发环境
目录 一、实验目的 二、实验环境 三、实验任务 四、实验原理 五、实验步骤 top.v mux2_1.v 一、实验目的 1. 掌握数据选择器的工作原理和逻辑功能。 2. 熟悉vivado集成开发环境。 3. 熟悉vivado中进行开发设计的流程。 二、实验环境 1. 装有vivado的计算机。 2. Sw…...
IDL学习笔记(三)OMI数据处理。hdf5文件读取,图像反转,GeoTiff区别,月季年均值计算提取输出,单位转换,运行时间计算
modis Level 2 grid 数据是全球格网化数据。一天的数据全在其中。 modis Level 1 和 2 数据是一景一景的影像。 IDL学习笔记(三)OMI数据处理 hdf5文件读取单位转换,输出hdf5数据集的图像,并检查图像经纬度是否正确,若错…...
深入浅出:PHP中的数据类型全解析
文章目录 引言理解数据类型标量类型整数 (integer)浮点数 (float)布尔值 (boolean)字符串 (string) 复合类型数组 (array)对象 (object)资源 (resource)NULL 特殊类型Callable强制类型转换 实战案例总结与展望参考资料 引言 在编程的世界里,数据类型是构建任何应用…...
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出
要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出 要使用 OpenResty 创建一个接口,返回客户端的 IP 地址,并以 JSON 格式输出方案一解决方案(openresty使用cjson)说明:使…...
智慧油客:从初识、再识OceanBase,到全栈上线
今天,我们邀请了智慧油客的研发总监黄普友,为我们讲述智慧油客与 OceanBase 初识、熟悉和结缘的故事。 智慧油客自2016年诞生以来,秉持新零售的思维,成功从过去二十年间以“以销售产品为中心”的传统思维模式,转向“以…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
