互联网目前已进入其生命末期,而物联网则正在落地开发,随之而来的各种原生云则是让互联网进入生命末期的主要诱因。同时由于物联网的兴起,对云的要求则更加迫切,所以这里不得不掌握一门新的云语言来增强自身的技能属性,避免被时代抛弃,golang,作为新生代语言,则属于天选之子。
当然了,新语言学习,我一向认为单纯的看语法,按部就班的学习,是一件很枯燥且性价比极低的事情,所以这里,我们就从mysql的crud来学起吧。当然了,工欲善其事必先利其器,我们首先要在本地安装好mysql server, go sdk,goland等必备工具,由于安装过程寥寥几笔,无需浓墨重彩,我这里不需多言。下面展示的是安装好之后的代码步骤
代码层级
代码层级很简单,dao放数据访问层,entity是实体层,service中则是增删改查的各种服务,main.go负责运行,而go.mod则是创建项目的时候,goland默认给我们创建的,注意这个go.mod非常重要,不要删除,否则会导致无法import一些包。
数据库连接connection.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package dao import ( "database/sql" _ "github.com/go-sql-driver/mysql" "strings" ) const ( userName = "root" password = "root" ip = "127.0.0.1" port = "3306" dbName = "test" ) func InitDB() *sql.DB { //Golang数据连接:"用户名:密码@tcp(IP:端口号)/数据库名?charset=utf8" path := strings.Join([]string{userName, ":" , password, "@tcp(" , ip, ":" , port, ")/" , dbName, "?charset=utf8" }, "" ) //打开数据库,前者是驱动名,所以要导入: _ "github.com/go-sql-driver/mysql" db, err := sql.Open( "mysql" , path) if err != nil { //如果打开数据库错误,直接panic panic(err) } //设置数据库最大连接数 db.SetConnMaxLifetime(10) //设置上数据库最大闲置连接数 db.SetMaxIdleConns(5) //验证连接 errPing := db.Ping() if errPing != nil { panic(err) } return db; } |
注意,在写驱动前,需要利用 go get -u github.com/go-sql-driver/mysql 命令将驱动包安装到GOPATH指定的目录下,go env命令可以查看GOPATH目录,之后在goland中,确认GOPATH目录,就可以正常的引用包了,否则import的包怎么都会检测不到:
用户实体user.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package entity type User struct { userId int userName string userAddr string } //(user *User) 其实就是java中的this关键字,指向当前对象 func (user *User) GetUserId() int { return user.userId } func (user *User) SetUserId(userId int) { user.userId = userId } func (user *User) GetUserName() string { return user.userName } func (user *User) SetUserName(userName string) { user.userName = userName } func (user *User) GetUserAddr() string { return user.userAddr } func (user *User) SetUserAddr(userAddr string) { user.userAddr = userAddr } |
需要注意,在go中,pulic,private,protected等修饰符是没有的, 方法首字母大写,则默认为public方法,方法首字母小写,则默认为private方法。
增删改查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package service import ( "firstgo/src/dao" ) func CreateRecord() (int64,error){ db := dao.InitDB() tx, err := db.Begin() if err != nil{ panic(err) } sql := "insert into user (`user_name`, `user_addr`) values (?, ?)" stmt, err := db.Prepare(sql) if err != nil { panic(err) } result, err := stmt.Exec( "testuser" , "china, beijing" ) if err != nil { //SQL执行失败,直接panic panic(err) } //提交事务 tx.Commit() //返回插入记录的id return result.LastInsertId() } |
新增用户,驱动代码如上,注意返回值,在go中,是支持多返回值的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package service import ( "firstgo/src/dao" ) func DeleteRecord(userId int) (int64, error) { db := dao.InitDB() tx, err := db.Begin() if err != nil { panic(err) } sql := "delete from user where user_id = ? " stmt, err := db.Prepare(sql) if err != nil { panic(err) } result, err := stmt.Exec(userId) if err != nil { //SQL执行失败,直接panic panic(err) } //提交事务 tx.Commit() return result.RowsAffected() } |
删除用户代码如上,需要注意的是 :=的写法,实际上是属于自动推导类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package service import "firstgo/src/dao" func UpdateRecord(userAddr string, userId int)(int64, error) { db := dao.InitDB() tx, err := db.Begin() if err != nil { panic(err) } sql := "update user set user_addr = ? where user_id = ? " stmt, err := db.Prepare(sql) if err != nil { panic(err) } result, err := stmt.Exec(userAddr, userId) if err != nil { //SQL执行失败,直接panic panic(err) } //提交事务 tx.Commit() return result.RowsAffected() } |
更新代码如上,和删除方法类似,无需多言。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package service import ( _ "database/sql" "firstgo/src/dao" "firstgo/src/entity" ) func QueryList() []entity.User { db := dao.InitDB() sql := "select * from user " stmt, err := db.Prepare(sql) if err != nil { panic(err) } rows, err := stmt.Query() if err != nil { //SQL执行失败,直接panic panic(err) } var users []entity.User for rows.Next() { var id int var name, password string err := rows.Scan(&id, &name, &password) if err != nil { //读取结果集失败 panic(err) } var user entity.User user.SetUserId(id) user.SetUserName(name) user.SetUserAddr(password) users = append(users, user) } return users } |
查询列表方法如上,从代码中,可以看到go中数组的写法和我们正常写法不一样,需要适应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | //package名称需要设置为main,才会进入main方法运行 package main import ( "firstgo/src/service" "fmt" ) func main() { //新增 recordId, err := service.CreateRecord() if err == nil && recordId > 0 { fmt.Println( "插入成功,id:" , recordId) } //删除 var removedRecordId = 1 rowAffected, err := service.DeleteRecord(removedRecordId) if err == nil && rowAffected>0 { fmt.Println( "删除成功,id:" , removedRecordId ) } //更新 var userAddr = "shanghai, china" var updateRecordId = 3 record, err := service.UpdateRecord(userAddr, updateRecordId) if err == nil && record>0{ fmt.Println( "更新成功,id:" , updateRecordId) } //查询 queryList := service.QueryList() if queryList != nil{ fmt.Println( "查询列表,list:" , queryList) } } |
写好后,在main.go中运行起来即可。记住,main方法的运行一定要有个package为main的包,否则会报错。运行起来后,我们就可以看到如下输出了:
1 2 3 4 5 | 插入成功,id: 9 更新成功,id: 3 查询列表,list: [{2 testuser china, beijing} {3 testuser shanghai, china} {4 testuser china, beijing} {5 testuser china, beijing} {6 testuser china, beijing} {7 testuser china, beijing} {8 testuser china, beijing} {9 testuser china, beijing}] Process finished with the exit code 0 |
是不是很简单?
参考
https://blog.csdn.net/qq_45193304/article/details/105464606
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2010-09-30 在asp.net利用jquery实现多文件上传