返回顶部
首页 > 资讯 > 后端开发 > GO >Gin+Gorm实现CRUD的实战
  • 179
分享到

Gin+Gorm实现CRUD的实战

Gin Gorm CRUD 2023-02-03 09:02:32 179人浏览 独家记忆
摘要

目录简介:开发环境:一、Gin0. 快速入门:1. 基准测试2. Gin的特性与JSONiter:二、GORM0. 特性与安装:三、Navicat连接数据库结构体定义与优化CRUD接

简介:

Q:Gin和Gorm都是干什么的?有什么区别?

A:Gin 和 Gorm 是 Go 编程语言中流行的开源库。但是,它们服务于不同的目的,通常在 WEB 开发项目中一起使用。

Gin 是一个用于构建 Http 服务器的 web 框架。它提供了一个简单易用的 api,用于处理 HTTP 请求和响应、路由、中间件和其他常见的 web 应用程序所需的功能。它以其高性能和简约为特点,提供了轻量级和灵活的解决方案来构建 web 服务器。

Gorm 是 Go 的一个 ORM(对象关系映射)库。它提供了一个简单易用的 API,用于与数据库交互、处理数据库迁移和执行常见的数据库操作,如查询、插入、更新和删除记录。它支持多种数据库后端,包括 Mysqlpostgresqlsqlite 等。

总而言之, Gin 是用于处理 HTTP 请求和响应、路由、中间件和其他与网络相关的东西的 web 框架,而 Gorm 则是用于与数据库交互并执行常见数据库操作的 ORM 库。它们通常一起使用,来处理 HTTP 请求/响应并在 web 开发项目中存储或获取数据。

开发环境:

一、Gin

0. 快速入门:

package main

import (
	"encoding/json"
	"net/http"

	"GitHub.com/gin-gonic/gin"
	"github.com/thinkerou/favicon"
)

// 中间件(拦截器),功能:预处理,登录授权、验证、分页、耗时统计...
// func myHandler() gin.HandlerFunc {
// 	return func(ctx *gin.Context) {
// 		// 通过自定义中间件,设置的值,在后续处理只要调用了这个中间件的都可以拿到这里的参数
// 		ctx.Set("usersesion", "userid-1")
// 		ctx.Next()  // 放行
// 		ctx.Abort() // 阻止
// 	}
// }

