error
抛异常和处理异常--panic recover()接收异常的信息并返回 err := recover() 返回异常--return 自定义error
v := err.(type) --获取变量err的实际类型
error 是 Go 语言中的一个预定义接口类型,它定义了一个方法 Error(),该方法返回一个字符串,表示错误的描述信息。
具体而言,error 接口的定义如下:
type error interface {
Error() string
}
这意味着任何实现了 Error() string 方法的类型,都可以被视为实现了 error 接口。
匿名字段:go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段
接口--interface go的面向对象,也可以使用这个实现OOP的多态。
type 接口类型名 interface{
方法名1( 参数列表1 ) 返回值列表1
方法名2( 参数列表2 ) 返回值列表2
…
}
1.接口名:使用type将接口定义为自定义的类型名。Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有字符串功能的接口叫Stringer等。接口名最好要能突出该接口的类型含义。
2.方法名:当方法名首字母是大写且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码访问。
3.参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
实现接口的条件
一个对象只要全部实现了接口中的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表。 接口类型变量能够存储所有实现了该接口的实例。eg
func main() {
var x Sayer // 声明一个Sayer类型的变量x
a := cat{} // 实例化一个cat
b := dog{} // 实例化一个dog
x = a // 可以把cat实例直接赋值给x
x.say() // 喵喵喵
x = b // 可以把dog实例直接赋值给x
x.say() // 汪汪汪
}
注意:值接收者可以接收指针或者值的变量,但是指针接受者只能接收指针的变量。 go中一个类型可以实现多个接口,多个类型可以实现一个班接口
并且一个接口的方法,不一定需要由一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。
type Washer interface {
wash()
dry()
}
type dyer struct{}
func (a dyer) dry() {
fmt.Println("甩一甩")
}
type haier struct {
dyer //嵌入结构体
}
func (h haier) wash() {
fmt.Println("洗一洗")
}
func main() {
var x Washer
var b = haier{}
x = b
x.dry()
x.wash()
}
注意dyer此时是嵌套在结构体中实现接口的一部分函数的,外部结构体可以直接调用嵌套结构体的实现的接口方法,反过来是不行的,会报错没有实现这个方法
接口也可以嵌套,同理,外层的接口可以直接调用内层接口的方法
空接口的定义
空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。
空接口类型的变量可以存储任意类型的变量。
****使用空接口当做函数的参数时,可以接收任意类型的参数
空接口作为map的值
使用空接口实现可以保存任意值的字典。
// 空接口作为map值
var studentInfo = make(map[string]interface{})
studentInfo["name"] = "李白"
studentInfo["age"] = 18
studentInfo["married"] = false
fmt.Println(studentInfo)
x.(T) 类型断言 该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。
因为空接口可以存储任意类型值的特点,所以空接口在Go语言中的使用十分广泛。
关于接口需要注意的是,只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。
当使用 Go 语言进行数据库操作时,gorm 是一个常用的 ORM(对象关系映射)库,而 MySQL 则是一种常见的关系型数据库。结合 gorm 和 MySQL,可以方便地进行数据库的连接、数据模型定义、查询和更新操作。
以下是 gorm + MySQL 的主要功能和特性的中文笔记描述:
- 连接数据库:gorm 提供了简单的方式来连接 MySQL 数据库。可以使用
gorm.Open函数指定数据库的连接信息,例如数据库类型、主机地址、端口号、用户名和密码等。连接成功后,可以使用 gorm 对象来执行后续的数据库操作。 - 定义数据模型:在 gorm 中,可以通过定义结构体来表示数据库中的表,并使用标签(Tag)来定义字段的映射关系。每个字段都可以指定类型、大小、约束条件等。还可以使用结构体之间的关系(例如一对一、一对多、多对多)来建立表之间的关联关系。
- 创建数据表:在 gorm 中,可以使用
AutoMigrate方法根据定义的数据模型自动创建对应的数据表。它可以自动检测数据库中的表结构和模型的差异,并进行相应的迁移操作,保证两者的一致性。 - 查询数据:gorm 提供了丰富的查询方法,可以根据指定的条件从数据库中获取数据。可以使用
Find方法获取所有满足条件的记录,使用First方法获取满足条件的第一条记录,还可以使用Where方法指定更复杂的查询条件。 - 更新数据:通过 gorm,可以方便地更新数据库中的数据。可以使用
Save方法更新单个对象的数据,也可以使用Update方法批量更新符合指定条件的数据。更新操作可以针对某个字段进行修改,也可以对多个字段进行同时修改。 - 删除数据:gorm 提供了
Delete方法来删除符合指定条件的数据。可以根据主键、字段值等条件进行删除操作。还可以使用软删除功能,在删除时将记录的特定字段标记为已删除状态而非真正删除记录。 - 事务支持:gorm 提供了事务功能,用于保证一系列数据库操作的原子性。可以使用
Begin方法开始一个事务,然后在事务中执行多个操作,最后使用Commit提交事务或使用Rollback回滚事务。 - 关联查询:在 gorm 中,可以通过预加载(Preloading)的方式进行关联查询。可以使用
Preload方法在查询时预先加载关联表的数据,避免了 N+1 查询的问题,提高了查询效率。
总的来说,gorm + MySQL 的组合提供了方便、灵活和高效的数据库操作能力。它减少了手动编写 SQL 语句的工作量,提供了面向对象的方式来进行数据模型定义和操作。结合 gorm 和 MySQL,可以轻松地进行各种数据库操作,并实现复杂的业务逻辑。
package main
//gorm demo1 //连接不同的数据库要使用不同的驱动
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type UserInfo struct {
ID int
Name string
Gender string
Hobby string
}
func main() {
db, err := gorm.Open("mysql", "root:20030303@tcp(localhost:3306)/b1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//创建表 自动迁移(把结构体和数据表进行对应)
db.AutoMigrate(&UserInfo{})
//创建记录
//u1 := UserInfo{1, "假紫颜", "女", "飞机"}
//db.Create(&u1)
//查询
var u UserInfo
db.First(&u) //查询表中第一条数据保存到u中
fmt.Printf("u:%#v\n", u)
//更新
db.Model(&u).Update("hobby", "受宠")
db.First(&u)
fmt.Printf("u:%#v\n", u)
//删除
db.Delete(&u)
db.First(&u)
fmt.Printf("u:%#v\n", u)
}
package main
import (
"database/sql"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
type User struct {
gorm.Model
Name string
Age sql.NullInt64 `gorm:"column:user age"` //零值类型
Birthday *time.Time
Email string `gorm:"type:varchar(120);unique_index"`
Role string `gorm:"size:255"` //字段大小255
MemberNumber *string `gorm:"unique;not null"` //设置会员号唯一且不为空
Num int `gorm:"AUTO_INCREMENT"` //设置为自增类型
Address string `gorm:"index:addr"` //给字段创建索引
IgnoreMe int `gorm:"-"`
}
type N struct {
Name string
}
func (User) TableName() string {
return "User_funcname"
} //使用User{}映射创建的表的名字会使用这个函数的返回值的string
func main() {
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
return "SMS_" + defaultTableName
} //修改默认的表名的前缀
db, err := gorm.Open("mysql", "root:20030303@(localhost:3306)/b1?charset=utf8mb4&parseTime=true&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.SingularTable(true) //禁用复数 就是创建的时候的表的名字后面会跟s 这是禁用这个选项
db.AutoMigrate(&User{})
db.AutoMigrate(&N{})
//使用User结构体创建名字为moxu的表
//db.Table("moxu").CreateTable(&User{})
}
Gorm 模型定义
定义模型
type User struct {
ID int64
Name string
Age int64
}
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// 1.定义模型
type User struct {
ID int64
Name string
Age int64
}
func main() {
//连接mysql数据库
// db, err := gorm.Open("mysql", "root:20030303@(localhost:3306)/b1?charset=utf8mb4&parseTime=True&loc=Local")
db, err := gorm.Open("mysql", "root:20030303@(localhost:3306)/b1?charset=utf8mb4&parseTime=true&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//2.把模型与数据库中的表对应起来 把模型的变化映射到数据库中的数据表
db.AutoMigrate(&User{})
//3.创建
u := User{ //在代码层面创建的一个User对象
ID: 0,
Name: "moxu",
Age: 18,
}
fmt.Println(db.NewRecord(&u)) //判断主键是否为空 主键为空代表还没有在数据库中去存入 为空返回true 不为空返回false
db.Create(&u) //在数据库中创建了一条moxu 18的记录
fmt.Println(db.NewRecord(&u))
}
Gorm创建记录及字段默认值相关
利用tag进行默认值的设置
字段 type gorm:"default 'moxu'"