关于gorm:golang-gorm-使用分享和-redis使用

GORM 官网反对的数据库类型有: MySQL,PostgreSQL,SQlite,SQL ServerMYSQLimport ( "gorm.io/driver/mysql" "gorm.io/gorm") func main() { // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情 dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})}PostgreSQLimport ( "gorm.io/driver/postgres" "gorm.io/gorm") dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})#### SQLiteimport ( "gorm.io/driver/sqlite" // Sqlite driver based on GGO // "github.com/glebarez/sqlite" // Pure go SQLite driver, checkout https://github.com/glebarez/sqlite for details "gorm.io/gorm") // github.com/mattn/go-sqlite3db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})SQL Serverimport ( "gorm.io/driver/sqlserver" "gorm.io/gorm") // github.com/denisenkom/go-mssqldbdsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})连接池GORM 应用database/sql保护连接池sqlDB, err := db.DB()// SetMaxIdleConns 设置闲暇连接池中连贯的最大数量sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置关上数据库连贯的最大数量。sqlDB.SetMaxOpenConns(100)// SetConnMaxLifetime 设置了连贯可复用的最大工夫。sqlDB.SetConnMaxLifetime(time.Hour)Createpackage mainimport ( "database/sql" "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" "time")type Userinfo struct { Id uint Name string Gender string Hobby string}type UserTest struct { ID uint Name string Email *string Age uint8 Birthday *time.Time MemberNumber sql.NullString ActivatedAt sql.NullTime CreatedAt time.Time UpdatedAt time.Time}func main() { // 连贯数据库 dsn := "root:xixxxxxu@tcp(10.xx.18x.1x:3306)/test?charset=utf8mb4&parseTime=True&loc=Local" db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{}) ////主动迁徙 //db.AutoMigrate(&Userinfo{}) //u1 := Userinfo{Id: 1, Name: "张三", Gender: "男", Hobby: "学习"} //db.Create(&u1) //创立 //create table and inster db.AutoMigrate(&UserTest{}) britime := time.Now() user := UserTest{Name: "Sean", Age: 17, Birthday: &britime} result := db.Create(&user) //user.ID // 返回插入数据的主键 //result.Error // 返回 error //result.RowsAffected // 返回插入记录的条数 fmt.Println(user.ID, result.Error, result.RowsAffected)} ...

March 15, 2023 · 3 min · jiezi

关于gorm:gorm-使用注意点

一、查问Find查问后果是列表,First查问的是单条数据。当 First、Last、Take 办法找不到记录时,GORM 会返回 ErrRecordNotFound 谬误 在应用Raw自定义SQL查问时,应用Scan来接收数据,尽管Find也是能够接管的,然而Find次要还是用来带条件查问的,链接到Raw前面时条件是不起作用的。所以用Scan函数单纯的接收数据就行了。 二、更新Gorm 更新数据:// 更新单个字段db.Model(&user).Update("name", "hello") // 通过 map 更新多个字段,零值字段也会更新db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) 如果您想要在更新、创立的时候 选定、疏忽某些字段,您能够应用 Select、Omit

September 8, 2022 · 1 min · jiezi

关于gorm:Gorm-原生Sql-查询

Gorm用原生sql查问有两种形式: // 第一种type Result struct { ID int Name string Age int}var result Resultdb.Raw("SELECT id, name, age FROM users WHERE id = ?", 3).Scan(&result)// 第二种result := map[string]interface{}{}db.Model(&User{}).First(&result)// SELECT * FROM `users` ORDER BY `users`.`id` LIMIT 1//通用应用形式rows, _ := db.Raw("select * from admin").Rows()fmt.Println(rows)res := scanRows2map(rows)func scanRows2map(rows *sql.Rows) []map[string]string { res := make([]map[string]string, 0) // 定义后果 map colTypes, _ := rows.ColumnTypes() // 列信息 var rowParam = make([]interface{}, len(colTypes)) // 传入到 rows.Scan 的参数 数组 var rowValue = make([]interface{}, len(colTypes)) // 接收数据一行列的数组 for i, colType := range colTypes { rowValue[i] = reflect.New(colType.ScanType()) // 跟据数据库参数类型,创立默认值 和类型 rowParam[i] = reflect.ValueOf(&rowValue[i]).Interface() // 跟据接管的数据的类型反射出值的地址 } // 遍历 for rows.Next() { rows.Scan(rowParam...) // 赋值到 rowValue 中 record := make(map[string]string) for i, colType := range colTypes { if rowValue[i] == nil { record[colType.Name()] = "" } else { record[colType.Name()] = Byte2Str(rowValue[i].([]byte)) } } res = append(res, record) } return res}// Byte2Str []byte to stringfunc Byte2Str(b []byte) string { return *(*string)(unsafe.Pointer(&b))}

September 6, 2022 · 1 min · jiezi

关于gorm:基于GORM框架的web后端开发一-GORM连接MySQL

GORM(Golang Object Relational Mapping):通过ORM语句(而不是SQL),把Go中对象或者说构造体的实例映射成数据库中的一条数据。 ORM有以下对应关系: 数据表 <==> 构造体数据行 <==> 构造体实例字段     <==> 构造体字段未完待续、、、、

June 11, 2022 · 1 min · jiezi

关于gorm:GO笔记04-GORM

GORM介绍gorm是一个应用Go语言编写的ORM框架。它文档齐全,对开发者敌对,反对支流数据库。ORM:Object Relation Mapping 对象关系映射长处:进步开发效率 毛病:就义执行性能,灵活性 装置GORMgo get -u github.com/jinzhu/gormDocker疾速创立Mysql实例在本地的33060端口运行一个名为mysql,用户名root明码123456的MySQL容器环境: docker run --name mysql -p 33060:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:8.0.19> docker exec -it mysql bash> mysql -uroot -p> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY '123456';下载Sequel Pro Nightly(正式版连贯Mysql8.0会解体) https://sequelpro.com/test-bu... 创立数据库db_test CREATE DATABASE db_test;连贯Mysqlimport ( "gorm.io/driver/mysql" "gorm.io/gorm")func main() { dsn := "root:123456@tcp(127.0.0.1:33060)/db_test?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})}GORM操作Mysqltype User struct { ID uint Name string}func main() { dsn := "root:123456@tcp(127.0.0.1:33060)/db_test?charset=utf8mb4&parseTime=True&loc=Local" db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{}) //主动建表 db.AutoMigrate(&User{}) //创立数据 u1 := User{1, "AAA"} u2 := User{2, "BBB"} db.Create(&u1) db.Create(&u2) // 删除 db.Delete(&u2) // 更新 db.Model(&u1).Update("name", "AAA1") // 查问单条 var u User db.First(&u) fmt.Printf("%#v\n", u) //{ID:0x1, Name:"AAA1"} // 查问多条 var us []User db.Find(&us) fmt.Printf("%#v\n", us)}GORM Modelgorm.ModelGORM内置了一个gorm.Model构造体。蕴含ID, CreatedAt, UpdatedAt, DeletedAt四个字段。type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time}模型嵌套 ...

January 16, 2022 · 5 min · jiezi

关于gorm:马哥高端Go语言百万并发高薪班微服务分布式高可用Go高并发fdfdsg

download:马哥高端Go语言百万并发高薪班/微服务/分布式高可用/Go高并发问题描述囚徒困境是博弈论中经典问题,有两个囚徒有坦率未报的偷盗案件,在审讯过程中每个囚徒可能抉择抗拒不承认或者坦率承认。局势就是两个囚徒给出自己策略算一个局势,那么根据排列组合局势有 抗拒,抗拒坦率,抗拒抗拒,坦率坦率,坦率如果两个人都抗拒不承认每人会被判 1 年,如果两个人都坦率每个人会被判 3 年,如果一方坦率另一方抗拒,抗拒一方会被判 5 年而坦率会被开释。 局中人:两个囚徒 策略抗拒或者坦率 效用函数矩阵抗拒 坦率抗拒 -1,-1 -5,0坦率 0,-5 -3,-3每个人都会抉择最大化自己受害的最大化策略,那么对于囚徒最大化受害就是服刑工夫最短,为了这个目标怎么的策略才是感性的呢? 对于囚徒(A 囚徒)做出策略时还需要考虑到另一个囚徒(B 囚徒)的策略抉择,那么 B 囚徒抉择有两种可能别离是抗拒或者是坦率,这里就称为 B 囚徒,如果 B 囚徒坦率的前提,A 囚徒如果坦率将服刑 3 年如果抗拒则服刑 5 年,所以 A 最佳抉择是认罪。 假设后面策略 A 囚徒抉择了抗拒情况,B 囚徒抉择坦率收益为 0,当 A 囚徒抉择坦率情况,B 囚徒也会抉择坦率获取去收益最大。 对于 A 囚徒无论 B 囚徒做出什么策略,坦率都是 A 囚徒的占优策略。两个囚徒都不能通过双方面改变策略来减少自己的效益,因此谁都没有游离这个策略组合的动机。 占优策略在抉择策略时,有一个策略的效用总是大于其余所有策略效用时,咱们就把这类策略称为占优策略(Dominant Strategy) 占优策略纳什均衡当所有参与者的最优回应是抉择他们的占优策略时,这时达到的纳什均衡称为占优策略纳什均衡。

January 2, 2022 · 1 min · jiezi

关于gorm:Go高级工程师实战营JK

download:Go高级工程师实战营Python字典内置函数和方法: 注:使用了 items、values、keys 返回的是可迭代对象,可能使用 list 转化为列表。 len(字典名): 返回键的个数,即字典的长度 复制代码 len(字典名):返回键的个数,即字典的长度dic = {'a':123,'b':456,'c':789,'d':567}print(len(dic)) 4复制代码str(字典名): 将字典转化成字符串 复制代码 str(字典名):将字典转化成字符串dic = {'a':123,'b':456,'c':789,'d':567}print(str(dic)) {'a': 123, 'b': 456, 'c': 789, 'd': 567}复制代码type(字典名): 查看字典的类型 复制代码 type(字典名):查看字典的类型dic = {'a':123,'b':456,'c':789,'d':567}print(type(dic)) <class 'dict'>复制代码内置方法: clear( ): 删除字典内所有的元素 复制代码 clear( ):删除字典内所有的元素dic = {'a':123,'b':456,'c':789,'d':567}dic.clear()print(dic) {}复制代码copy( ): 浅拷贝一个字典 复制代码 copy( ):浅拷贝一个字典dic = {'a':123,'b':456,'c':789,'d':567}dic_two = dic.copy()print(dic) {'a': 123, 'b': 456, 'c': 789, 'd': 567}print(dic_two) {'a': 123, 'b': 456, 'c': 789, 'd': 567}复制代码fromkeys(seq[,value]): 创建一个新字典,seq作为键,value为字典所有键的初始值(默认为None) 复制代码 ...

November 17, 2021 · 1 min · jiezi

关于gorm:极客大学云原生训练营JIKE

download:极客大学-云原生训练营Python list列表增加元素的3种方法 运行后果:language = ['Python', 'C++', 'Java']birthday = [1991, 1998, 1995]info = ['Python', 'C++', 'Java', 1991, 1998, 1995] 从运行后果可能发现,使用+会生成一个新的列表,原有的列表不会被改变。 +更多的是用来拼接列表,而且执行效率并不高,如果想在列表中插入元素,应该使用上面几个顺便的方法。Python append()方法增加元素append() 方法用于在列表的开端追加元素,该方法的语法格局如下:listname.append(obj) 其中,listname 示意要增加元素的列表;obj 示意到增加到列表开端的数据,它可能是单个元素,也可能是列表、元组等。 请看上面的演示:l = ['Python', 'C++', 'Java'] 追加元素l.append('PHP')print(l) 追加元组,整个元组被当成一个元素t = ('JavaScript', 'C#', 'Go')l.append(t)print(l) 追加列表,整个列表也被当成一个元素l.append(['Ruby', 'SQL'])print(l)运行后果为:['Python', 'C++', 'Java', 'PHP']['Python', 'C++', 'Java', 'PHP', ('JavaScript', 'C#', 'Go')]['Python', 'C++', 'Java', 'PHP', ('JavaScript', 'C#', 'Go'), ['Ruby', 'SQL']] 可能看到,当给 append() 方法传送列表或者元组时,此方法会将它们视为一个整体,作为一个元素增加到列表中,从而形成蕴含列表和元组的新列表。Python extend()方法增加元素extend() 和 append() 的不同之处在于:extend() 不会把列表或者元祖视为一个整体,而是把它们蕴含的元素逐个增加到列表中。 extend() 方法的语法格局如下:listname.extend(obj) 其中,listname 指的是要增加元素的列表;obj 示意到增加到列表开端的数据,它可能是单个元素,也可能是列表、元组等,但不能是单个的数字。 请看上面的演示:l = ['Python', 'C++', 'Java'] ...

November 6, 2021 · 1 min · jiezi

关于gorm:gorm源码-连接的申请与释放

gorm封装了go自带的database/sql,提供了不便操作的办法,然而其连贯的申请和开释还是应用database/sql中的实现。 查问语句的连贯申请与开释查问语句的code demo: func GetHost(hid int) *Host { var hosts []Host dt := DBInstance.Table("host").Where("id > ?", hid).Scan(&hosts); if dt.Error != nil { fmt.Println("GetHost error:", dt.Error) return nil } if len(hosts) > 0 { return &hosts[0] } else { return nil }}DBInstance.Table("host")设置表名,Where("id > ?", hid)设置查问条件。 Scan(&hosts)才真正的执行sql查问,包含conn申请、sql执行、conn开释。 // Scan scan value to a structfunc (s *DB) Scan(dest interface{}) *DB { //后果存在"gorm:query_destination"对应的value上 return s.NewScope(s.Value).Set("gorm:query_destination", dest).callCallbacks(s.parent.callbacks.queries).db }查问语句的callbacks: // Define callbacks for queryingfunc init() { DefaultCallback.Query().Register("gorm:query", queryCallback) DefaultCallback.Query().Register("gorm:preload", preloadCallback) DefaultCallback.Query().Register("gorm:after_query", afterQueryCallback)}在queryCallback中进行了连贯的申请和开释: ...

October 29, 2021 · 2 min · jiezi

关于gorm:gorm源码-自动更新时间字段

gorm反对对model中的工夫字段进行默认操作: CreatedAt:创立工夫UpdatedAt:更新工夫DeletedAt: 删除工夫也就是说,若model中含有上述字段,在CRUD操作时,gorm会自动更新上述的工夫字段的值为now()。 删除的时候删除的callbacks: // github.com/jinzhu/gorm/callback_delete.go// Define callbacks for deletingfunc init() { ...... DefaultCallback.Delete().Register("gorm:delete", deleteCallback) ......}在deleteCallback中,依据model中是否有DeletedAt字段,决定是执行update还是delete: // deleteCallback used to delete data from database or set deleted_at to current time (when using with soft delete)func deleteCallback(scope *Scope) { if !scope.HasError() { var extraOption string if str, ok := scope.Get("gorm:delete_option"); ok { extraOption = fmt.Sprint(str) } //查找DeletedAt字段 deletedAtField, hasDeletedAtField := scope.FieldByName("DeletedAt") if !scope.Search.Unscoped && hasDeletedAtField { //model struct中有DeletedAt字段 scope.Raw(fmt.Sprintf( "UPDATE %v SET %v=%v%v%v", //执行update-sql scope.QuotedTableName(), scope.Quote(deletedAtField.DBName), //将 UpdateAt对应的db字段更新为now() scope.AddToVars(scope.db.nowFunc()), addExtraSpaceIfExist(scope.CombinedConditionSql()), addExtraSpaceIfExist(extraOption), )).Exec() } else { scope.Raw(fmt.Sprintf( "DELETE FROM %v%v%v", //model struct中没有DeletedAt字段, 执行delete-sql scope.QuotedTableName(), addExtraSpaceIfExist(scope.CombinedConditionSql()), addExtraSpaceIfExist(extraOption), )).Exec() } }}插入的时候插入的callbacks: ...

October 29, 2021 · 1 min · jiezi

SQLRESTful开源GO脚手架工具ginbrogin-and-gorms-brother-详解

安装felixgit clone https://github.com/dejavuzhou/felixcd felixgo mod downloadgo installecho "添加 GOBIN 到 PATH环境变量"echo "或者"go get github.com/dejavuzhou/felixecho "go build && ./felix -h"What is GinbroGin脚手架工具:因为工作中非常多次的使用mysql数据库 + gin + GORM 来开发RESTful API程序,所以开发一个Go语言的RESTful APIs的脚手架工具Ginbro代码来源:Ginrbo的代码迭代自github.com/dejavuzhou/ginbroSPA二进制化工具:vuejs全家桶代码二进制化成go代码,编译的时候变成二进制,运行的时候直接加载到内存中,同时和gin API在一个域名下不需要再nginx中配置rewrite或者跨域,加快API访问速度功能一:Gin+GORM_SQL RESTful 脚手架工具工作原理通过cobra 获取命令行参数使用sql参数连接数据库后去数据库表的名称和字段类型等数据库数据库边的表名和字段信息,转换成 Swagger doc 规范字段 和 GORM 模型字段使用标准库 text/template 生成swagger.yaml, GORM 模型文件, GIN handler 文件 ...使用 go fmt ./... 格式化代码使用标准库archive/zip打包*.go config.toml ...代码,提供zip文件下载(命令行模式没有)支持数据库大多数SQL数据库mysqlSQLitepostgreSQLmssql(TODO:: sqlserver)ginbro 生成app代码包含功能简介每一张数据库表生成一个RESTful规范的资源(GET<pagination>/POST/GET<one>/PATCH/DELETE)支持API-json数据分页-和总数分页缓存,减少全表扫描支持golang-内存单机缓存缓存前端代码和API公用一个服务,减少跨域OPTION的请求时间和配置时间,同时完美支持前后端分离开箱支持jwt-token认证和Bearer Token 路由中间件开箱即用的logrus数据库开箱即用的viper配置文件开箱即用的swagger API 文档开箱即用的定时任务系统项目演示地址felix sshw 网页UI演示地址 用户名和密码都是admin生成swagger API交互文档地址 http://ginbro.mojotv.cn/swagger/msql生成go代码地址bili命令行演示视频地址命令行参数详解[root@ericzhou felix]# felix ginbro -hgenerate a RESTful APIs app with gin and gorm for gophersUsage: felix ginbro [flags]示例:felix ginbro -a dev.wordpress.com:3306 -P go_package_name -n db_name -u db_username -p 'my_db_password' -d '~/thisDir'Flags: --authColumn string 使用bcrypt方式加密的用户表密码字段名称 (default "password") --authTable string 认知登陆用户表名称 (default "users") -a, --dbAddr string 数据库连接的地址 (default "127.0.0.1:3306") -c, --dbChar string 数据库字符集 (default "utf8") -n, --dbName string 数据库名称 -p, --dbPassword string 数据库密码 (default "password") -t, --dbType string 数据库类型: mysql/postgres/mssql/sqlite (default "mysql") -u, --dbUser string 数据库用户名 (default "root") -d, --dir string golang代码输出的目录,默认是当前目录 (default ".") -h, --help 帮助 -l, --listen string 生成go app 接口监听的地址 (default "127.0.0.1:5555") --pkg string 生成go app 包名称(go version > 1.12) 生成go.mod文件, eg: ginbroSon[root@ericzhou felix]# web界面对于那些喜欢使用命令行的同学,你们可以选择使用web界面来操作 ...

May 22, 2019 · 2 min · jiezi

GORM 关联查询

定义了一个 User 和 Company, User 中可以包含多个 Company, 如下:type User struct { ID int gorm:"TYPE:int(11);NOT NULL;PRIMARY_KEY;INDEX" Name string gorm:"TYPE: VARCHAR(255); DEFAULT:'';INDEX" Companies []Company gorm:"FOREIGNKEY:UserId;ASSOCIATION_FOREIGNKEY:ID" CreatedAt time.Time gorm:"TYPE:DATETIME" UpdatedAt time.Time gorm:"TYPE:DATETIME" DeletedAt *time.Time gorm:"TYPE:DATETIME;DEFAULT:NULL"}type Company struct { gorm.Model Industry int gorm:"TYPE:INT(11);DEFAULT:0" Name string gorm:"TYPE:VARCHAR(255);DEFAULT:'';INDEX" Job string gorm:"TYPE:VARCHAR(255);DEFAULT:''" UserId int gorm:"TYPE:int(11);NOT NULL;INDEX"}在查询 User 时希望把 Company 的信息也一并查询, 有以下三种方法:Related使用 Related 方法, 需要把把 User 查询好, 然后根据 User 定义中指定的 FOREIGNKEY 去查找 Company, 如果没定义, 则调用时需要指定, 如下:var u Userdb.First(&u)db.Model(&u).Related(&u.Companies).Find(&u.Companies)User 列表时遍历列表一一查询 CompanyAssociation使用 Association 方法, 需要把把 User 查询好, 然后根据 User 定义中指定的 AssociationForeignKey 去查找 Company, 必须定义, 如下:var u Userdb.First(&u)db.Model(&u).Association(“Companies”).Find(&u.Companies)Preload使用 Preload 方法, 在查询 User 时先去获取 Company 的记录, 如下:// 查询单条 uservar u Userdb.Debug().Preload(“Companies”).First(&u)// 对应的 sql 语句// SELECT * FROM users LIMIT 1;// SELECT * FROM companies WHERE user_id IN (1);// 查询所有 uservar list []Userdb.Debug().Preload(“Companies”).Find(&list)// 对应的 sql 语句// SELECT * FROM users;// SELECT * FROM companies WHERE user_id IN (1,2,3…);本文中是一对多, 一对一的也是类似的, 完整代码见: GORM Related ...

April 14, 2019 · 1 min · jiezi

PHP 转 Go,用 Laravel、thinkphp 的用法造了一个 ThinkGo 框架

ThinkGo 是一个轻量级的 Go 语言 MVC 框架,目前支持路由、中间件、控制器、请求、响应、Session、视图、日志等 web 框架应该具备的基本功能,致力于让代码简洁、富于表达力,帮助开发者快速构建一个 Web 应用。安装go get -u github.com/thinkoner/thinkgo用法package mainimport ( “github.com/thinkoner/thinkgo” “fmt” “github.com/thinkoner/thinkgo/router” “github.com/thinkoner/thinkgo/context”)func main() { app := thinkgo.BootStrap() app.RegisterRoute(func(route *router.Route) { route.Get("/", func(req *context.Request) *context.Response { return thinkgo.Text(“Hello ThinkGo !”) }) route.Get("/ping", func(req *context.Request) *context.Response { return thinkgo.Json(map[string]string{ “message”: “pong”, }) }) // Dependency injection route.Get("/user/{name}", func(req *context.Request, name string) *context.Response { return thinkgo.Text(fmt.Sprintf(“Hello %s !”, name)) }) }) // listen and serve on 0.0.0.0:9011 app.Run()}项目地址GitHub: https://github.com/thinkoner/...Gitee: https://gitee.com/thinkgo/thi…大佬们来指点指点,贡献贡献代码。。。 ...

January 29, 2019 · 1 min · jiezi