func main() {
	// 创建一个服务
	ginServer := gin.Default()
	ginServer.Use(favicon.New("./Arctime.ico")) // 这里如果添加了东西然后再运行没有变化,请重启浏览器,浏览器有缓存

	// 加载静态页面
	ginServer.LoadhtmlGlob("templates
	// 看到后端的实时响应里面接收到数据就可以了

	// 处理表单请求 这些都是支持函数式编程,Go语言特性,可以把函数作为参数传进来
	ginServer.POST("/user/add", func(ctx *gin.Context) {
		username := ctx.PostForm("username")
		passWord := ctx.PostForm("password")
		ctx.JSON(http.StatusOK, gin.H{
			"msg":      "ok",
			"username": username,
			"password": password,
		})
	})

	// 路由
	ginServer.GET("/test", func(ctx *gin.Context) {
		// 重定向 -> 301
		ctx.Redirect(301, "https://conqueror712.gitee.io/conqueror712.gitee.io/")
	})
	// http://localhost:8081/test

	// 404
	ginServer.NoRoute(func(ctx *gin.Context) {
		ctx.HTML(404, "404.html", nil)
	})

	// 路由组暂略

	// 服务器端口,用服务器端口来访问地址
	ginServer.Run(":8081") // 不写的话默认是8080,也可以更改
}

API用法示例https://gin-gonic.com/zh-cn/docs/examples/

1. 基准测试

Q:基准测试是什么?

A:基准测试,也称为性能测试或压力测试,是一种用于测量系统或组件性能的测试。基准测试的目的是了解系统或组件在特定条件下的性能,并将结果与其他类似系统或组件进行比较。基准测试可用于评估各种类型的系统和组件,包括硬件、软件、网络和整个系统。

Q:什么时候需要基准测试呀?

A:基准测试通常涉及在被测系统或组件上运行特定工作负载或任务,并测量吞吐量、延迟时间、CPU使用率、内存使用率等各种性能指标。基准测试的结果可用于识别瓶颈和性能问题,并做出有关如何优化系统或组件以提高性能的明智决策。

有许多不同类型的基准测试,每种类型都有自己的指标和工作负载。常见的基准测试类型包括:

  • 人工基准测试:使用人工工作负载来测量系统或组件的性能。
  • 真实世界基准测试:使用真实世界的工作负载或场景来测量系统或组件的性能。
  • 压力测试:旨在将系统或组件推到极限,以确定在正常使用条件下可能不明显的性能问题

重要的是要知道基准测试不是一次性的活动,而是应该定期进行的活动,以评估系统的性能并检测随时间的消耗。

Q:什么样的基准测试结果是我们想要的呀?

A:

  • 在一定的时间内实现的总调用数,越高越好
  • 单次操作耗时(ns/op),越低越好
  • 堆内存分配 (B/op), 越低越好
  • 每次操作的平均内存分配次数(allocs/op),越低越好

2. Gin的特性与Jsoniter:

Gin v1 稳定的特性:

  • 零分配路由。
  • 仍然是最快的 http 路由器和框架。
  • 完整的单元测试支持。
  • 实战考验。
  • API 冻结,新版本的发布不会破坏你的代码。
  • Gin 项目可以轻松部署在任何云提供商上。

Gin 使用 encoding/json 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 jsoniter。

$ go build -tags=jsoniter .

Jsoniter是什么?

  • json-iterator是一款快且灵活的JSON解析器,同时提供JavaGo两个版本。
  • json-iterator是最快的JSON解析器。它最多能比普通的解析器快10倍之多
  • 独特的iterator api能够直接遍历JSON ,极致性能、零内存分配
  • 从dsljson和jsonparser借鉴了大量代码。

下载依赖:go get github.com/json-iterator/go

二、GORM

0. 特性与安装:

  • 全功能 ORM
  • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
  • Create,Save,Update,Delete,Find 中钩子方法
  • 支持 PreloadJoins 的预加载
  • 事务,嵌套事务,Save Point,Rollback To Saved Point
  • Context、预编译模式、DryRun 模式
  • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
  • SQL 构建器,Upsert,数据库,Optimizer/Index/Comment Hint,命名参数,子查询
  • 复合主键,索引,约束
  • Auto Migration
  • 自定义 Logger
  • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、prometheus
  • 每个特性都经过了测试的重重考验
  • 开发者友好
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite

其他的补充内容:

  • Gorm是软删除,为了保证数据库的完整性

三、Navicat

新建连接 -> mysql -> 连接名随便 -> 密码随便 -> 双击左侧打开 -> 右键information_schema -> 新建数据库 -> 名称crud-list -> 字符集utf8mb4

这里如果打开的时候报错navicat 1045 - access denied for user 'root'@'localhost' (using password: 'YES'),则需要查看自己的数据库本身的问题

四、Gin+Gorm的CRUD

连接数据库

编写测试代码,成功运行即可,但是这个时候还不能查看数据库是否被创建,

如果要看我们需要定义结构体,然后定义表迁移,具体代码如下:

package main

import (
	"fmt"
	"time"

	// "gorm.io/driver/sqlite"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func main() {
	// 如何连接数据库 ? MySQL + Navicat
	// 需要更改的内容:用户名,密码,数据库名称
	dsn := "root:BqV?eGCc_1o+@tcp(127.0.0.1:3306)/crud-list?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

	fmt.Println("db = ", db)
	fmt.Println("err = ", err)

	// 连接池
	sqlDB, err := db.DB()
	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(100)
	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	sqlDB.SetConnMaxLifetime(10 * time.Second) // 10秒钟

	// 结构体
	type List struct {
		Name    string
		State   string
		Phone   string
		Email   string
		Address string
	}

	// 迁移
	db.AutoMigrate(&List{})

	// 接口
	r := gin.Default()

	// 端口号
	PORT := "3001"
	r.Run(":" + PORT)
}

定义好之后我们运行,没有报错并且在终端显示出来3001就是正确的,这个时候我们可以去Navicat里面查看crud-list下面的"表",刷新后发现有一个lists产生,那就是对的了。

但是这个时候我们存在两个问题:

  • 没有主键:在struct里添加gorm.Model来解决,Ctrl+左键可以查看model
  • 表里面的名称变成了复数:详见文档的高级主题-GORM配置里,在*db*, *err* *:=* gorm.Open(mysql.Open(dsn), *&*gorm.Config{})里面添加一段话即可

更改完成之后我们要先在Navicat里面把原来的表lists删掉才能重新创建,这个时候我们重新运行,就会发现表单里面多了很多东西

结构体定义与优化

例如:

`gorm:"type:varchar(20); not null" json:"name" binding:"required"`

需要注意的是:

  • 结构体里面的变量(Name)必须首字母大写,否则创建不出列,会被自动忽略
  • gorm指定类型
  • json表示json接收的时候的名称
  • binding required表示必须传入

CRUD接口

// 测试
r.GET("/", func(c *gin.Context) {
	c.JSON(200, gin.H{
		"message": "请求成功",
	})
})

编写完这一段之后运行代码,然后去postman里面新建一个GET接口127.0.0.1:3001然后send一下,出现请求成功就请求成功了。

增也是一样,写好之后直接用如下JSON来测试就可以:

{
	"name" : "张三",
    "state" : "在职",
    "phone" : "13900000000",
    "email" : "6666@qq.com",
    "address" : "二仙桥成华大道"
}

返回:

{
    "code": "200",
    "data": {
        "ID": 1,
        "CreatedAt": "2023-01-24T09:27:36.73+08:00",
        "UpdatedAt": "2023-01-24T09:27:36.73+08:00",
        "DeletedAt": null,
        "name": "张三",
        "state": "在职",
        "phone": "13900000000",
        "email": "6666@qq.com",
        "address": "二仙桥成华大道"
    },
    "msg": "添加成功"
}

这时候也可以在数据库里看到这条数据

删除也是一样,编写完运行之后添加一个DELETE接口,然后输入127.0.0.1:3001/user/delete/2之后send就可以看到返回了(前提是有数据)

{
    "code": 200,
    "msg": "删除成功"
}

如果是删除了不存在的id,就会返回

{
    "code": 400,
    "msg": "id没有找到,删除失败"
}

顺带一提,事实上这个代码还可以优化,这里的if else太多了,后面优化的时候有错误直接return

修改也是一样,示例:

{
	"name" : "张三",
    "state" : "离职",
    "phone" : "13900000000",
    "email" : "6666@qq.com",
    "address" : "二仙桥成华大道"
}

返回:

{
    "code": 200,
    "msg": "修改成功"
}

查询分为两种:

  • 条件查询
  • 分页查询

条件查询的话,直接写好了请求127.0.0.1:3001/user/list/王五

返回:

{
    "code": "200",
    "data": [
        {
            "ID": 3,
            "CreatedAt": "2023-01-24T10:06:25.305+08:00",
            "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
            "DeletedAt": null,
            "name": "王五",
            "state": "在职",
            "phone": "13100000000",
            "email": "8888@qq.com",
            "address": "八仙桥成华大道"
        }
    ],
    "msg": "查询成功"
}

全部 / 分页查询的话

譬如说请求是:127.0.0.1:3001/user/list?pageNum=1&pageSize=2

意思就是查询第一页的两个

返回:

{
    "code": 200,
    "data": {
        "list": [
            {
                "ID": 3,
                "CreatedAt": "2023-01-24T10:06:25.305+08:00",
                "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
                "DeletedAt": null,
                "name": "王五",
                "state": "在职",
                "phone": "13100000000",
                "email": "8888@qq.com",
                "address": "八仙桥成华大道"
            }
        ],
        "pageNum": 1,
        "pageSize": 2,
        "total": 2
    },
    "msg": "查询成功"
}

如果请求是:127.0.0.1:3001/user/list

返回:

{
    "code": 200,
    "data": {
        "list": [
            {
                "ID": 1,
                "CreatedAt": "2023-01-24T09:27:36.73+08:00",
                "UpdatedAt": "2023-01-24T09:55:20.351+08:00",
                "DeletedAt": null,
                "name": "张三",
                "state": "离职",
                "phone": "13900000000",
                "email": "6666@qq.com",
                "address": "二仙桥成华大道"
            },
            {
                "ID": 3,
                "CreatedAt": "2023-01-24T10:06:25.305+08:00",
                "UpdatedAt": "2023-01-24T10:06:25.305+08:00",
                "DeletedAt": null,
                "name": "王五",
                "state": "在职",
                "phone": "13100000000",
                "email": "8888@qq.com",
                "address": "八仙桥成华大道"
            }
        ],
        "pageNum": 0,
        "pageSize": 0,
        "total": 2
    },
    "msg": "查询成功"
}

完整代码如下:

package main

import (
	"fmt"
	"strconv"
	"time"

	// "gorm.io/driver/sqlite"
	"github.com/gin-gonic/gin"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

func main() {
	// 如何连接数据库 ? MySQL + Navicat
	// 需要更改的内容:用户名,密码,数据库名称
	dsn := "root:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true,
		},
	})

	fmt.Println("db = ", db)
	fmt.Println("err = ", err)

	// 连接池
	sqlDB, err := db.DB()
	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(100)
	// SetConnMaxLifetime 设置了连接可复用的最大时间。
	sqlDB.SetConnMaxLifetime(10 * time.Second) // 10秒钟

	// 结构体
	type List struct {
		gorm.Model        // 主键
		Name       string `gorm:"type:varchar(20); not null" json:"name" binding:"required"`
		State      string `gorm:"type:varchar(20); not null" json:"state" binding:"required"`
		Phone      string `gorm:"type:varchar(20); not null" json:"phone" binding:"required"`
		Email      string `gorm:"type:varchar(40); not null" json:"email" binding:"required"`
		Address    string `gorm:"type:varchar(200); not null" json:"address" binding:"required"`
	}

	// 迁移
	db.AutoMigrate(&List{})

	// 接口
	r := gin.Default()

	// 测试
	// r.GET("/", func(c *gin.Context) {
	// 	c.JSON(200, gin.H{
	// 		"message": "请求成功",
	// 	})
	// })

	// 业务码约定:正确200,错误400

	// 增
	r.POST("/user/add", func(ctx *gin.Context) {
		// 定义一个变量指向结构体
		var data List
		// 绑定方法
		err := ctx.ShouldBindJSON(&data)
		// 判断绑定是否有错误
		if err != nil {
			ctx.JSON(200, gin.H{
				"msg":  "添加失败",
				"data": gin.H{},
				"code": "400",
			})
		} else {
			// 数据库的操作
			db.Create(&data) // 创建一条数据
			ctx.JSON(200, gin.H{
				"msg":  "添加成功",
				"data": data,
				"code": "200",
			})
		}
	})

	// 删
	// 1. 找到对应的id对应的条目
	// 2. 判断id是否存在
	// 3. 从数据库中删除 or 返回id没有找到

	// Restful编码规范
	r.DELETE("/user/delete/:id", func(ctx *gin.Context) {
		var data []List
		// 接收id
		id := ctx.Param("id") // 如果有键值对形式的话用Query()
		// 判断id是否存在
		db.Where("id = ? ", id).Find(&data)
		if len(data) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "id没有找到,删除失败",
				"code": 400,
			})
		} else {
			// 操作数据库删除(删除id所对应的那一条)
			// db.Where("id = ? ", id).Delete(&data) <- 其实不需要这样写,因为查到的data里面就是要删除的数据
			db.Delete(&data)

			ctx.JSON(200, gin.H{
				"msg":  "删除成功",
				"code": 200,
			})
		}

	})

	// 改
	r.PUT("/user/update/:id", func(ctx *gin.Context) {
		// 1. 找到对应的id所对应的条目
		// 2. 判断id是否存在
		// 3. 修改对应条目 or 返回id没有找到
		var data List
		id := ctx.Param("id")
		// db.Where("id = ?", id).Find(&data) 可以这样写,也可以写成下面那样
		// 还可以再Where后面加上Count函数,可以查出来这个条件对应的条数
		db.Select("id").Where("id = ? ", id).Find(&data)
		if data.ID == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "用户id没有找到",
				"code": 400,
			})
		} else {
			// 绑定一下
			err := ctx.ShouldBindJSON(&data)
			if err != nil {
				ctx.JSON(200, gin.H{
					"msg":  "修改失败",
					"code": 400,
				})
			} else {
				// db修改数据库内容
				db.Where("id = ?", id).Updates(&data)
				ctx.JSON(200, gin.H{
					"msg":  "修改成功",
					"code": 200,
				})
			}
		}
	})

	// 查
	// 第一种:条件查询,
	r.GET("/user/list/:name", func(ctx *gin.Context) {
		// 获取路径参数
		name := ctx.Param("name")
		var dataList []List
		// 查询数据库
		db.Where("name = ? ", name).Find(&dataList)
		// 判断是否查询到数据
		if len(dataList) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "没有查询到数据",
				"code": "400",
				"data": gin.H{},
			})
		} else {
			ctx.JSON(200, gin.H{
				"msg":  "查询成功",
				"code": "200",
				"data": dataList,
			})
		}
	})

	// 第二种:全部查询 / 分页查询
	r.GET("/user/list", func(ctx *gin.Context) {
		var dataList []List
		// 查询全部数据 or 查询分页数据
		pageSize, _ := strconv.Atoi(ctx.Query("pageSize"))
		pageNum, _ := strconv.Atoi(ctx.Query("pageNum"))

		// 判断是否需要分页
		if pageSize == 0 {
			pageSize = -1
		}
		if pageNum == 0 {
			pageNum = -1
		}

		offsetVal := (pageNum - 1) * pageSize // 固定写法 记住就行
		if pageNum == -1 && pageSize == -1 {
			offsetVal = -1
		}

		// 返回一个总数
		var total int64

		// 查询数据库
		db.Model(dataList).Count(&total).Limit(pageSize).Offset(offsetVal).Find(&dataList)

		if len(dataList) == 0 {
			ctx.JSON(200, gin.H{
				"msg":  "没有查询到数据",
				"code": 400,
				"data": gin.H{},
			})
		} else {
			ctx.JSON(200, gin.H{
				"msg":  "查询成功",
				"code": 200,
				"data": gin.H{
					"list":     dataList,
					"total":    total,
					"pageNum":  pageNum,
					"pageSize": pageSize,
				},
			})
		}

	})

	// 端口号
	PORT := "3001"
	r.Run(":" + PORT)
}

