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

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工程

云女士的工程结构如下所示。

Gin目录结构

云女士的 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 表的增删改成功时返回内容如下所示。

Gin-增删改成功

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

Gin-查询图书

Gin-查询人物

Spring boot 快速搭建Crud工程

Spring Boot 基础就不介绍了

云女士基于 Gin 和 Gorm 搭建的 Crud 工程,我看完后内心扑哧一笑:不过如此。

那现在该轮到我表演了。首先给出整个工程结构图如下所示。

Springboot目录结构

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更加的开箱即用?

前言 隔壁组的云计算零零后女同事&#xff0c;后文简称 云女士 &#xff0c;非说 Go 的 Gin 框架比 Springboot 更加的开箱即用&#xff0c;我心想在 Java 里面 Springboot 已经打遍天下无敌手&#xff0c;这份底蕴岂是 Gin 能比。 但是云女士突出一个执拗&#xff0c;非我要…...

Java 中枚举的 toString 方法及其字段信息展示

在 Java 编程中&#xff0c;枚举&#xff08;enum&#xff09;是一种特殊的数据类型&#xff0c;用于定义一组固定的常量。枚举类型不仅限于简单的常量定义&#xff0c;还可以包含字段、方法以及构造函数&#xff0c;从而使其具备更强的表达能力。toString 方法是 Java 中所有对…...

Python数据分析(OpenCV视频处理)

处理视频我们引入的还是numpy 和 OpenCV 的包 引入方式如下&#xff1a; import numpy as np import cv2 我们使用OpenCV来加载本地视频&#xff0c;参数就是你视频的路径就可以 #加载视频 cap cv2.VideoCapture(./1.mp4) 下面我们进行读取视频 #读取视频 flag,frame cap.re…...

DocFlow票据AI自动化处理工具:出色的文档解析+抽取能力,提升企业文档数字化管理效能

目录 财务应付 金融信贷业务 近期&#xff0c;DocFlow票据自动化产品正式上线。DocFlow是一款票据AI自动化处理工具&#xff0c;支持不同版式单据智能分类扩展&#xff0c;可选功能插件配置流程&#xff0c;满足多样业务场景。 随着全球化与信息化进程&#xff0c;企业的文件…...

python编程Day15-UnitTest框架的介绍

框架 framework为了解决一类事情的功能集合 Unittest 框架 是 Python 自带的单元测试框架 自带的, 可以直接使用, 不需要单外安装 测试人员 用来做自动化测试, 作为自动化测试的执行框架, 即 管理和执行用例的 使用原因 能够组织多个用例去执行提供丰富的断言方法能够生成测试报…...

Linux——进程控制模拟shell

1.进程创建 我们在之前的文章中介绍过进程创建的方法&#xff0c;可以通过系统调用接口fork来创建新的进程。 fork在创建完新的子进程之后&#xff0c;返回值是一个pid&#xff0c;对于父进程返回子进程的pid&#xff0c;对于子进程返回0。fork函数后父子进程共享代码&#xff…...

OpenCV的图像矫正

一、原理 图像矫正的原理是透视变换&#xff0c;下面来介绍一下透视变换的概念。 透视变换&#xff08;Perspective Transform&#xff09;基于一个4对点的映射关系&#xff08;4个源点到4个目标点&#xff09;&#xff0c;通过这些点之间的映射&#xff0c;可以计算一个变换…...

基于php求职招聘系统设计

摘要 随着社会信息化时代的到来&#xff0c;如今人们社会的生活节奏普遍加快&#xff0c;人们对于工作效率的要求也越来越高&#xff0c;企业 举办招聘会耗时耗财&#xff0c;个人参加招聘会漫无目的寻找不到“方向”&#xff0c;网络搜索工作量目的性不强&#xff0c;信息量繁…...

并行口的基本概念

