Go语言对于MySQL的基本操作
一.下载依赖
终端中输入:
go get -u github.com/go-sql-driver/mysql
导入包
import ("database/sql"_ "github.com/go-sql-driver/mysql" )
二.案例
package main//go get-u github.com/go-sql-driver/mysql 获取驱动
import ("database/sql""fmt"_ "github.com/go-sql-driver/mysql"
)var db *sql.DB
//根据数据库表中,有属性id,name,age,且id为插入时,自增1
var usergroup map[int]user = make(map[int]user, 100)type user struct {id intname stringage int
}func initDB() (err error) {//连接数据库 user:password@tcp(ip:port)/databasenamedsn := "root:123456@tcp(127.0.0.1:3306)/sql_test"db, err = sql.Open("mysql", dsn) //dsn格式不对这里会报错if err != nil {fmt.Printf("dsn: %s invaid! err:%v\n", dsn, err)return err}//判断一下是否连接成功err = db.Ping()if err != nil {fmt.Printf("open %s failed! err:%v\n", dsn, err)return err} else {fmt.Printf("open %s success!\n", dsn)}//设置数据库连接池的最大连接数,根据业务调整db.SetMaxOpenConns(10)db.SetMaxIdleConns(5) //最大闲置连接数return nil
}// 输入id,返回对应的user信息 查询单条记录
func queryOne(id int) (u user, err error) {//查询单条语句sqlstr := "select * from user where id=?" //?为占位符,在Query的时候可以用后续的参数进行填充rowObj := db.QueryRow(sqlstr, id) //从数据库连接池中拿去一个连接去进行查询//得到了rowObj必须调用Scan方法,因为该方法会释放数据库连接,把连接放回连接池,否则连接池最大连接用完,则会影响后续连接查询rowObj.Scan(&u.id, &u.name, &u.age)if rowObj == nil {fmt.Printf("query failed,err:%v\n", err)return u, err}return u, nil
}// 查询多行 读取到map中
func query() (err error) {sqlstr := "select * from user"rows, err := db.Query(sqlstr)if err != nil {fmt.Printf("query failed,err:%v\n", err)return}//记得关闭,放回连接池defer rows.Close()var u user//用一个for循环,把每次读到的行信息,存放到全局变量usergroup中,达到程序启动初始化的效果for rows.Next() {err = rows.Scan(&u.id, &u.name, &u.age)if err != nil {fmt.Printf("scan failed,err:%v\n", err)return}usergroup[u.id] = u}return nil
}// 插入一条学生数据,并且更新map id是主码,
//实际插入学生数据的时候,并不知道数据库中学号应该分配多少,所以在插入后得到返回的id,再更新map
func insert(u user) (id int64, err error) {sqlstr := "insert into user(name,age) values(?,?)"var res sql.Result//执行该语句res, err = db.Exec(sqlstr, u.name, u.age)if err != nil {fmt.Printf("insert failed,err:%v\n", err)return}//拿到插入的id,返回id, err = res.LastInsertId()if err != nil {fmt.Printf("insert failed,err:%v\n", err)return}return id, nil
}//删除指定id的user,实际上最好判断一下是否存在map中,这里就先不写了
func deleteUser(id int) (err error) {sqlstr := "delete from user where id=?"_, err = db.Exec(sqlstr, id)if err != nil {fmt.Printf("delete failed,err:%v\n", err)return err}delete(usergroup, id)return nil
}// 查询单条语句
func test01() {//查询学号为1的学生信息u, err := queryOne(1)if err != nil {fmt.Printf("query failed,err:%v\n", err)return}println(u.id, u.name, u.age)}// 程序初始化时,把user表中信息全部读取到map中
func readToMap() {//从数据库中读取user放入map中err := query()if err != nil {fmt.Printf("query failed,err:%v\n", err)return}
}// 测试插入
func myInsertTest() {var u useru.age = 23u.name = "周杰伦"id, err1 := insert(u)if err1 != nil {fmt.Printf("insert failed,err:%v\n", err1)return}//说明插入成功u.id = int(id)usergroup[u.id] = u
}//遍历map
func printMap() {//遍历for _, u := range usergroup {println(u.id, u.name, u.age)}println("***************************************")
}func main() {err := initDB()defer db.Close()if err != nil {fmt.Printf("init db failed,err:%v\n", err)return}readToMap()printMap()myInsertTest()printMap()}
三.预处理
预处理执行过程:
- 把SQL语句分成两部分,命令部分与数据部分。
- 先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预处理。
- 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位符替换。
- MySQL服务端执行完整的SQL语句并将结果返回给客户端。
优点:
- 优化MySQL服务器重复执行SQL的方法,可以提升服务器性能,提前让服务器编译,一次编译多次执行,节省后续编译的成本。
- 避免SQL注入问题。
func prepareInsert() {sqlstr := "insert into user(name,age) values(?,?)"//先将sql语句发送给数据库,为后续执行做准备,后续只需要传递参数即可stmt, err := db.Prepare(sqlstr)if err != nil {fmt.Printf("prepare failed,err:%v\n", err)return}defer stmt.Close()//后续只需要用stmt执行操作,传递参数res, err1 := stmt.Exec("陶喆", 18)if err1 != nil {fmt.Printf("insert failed,err:%v\n", err1)return}id, err2 := res.LastInsertId()if err2 != nil {fmt.Printf("insert failed,err:%v\n", err2)return}usergroup[int(id)] = user{int(id), "陶喆", 18}}
四.事务操作
//事务操作
func transactionDemo() {//开启事务tx,err:=db.Begin()if err!=nil{fmt.Printf("begin failed,err:%v\n", err)return}//执行多个SQL操作sqlstr1:="update user set age=? where id=1"sqlstr2:="update user set age=? where id=2"_,err=tx.Exec(sqlstr1, 18)if err!=nil{//回滚fmt.Println("sqlstr1 failed,err:%v\n", err)tx.Rollback()}_,err=tx.Exec(sqlstr2, 18)if err!=nil{fmt.Println("sqlstr2 failed,err:%v\n", err)//回滚tx.Rollback()}//提交tx.Commit()
}
五.对于sqlx库的使用
下载依赖:
go get github.com/jmoiron/sqlx
package mainimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx"
)var db *sqlx.DB//和上一个例子不一样,这个要字段要供其它包方法使用,比如Get方法需要对结构体进行反射,所以要大写
type user struct {Id intName stringAge int
}func initDB() (err error) {dsn := "root:9826942694yzy@tcp(127.0.0.1:3306)/sql_test"// 也可以使用MustConnect连接不成功就panicdb, err = sqlx.Connect("mysql", dsn)if err != nil {fmt.Printf("connect DB failed, err:%v\n", err)return}//这是最大连接池数量和最大休闲连接池数量db.SetMaxOpenConns(20)db.SetMaxIdleConns(10)return
}func main() {err := initDB()if err != nil {fmt.Printf("init db failed,err:%v\n", err)return}defer db.Close()sqlStr := "select *from user where id=?"var u usererr = db.Get(&u, sqlStr, 1)if err != nil {fmt.Printf("get failed, err:%v\n", err)return}fmt.Println(u.Id, u.Name, u.Age)var userlist = make([]user, 100)sqlStr1 := "select * from user"err = db.Select(&userlist, sqlStr1)if err != nil {fmt.Printf("select failed,err:%v\n", err)return}fmt.Println(userlist)
}
六.sql注入问题
func main() {err := initDB()if err != nil {fmt.Printf("init db failed,err:%v\n", err)return}defer db.Close()//这样符合要求inject_demo("周杰伦")//但是由于用户可以自行输出,如果输入以下,会输出所有//"select * from user where name='xxx' or 1=1#'" == select * from user where name='xxx' or 1=1 这样会输出所有信息 #在mysql中是注释inject_demo("xxx' or 1=1#")//select *from user where name='xxx' union select * from user 输出所有inject_demo("xxx' union select * from user#")}
相关文章:
Go语言对于MySQL的基本操作
一.下载依赖 终端中输入: go get -u github.com/go-sql-driver/mysql 导入包 import ("database/sql"_ "github.com/go-sql-driver/mysql" ) 二.案例 package main//go get-u github.com/go-sql-driver/mysql 获取驱动 import ("databa…...
AndroidStudio下载安装,环境部署以及常见问题解决教程(亲测)
AndroidStudio下载安装,环境部署以及常见问题解决!!! 文章目录 前言 一、Android Studio 下载与安装 1.1 系统要求 1.2 下载 Android Studio 1.3 安装 Android Studio Windows 系统 1.4 初始配置 二、环境部署 2.1 安装 …...
开源免费一句话生成儿童故事视频核心思想解析
再看一个演示视频,学会核心思想后,可以打造自己的内容生成工具,后文有基于飞书多维表格的实现效果: 一句话灵感生成儿童故事视频演示 这是一款专门为内容素材创作打造的创新工具,可根据用户输入的主题,快速…...
数据结构——最短路(BFS,Dijkstra,Floyd)
完整版可以看我的最短路问题模版总结_稠密图最短路-CSDN博客 考研数据结构只考BFS,Dijkstra和Floyd 下面代码以Acwing模板题为例 BFS代码 适用类型: 1.单源最短路径 2.无权图 3.不适用于带权图和负权回路图 //Acwing走迷宫bfs #include<bits/stdc.h>usi…...
Kali Linux汉化教程:轻松设置中文界面
1.打开终端 2.输入sudo dpkg-reconfigure locales,回车,输入密码,回车 sudo dpkg-reconfigure locales 3.往下滑,滑到底,找到‘zh_CN.UTF-8 UTF-8’,回车 4.选择‘zh_CN.UTF-8’,回车 5.没有 ‘zh_CN.UTF-8’选项的特…...
分布式锁: 并发时,redis如何避免删别人的锁
在使用Redis实现分布式锁的时候,如何避免在并发情况下误删别人的锁。首先,分布式锁的基本概念:是多个客户端在访问共享资源时,通过某种机制来确保同一时间只有一个客户端能持有锁。 Redis通常用SET命令加上NX选项来创建锁…...
Leetcode 160 Intersection of Two Linked Lists
题意 给定两个链表,找这两个链表第一个公共节点,如果没有返回nullptr 题目链接 https://leetcode.com/problems/intersection-of-two-linked-lists/description/ 题解 两个指针分别从两个链表(记录为表A,表B)的表…...
【八股文】从浏览器输入一个url到服务器的流程
1.url解析与DNS解析 浏览器解析用户输入的URL,提取协议(HTTP\HTTPS)、域名、端口及路径等信息 浏览器首先检查本地DNS缓存和系统DNS缓存,若未命中,查询本地hosts文件 最后递归查询向本地DNS服务器发起请求ÿ…...
C++和标准库速成(八)——指针、动态数组、const、constexpr和consteval
目录 1. 指针和动态数组1.1 栈和自由存储区1.2 使用指针1.3 动态分配的数组1.4 空指针常量 2. const2.1 const修饰类型2.2 const与指针2.3 使用const保护参数2.4 const方法(建议) 3. constexpr4. consteval参考 1. 指针和动态数组 动态内存允许所创建的程序具有在编…...
超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction
1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术,广泛应用于医学影像领域。通过重建和可视化三维结构,3D超声能够显著提高诊断精度和效率,同时减少医生的脑力负担。本技术文档将详细阐述…...
[HelloCTF]PHPinclude-labs超详细WP-Level 6Level 7Level 8Level 9-php://协议
由于Level 6-9 关的原理都是通用的, 这里就拿第6关举例, 其他的关卡同理 源码分析 定位到代码 isset($_GET[wrappers]) ? include("php://".$_GET[wrappers]) : ; 与前几关发生变化的就是 php:// 解题分析 这一关要求我们使用 php协议 php:// 协议 php://filte…...
【Linux】Bash是什么?怎么使用?
李升伟 整理 什么是 Bash? Bash(Bourne Again Shell)是一种 命令行解释器(Shell),广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell(sh) 的增强版,提供了更多的功能…...
cmake结合qt开发界面程序实例
在使用 CMake 构建 Qt 界面应用程序时,你需要设置 CMakeLists.txt 文件来指定项目配置、源文件、库依赖等。以下是一个简单的示例,展示了如何创建一个包含 Qt 界面(使用 QWidget)的 Qt 项目,并使用 CMake 进行构建。 …...
vue3二次封装tooltip实现el-table中的show-overflow-tooltip效果
开发过程中遇到需要根据后端返回的数据长度来判断是否需要使用el-tooltip的情况,想到el-table里面就有这种交互效果,如果不论文字是否超出容器长度都展示tooltip的话,交互效果难免会差很多,所以二次封装了这个组件: 给…...
如何创建并保存HTML文件?零基础入门教程
原文:如何创建并保存HTML文件?零基础入门教程 | w3cschool笔记 本文将以Windows系统为例,教你用最简单的记事本创建并保存第一个HTML网页。 📝 第一步:准备工具 文本编辑器:使用系统自带的记事本ÿ…...
React19源码系列之FiberRoot节点和Fiber节点
在上一篇文章,看了createRoot函数的大致流程。 createContainer函数创建并返回了FiberRoot 。FiberRoot是由createFiberRoot函数创建, createFiberRoot函数还将 FiberRoot和 根Fiber 通过current属性建立起了联系。将FiberRoot作为参数传给 ReactDOMRoo…...
每天看一篇漏洞报告
前言: 内容来源于乌云漏洞 今日思考xss漏洞, 今天看到一篇文章,里面详细说了xss的绕过技巧,虽然时间久了,没有去尝试,待会有时间去测试一下 以下是整理后的文章,原文在下面 文章链接&#…...
采用贝塞尔函数,进行恒定束宽波束形成算法
matlab采用贝塞尔函数,进行恒定束宽波束形成算法 beselle.m , 1452 20191225160928.png , 43700 20191225160935.png , 45238 20191225161010.png , 76862...
TCP协议的多线程应用、多线程下的网络编程
DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式,一个服务端对应一个客户端,实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类,多线程接收socket对象 public class ServerSocketNable implements Run…...
华为中小型企业项目案例
实验目的(1) 熟悉华为交换机和路由器的应用场景 (2) 掌握华为交换机和路由器的配置方法 实验拓扑实验拓扑如图所示。 华为中小型企业项目案例拓扑图 实验配置市场部和技术部的配置创建VLANLSW1的配置 [LSW1]vlan batch 10 20 [LSW1]q…...
LabVIEW VI Scripting随机数波形图自动生成
通过LabVIEW VI Scripting 技术,实现从零开始编程化创建并运行一个随机数波形监测VI。核心功能包括自动化生成VI框架、添加控件与函数、配置数据流逻辑及界面布局优化,适用于批量生成测试工具、教学模板开发或复杂系统的模块化构建。通过脚本化操作&…...
MATLAB 控制系统设计与仿真 - 26
状态空间控制系统概述 状态空间描述 现代控制理论是建立在状态空间基础上的控制系统分析和设计理论,它用状态变量来刻画系统的内部特征,用‘一节微分方程组’来描述系统的动态特性。系统的状态空间模型描述了系统输入/输出与内部状态之间的关系&#x…...
Python----计算机视觉处理(Opencv:图像镜像旋转)
一、图像镜像旋转 图像的旋转是围绕一个特定点进行的,而图像的镜像旋转则是围绕坐标轴进行的。图像镜像旋转,也可 以叫做图像翻转,分为水平翻转、垂直翻转、水平垂直翻转三种。 通俗的理解为,当以图片的中垂线为x轴和y轴时&#x…...
C++从入门到入土(八)——多态的原理
目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中,我们介绍了C三大特性之一的多态,我们主要介绍了多态的构成条件,但是对于多态的原理我们探讨的是不够深入的,下面这这一篇文章,我们将…...
国产编辑器EverEdit - 语法着色文件的语法
1 语法着色定义(官方文档) 1.1 概述 EverEdit有着优异的语法着色引擎,可以高亮现存的绝大多数的编程语言。在EverEdit的语法着色中有Region和Item两个概念,Region表示着不同的区块。而Item则代表着这些区块中不同的部分。一般情况下,Region…...
vue3当中使用Pinia的store的组件化开发模式
一、安装与初始化 安装Pinia npm install pinia # 或 yarn add pinia目的:引入Pinia核心库,为状态管理提供基础支持。 挂载Pinia实例 在main.js中初始化并注入Vue应用: import { createApp } from vue import { createPinia } from pinia i…...
PyCharm安装redis,python安装redis,PyCharm使用失败问题
报错信息 Usage: D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip install [options] -r [package-index-options] … D:\wb2\wbrj_pys\venv\Scripts\python.exe -m pip instal…...
保姆级离线TiDB V8+解释
以前学习的时候还是3版本,如今已经是8版本了 https://cn.pingcap.com/product-community/?_gl1ujh2l9_gcl_auMTI3MTI3NTM3NC4xNzM5MjU3ODE2_gaMTYwNzE2NTI4OC4xNzMzOTA1MjUz_ga_3JVXJ41175MTc0MTk1NTc1OC4xMS4xLjE3NDE5NTU3NjIuNTYuMC41NDk4MTMxNTM._ga_CPG2VW1Y4…...
PyTorch 深度学习实战(17):Asynchronous Advantage Actor-Critic (A3C) 算法与并行训练
在上一篇文章中,我们深入探讨了 Soft Actor-Critic (SAC) 算法及其在平衡探索与利用方面的优势。本文将介绍强化学习领域的重要里程碑——Asynchronous Advantage Actor-Critic (A3C) 算法,并展示如何利用 PyTorch 实现并行化训练来加速学习过程。 一、A…...
【服务器知识】Nginx路由匹配规则说明
Nginx路由匹配规则说明 **一、Nginx路由匹配核心机制****二、匹配规则语法详解**1. **精确匹配 ()**2. **前缀匹配 (^~ 或 /)**3. **正则匹配 (~ 或 ~*)**4. **通配符匹配 (*)** **三、路由匹配优先级顺序****四、高级路由技巧**1. **条件判断 (if语句)**2. **路径重写 (rewrit…...