到此这篇关于Gin+Gorm实战CRUD的文章就介绍到这了,更多相关Gin Gorm CRUD内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Gin+Gorm实现CRUD的实战

本文链接: https://lsjlt.com/news/194058.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Gin+Gorm实现CRUD的实战
    目录简介:开发环境:一、Gin0. 快速入门:1. 基准测试2. Gin的特性与Jsoniter:二、GORM0. 特性与安装:三、Navicat连接数据库结构体定义与优化CRUD接...
    99+
    2023-02-03
    Gin Gorm CRUD
  • gorm+gin实现restful分页接口的实践
    目录1. 定义分页struct 2. 数据表Model 3. 定义分页查询搜索的结构体 4. 分页和搜索数据查询5.例子代码 API处理分页看似简单,实际上暗藏危机.最常见的分页方式...
    99+
    2024-04-02
  • gorm+gin怎么实现restful分页
    本篇内容主要讲解“gorm+gin怎么实现restful分页”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“gorm+gin怎么实现restful分页”吧!API处理分页看似简单,实际上暗藏危机....
    99+
    2023-06-22
  • GO项目实战之Gorm格式化时间字段实现
    目录goshop开源项目的更新解决方法:补充:gorm时间格式化问题详解总结goshop开源项目的更新 备注:前面项目中用到的代码已经分享到GitHub中去了,并且以后所有项目中会出...
    99+
    2023-01-07
    golang格式化时间 gorm格式化时间字段 gorm使用
  • gORM操作MySQL的实现
    ORM 框架 ORM:Object  Relational   Mapping  —— 对象关系映射。 作用: 通过操作结构体对象...
    99+
    2024-04-02
  • Gin与Mysql实现简单Restful风格API实战示例详解
    目录Itworksmain.go编译运行数据库CURD增删改查增 查查询列表Query查询单条记录QueryRow改删组织代码封装模型方法Handler函数组织项目数据库处...
    99+
    2024-04-02
  • 基于GORM如何实现CreateOrUpdate
    这篇文章主要讲解了“基于GORM如何实现CreateOrUpdate”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于GORM如何实现CreateOrUpdate”吧!GORM 写...
    99+
    2023-07-04
  • Golang使用Gin创建RestfulAPI的实现
    目录基本要求设计API代码开发创建项目创建数据格式Restful API返回数据列表新增数据项返回指定数据今天学习下Go语言如何集成Gin框架编写Restful Web API的基本...
    99+
    2023-01-28
    Golang 创建Restful API Golang Gin创建Restful API
  • 用Python实现CRUD功能REST服
    最近内部需要实现一个新的HTTP REST服务,数据用JSON。打算用Python来做一个原型,用于比较和Java实现方案的具体差异,以前也没有Python实战经验,所以摸索过程如下。 首先定义协议,假定我们要实现一个群组成员管理的服务&#...
    99+
    2023-01-31
    功能 Python CRUD
  • Gin框架限流实现示例
    目录什么是限流为什么要进行限流Gin框架的限流实现测试总结完整代码什么是限流 限流是指通过一定的算法,对接口的请求进行限制,防止并发量过大,导致系统瘫痪或响应变慢的情况出现。 为什么...
    99+
    2023-03-19
    Gin框架限流
  • Gin框架限流如何实现
    本文小编为大家详细介绍“Gin框架限流如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Gin框架限流如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是限流限流是指通过一定的算法,对接口的请求进行...
    99+
    2023-07-05
  • gorm整合进go-zero的实现方法
    go-zero提供的代码生成器里面,没有提供orm框架操作,但是提供了遍历的缓存操作。但是gorm框架的话,没有比较好的缓存插件,虽然有一个gcache,但不支持gorm2.0版本。...
    99+
    2024-04-02
  • golang gorm的关系关联实现示例
    目录1. 关联1.1. 属于1.2. 包含一个1.3. 包含多个1.4. 多对多1.5. 多种包含1.6. 关联模式1. 关联 1.1. 属于 // `User`属于`Profile...
    99+
    2024-04-02
  • Gin框架之参数绑定的实现
    为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、...
    99+
    2024-04-02
  • MyBatis-Plus使用ActiveRecord(AR)实现CRUD
    目录1.什么是ActiveRecord(AR)?2.通过AR实现CRUD1.1insert1.2update1.3delete1.4select1.什么是ActiveRecord(A...
    99+
    2024-04-02
  • PythonPygame实战之飞机大战的实现
    目录导语一、环境安装1)各种素材(图片、字体等)2)运行环境二、代码展示1)文章思路2)附代码讲解3)主程序三、效果展示总结导语 三月疫情原因,很多地方都封闭式管理了! 在回家无聊的...
    99+
    2024-04-02
  • 将原生JDBC封装实现CRUD的案例
    将原生JDBC封装实现CRUD 1、项目结构 pom.xml加入依赖 2、思路 初步 1、加载数据库驱动连接数据库 2、sql语句 3、创建PreparedStatement对象...
    99+
    2024-04-02
  • 基于GORM实现CreateOrUpdate方法详解
    目录正文GORM 写接口原理CreateSaveUpdate & UpdatesFirstOrInitFirstOrCreate方案一:FirstOrCreate ...
    99+
    2024-04-02
  • axios gin的GET和POST请求实现示例
    目录axios-GET请求Gin-GET响应Vue-POST请求Gin-POST响应axios-GET请求 created() { console.log('...
    99+
    2024-04-02
  • axios gin的GET和POST请求怎么实现
    今天小编给大家分享一下axios gin的GET和POST请求怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作