单片机的并行口结构包括多个并行I/O端口&#xff0c;用于与外部设备进行并行数据传输。这些端口能够直接读写外部存储器、显示设备、打印机等外设的数据&#xff0c;是单片机与外界交互的重要通道。在深入探讨之前&#xff0c;我们先简要了解下单片机的基本概念。 单片机&…...

(六)机器学习 - 正态数据分布

正态数据分布&#xff0c;也称为高斯分布&#xff08;Gaussian distribution&#xff09;&#xff0c;是一种在统计学中非常重要的概率分布。它描述了自然和社会科学中许多现象的分布情况&#xff0c;如人的身高、体重、智商等。正态分布的图形特征是中间高、两边低&#xff0c…...

电脑系统报错找不到d3dcompiler_47.dll怎么修复?怎么预防“d3dcompiler_47.dll”文件缺失?

“d3dcompiler_47.dll”文件缺失的修复与预防策略 在日常使用电脑软件&#xff0c;尤其是运行大型游戏或图形密集型应用时&#xff0c;我们可能会遇到一些令人困惑的系统报错。其中之一便是“找不到d3dcompiler_47.dll”的错误提示。这个错误不仅影响软件的正常运行&#xff0…...

Github 2024-12-12 Go开源项目日报Top10

根据Github Trendings的统计,今日(2024-12-12统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目10Go Ethereum: 以太坊Go语言官方实现 创建周期:3717 天开发语言:Go协议类型:GNU Lesser General Public License v3.0Star数量:4504…...

RIP协议

介绍 路由信息协议RIP&#xff08;Routing Information Protocol&#xff09;是基于距离矢量&#xff08;Distance-Vector&#xff09;算法的路由协议&#xff0c;它是一种较为简单的内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;。它的主要功能是帮助路…...

vue-router查漏补缺

一、动态路由匹配 1.带参数的动态路由匹配 import User from ./User.vue// 这些都会传递给 createRouter const routes [// 动态字段以冒号开始{ path: /users/:efg, component: User }, ]这种方式的路由会匹配到/users/abc或者/users/123,路径参数用冒号:表示&#xff0c;并…...

使用Flink CDC实现 Oracle数据库数据同步的oracle配置操作

使用Flink CDC实现 Oracle数据库数据同步的oracle配置操作&#xff0c;包括开启日志归档和用户授权。 flink官方参考资料&#xff1a; https://nightlies.apache.org/flink/flink-cdc-docs-master/zh/docs/connectors/flink-sources/oracle-cdc/ 操作步骤&#xff1a; 1.启用…...

mqtt.js 客户端封装

mqtt.js 客户端封装 没封装前使用 const client mqtt.connect(ws://10.10.20.9:9001) onMounted(() > {const topicList []const channelCount 12for(let i 0; i < channelCount; i) {topicList.push(/test/sendImage${i 1})}client.on(connect, () > {console…...

www.aws.training网站的账户密码如何修改

www.aws.training网站的账户密码如何修改 参加aws考试后, 账号密码如何修改呢? 是不是找了好久都找不到. 右上角, 我的账户, 点击注销. 然后会跳到页面: 点击那个网址链接, 进入新的页面,点安全: 右上角: 更改密码. 按提示来就好....

使用Python实现高性能数据存储

在数据驱动的时代&#xff0c;处理和存储海量数据已成为关键需求。高性能数据存储不仅能够确保数据的快速读写&#xff0c;还能提升系统的整体性能。Python作为一种灵活且功能强大的编程语言&#xff0c;提供了多种高效的数据存储解决方案。本文将详细介绍如何使用Python实现高…...

[已解决]nvm安装node.js 报错 拒绝访问此应用无法在你电脑上运行

报错如下&#xff1a; 出错背景&#xff1a; 心血来潮把node删掉重新安装&#xff0c;想用nvm来进行管理node 出错原因&#xff1a; npm下载失败、下载不完整 不完整的npm展示&#xff1a; 出错根本原因&#xff1a; 可能因为镜像源或者网络波动&#xff0c;导致node下载…...

图文检索(36):Decomposing Semantic Shifts for Composed Image Retrieval

Decomposing Semantic Shifts for Composed Image Retrieval 摘要方法3.1 前期准备3.2 视觉语言表示3.3 降级过程3.4 升级过程3.5 训练和推理 结论 发布时间&#xff08;2024 AAAI&#xff09; 标题&#xff1a;分解语义转换以实现组合图像检索 摘要 语义转换网络 (SSN)&…...

批量计算(Batch Processing)

批量计算&#xff08;Batch Processing&#xff09;是一种数据处理方式&#xff0c;指的是将大量任务或数据分批次进行处理&#xff0c;而不是实时处理每一个任务。这种处理方式通常在任务之间没有依赖关系时使用&#xff0c;可以大大提高计算效率和资源利用率。批量计算广泛应…...

Linux yum-config-manager命令异常

错误信息 使用 yum-config-manager命令时错误信息如下 sudo yum-config-manager \ > --add-repo \ > https://download.docker.com/linux/centos/docker-ce.repo sudo: yum-config-manager: command not found 解决办法 第一步&#xff1a; sudo yum -y install yum-u…...

【C++】关联存储结构容器-set(集合)详解

目录 一、基本概念 二、内部实现 三、常用操作 3.1 构造函数 3.2 插入操作 3.3 删除操作 3.4 查找操作 3.5 访问元素 3.6 容量操作 3.7 交换操作 四、特性 五、应用场景 结语 一、基本概念 set是C标准模板库&#xff08;STL&#xff09;中的一种关联容器&#xf…...

如何利用SPSS软件进行多组间显著性检验以abcd显示

1.SPSS软件中进行多组间的显著性检验 要在SPSS软件中进行多组间的显著性检验&#xff0c;并以abcd显示结果&#xff0c;你可以按照以下步骤操作&#xff1a; 数据准备&#xff1a; 确保你的数据已经正确输入SPSS&#xff0c;其中每行代表一个观测值&#xff0c;包含至少两列&a…...

C++ 之计时函数总结

C 之计时函数总结 总结Windows下C开发时的计时实现 1. clock() #include <time.h>   //引入头文件void main() {clock_t start, end;start clock();fun(); //需计时的函数end clock(); float t_cfloat(end-start)/CLOCKS_PER_SEC;cout << "func cos…...

仿dota2渲染--shader常见贴图含义(直观展示)

Properties {[Header(Texture)]_MainTex ("RGB:颜色 A:透贴", 2D) "white"{}_NormTex ("RGB:法线贴图", 2D) "bump" {}_MaskTex ("R:高光强度 G:边缘光强度 B:高光染色 A:高光次幂…...

NoSQL大数据存储技术测试(5)MongoDB的原理和使用

单项选择题 第1题 关于 MongoDB 集群部署下面说法不正确的是&#xff08;&#xff09; 已经不使用主从复制的模式 在实际应用场景中&#xff0c; Mongodb 集群结合复制集和分片机制 MongoDB 支持自动分片&#xff0c; 不支持手动切分 &#xff08;我的答案&#xff09; 每…...

视图、转发与重定向、静态资源处理

目录 视图 默认视图 视图机制原理 自定义视图 请求转发与重定向 静态资源处理 视图 每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性 可以通过 order 属性指定解析器的优先顺序&#xff0c;order 越小优先级越高 默认是最低优先级&#xff0c;Integer.MAX_…...

ThinkPHP 5.1 的模板布局功能

ThinkPHP 5.1 的模板布局功能&#xff0c;包括全局配置、模板标签以及动态方法布局三种方式。以下是对这三种方式的要点概括和补充&#xff0c;以便于更好地理解和使用&#xff1a; 方式一&#xff1a;全局配置方式 适用于全站使用相同布局的情况&#xff0c;配置简单且统一。…...

入门网络安全工程师要学习哪些内容【2025年寒假最新学习计划】

&#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 大家都知道网络安全行业很火&#xff0c;这个行业因为国家政策趋势正在大力发展&#xff0c;大有可为!但很多人对网络安全工程师还是不了解&#xff0c;不知道网…...

Redis Cluster 分片机制

Redis 集群是 Redis 提供的一种分布式实现&#xff0c;用于水平扩展数据存储能力。通过 Redis 集群&#xff0c;可以将数据分片存储在多个 Redis 节点上&#xff0c;同时提供高可用性和故障转移功能。 分片&#xff08;Sharding&#xff09;&#xff1a; Redis 集群将数据划分…...

LightRAG测试BUG

错误一&#xff1a; LightRAG无法回答错误&#xff1a; INFO:lightrag:kw_prompt result:{{"high_level_keywords": ["xxx", "xxx"],"low_level_keywords": ["xxx", "xxx", "xxx"] }} JSON parsing e…...

关于手柄摇杆的连线

由于时间实在是太久远了&#xff0c;我也忘记具体的连线了&#xff0c;只能提供当时的连线图片。...

运算符优先级和,|| 的介绍

运算符优先级 关系运算的优先级高于逻辑运算&#xff0c;所以需要加上小括号来改变 更详细的运算符优先级可以去MATLAB官网看 &运算的优先级高于|优先级&#xff1a; &&&#xff0c;|| 的介绍 我们知道&#xff0c;&运算时&#xff0c;若第一个为 0 0 0&…...

Excel的文件导入遇到大文件时

Excel的文件导入向导如何把已导入数据排除 入起始行&#xff0c;选择从哪一行开始导入。 比如&#xff0c;前两行已经导入了&#xff0c;第二次导入的时候排除前两行&#xff0c;从第三行开始&#xff0c;就将导入起始行设置为3即可&#xff0c;且不勾选含标题行。 但遇到大文…...

SQL Having用法

拿个业务场景说这个案例&#xff0c;比如我们有个表里面可能有批改过的数据&#xff0c;批改过得数据不会随着新批改的数据覆盖&#xff0c;而是逐条插入表中&#xff0c;如果想找出包含最早批改的数据和最新批改数据的话&#xff0c;那么我们就需要用到了havinng 用法,假设最开…...

【mysql优化 | 新增分区】

在同步其他系统的数据&#xff0c;大概每天有16w多&#xff0c;目前已经600多万条数据了&#xff0c;导致查询的时候特别慢。 因为是报表&#xff0c;而且是每天统计&#xff0c;所以我们可以按照日期进行分区。 ALTER TABLE table PARTITION BY RANGE (TO_DAYS(rsdate)) (PA…...

vue 组件之间的传值方式

一、父组件向子组件传值 父组件可以使用 props 将数据传递给子组件。 <!-- 父组件 --> <template><ChildComponent :message"parentMessage" /> </template><script> import ChildComponent from ./ChildComponent.vue;export defau…...

VScode执行任务

背景 在vscode 中 如果执行命令需要传递进来参数&#xff0c;那么直接通过命令行终端的方式不太方便。通过task 任务的方式来进行启动执行&#xff0c;降低反复输入参数等繁琐工作。 首先可以查看vscode 官方文档 task 启动 crtl shift p .vscode/task.json 示例 执行cp…...

以太网链路详情

文章目录 1、交换机1、常见的概念1、冲突域2、广播域3、以太网卡1、以太网卡帧 4、mac地址1、mac地址表示2、mac地址分类3、mac地址转换为二进制 2、交换机的工作原理1、mac地址表2、交换机三种数据帧处理行为3、为什么会泛洪4、转发5、丢弃 3、mac表怎么获得4、同网段数据通信…...

将PDF流使用 canvas 绘制然后转为图片展示在页面上(二)

将PDF流转为图片展示在页面上 使用 pdfjs-dist 库来渲染 PDF 页面到 canvas 上&#xff0c;然后将 canvas 转为图片 安装 pdfjs-dist 依赖 npm install pdfjs-dist 或者 yarn add pdfjs-dist创建一个组件来处理 PDF 流的加载和渲染 该组件中是一个包含 PDF 文件的 ArrayBuffer…...

若依集成Uflo2工作流引擎

文章目录 1. 创建子模块并添加依赖1.1 新建子模块 ruoyi-uflo1.2 引入 Uflo2 相关依赖 2. 配置相关 config2.1 配置 ServletConfig2.2 配置 UfloConfig2.3 配置 TestEnvironmentProvider 3. 引入Uflo配置文件4. 启动并访问 Uflo2 是由 BSTEK 自主研发的一款基于 Java 的轻量级工…...

CV(4)--边缘提取和相机模型

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 边缘提取&#xff08;涉及语义分割&#xff09;&#xff1a; 图象的边缘是指图象局部区域亮度变化显著的部分,也有正负之分&#xff0c;暗到亮为正 求边缘的幅度&#xff1a;sobel&#xff0c;Canny算子 图像分高频分量和低…...

使用html 和javascript 实现微信界面功能2

1.功能说明&#xff1a; 对上一篇的基础上进行了稍稍改造 主要修改点&#xff1a; 搜索功能: 在搜索框后面增加了搜索按钮。 搜索按钮调用performSearch函数来执行搜索操作。 表单形式的功能: 上传文件: 修改为表单形式&#xff0c;允许用户通过文件输入控件选择文件并上传。 …...

音视频入门基础:MPEG2-TS专题(12)—— FFmpeg源码中,把各个transport packet组合成一个Section的实现

一、引言 从《音视频入门基础&#xff1a;MPEG2-TS专题&#xff08;9&#xff09;——FFmpeg源码中&#xff0c;解码TS Header的实现》可以知道&#xff1a;FFmpeg源码中使用handle_packet函数来处理一个transport packet&#xff08;TS包&#xff09;&#xff0c;该函数的前半…...

数据结构Day一

1.思维导图 2.顺序表的创建 seq.h #ifndef __SEQ_H__ #define __SEQ_H__#define max 30 typedef int DataType; typedef struct {DataType data[max];int len; }seqList,*seqListPtr;seqListPtr seq_create();#endifseq.c #include <stdio.h> #include <stdlib.h&g…...

cpptoml介绍

cpptoml 是一个用于 C 的开源库&#xff0c;旨在提供对 TOML&#xff08;Toms Obvious, Minimal Language&#xff09;格式的支持。它允许开发者轻松地在 C 项目中读取、解析和生成 TOML 格式的配置文件。cpptoml 是一个轻量级、易于使用的库&#xff0c;适用于那些希望将 TOML…...

迭代器(转

package Scala4 //迭代器 object hd { def main(args: Array[String]): Unit { var li1 List(1, 2, 3, 4, 5, 6) //依次输出List的元素 //1.循环 //li1.foreach(println) //2.迭代器 //2.1创建一个迭代器&#xff08;iterator&#xff09; // val it1li1.iterator.take(3)/…...

鸿蒙元服务上架

鸿蒙元服务上架 一、将代码打包成 .app 文件1. 基本需求2. 生成密钥和证书请求文件3. 申请发布证书4. 申请发布Profile5. 配置签名信息6. 更新公钥指纹7. 打包项目成 .app 文件 二、发布元服务1. 进入应用信息页面2. 上传软件包3. 配置隐私协议4. 配置版本信息5. 提交审核&…...

查询三网话费余额接口,移动话费余额接口、电信话费余额接口、联通话费余额的接口+html前端查询UI界面

PHP是直接请求的接口&#xff0c;HTML代码也是直接请求的接口。如果HTML想上线运行&#xff0c;还是需要做下安全的。 下边是PHP代码 <?php // 定义API接口地址和参数 $apiUrl "https://api.taolale.com/api/Inquiry_Phone_Charges/get"; //API文档地址&…...