GORM
GORM : Object Relational Mapping
对象:程序中的对象、实例,如结构体
关系:关系数据库,例如MySQL
数据表;结构体
数据行:结构体实例
字段:结构体字段
ORM的优点在于提高开发效率
缺点:牺牲执行能力,牺牲灵活性以及弱化SQL能力
11.1 在本地或远程启动并连接数据库
11.1.1 启动服务器和Docker
ssh root@xxx
systemctl start docker //启动docker
11.1.2 使用容器启动MySQL
docker run -d -p 80:80 docker/getting-started //启动docker
docker run --name mysql -e MYSQL_ROOT_PASSWORD=xxx, -p 3301:3306 -d mysql //启动容器
docker exec -it 8b4545118c60 /bin/bash //进入容器
mysql -u root -p //
mysql -u root -p
Enter password: //输入密码则会看到连接成功
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 17
Server version: 8.0.28 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
11.1.3 数据库操作
CREATE DATABASE db1; //创建数据库
show databases; //查看看数据库是否创建成功
use db1; //使用数据库
show tables;//查看数据库中的数据表
11.2 使用GORM连接数据库
import (
"github.com/jinzhu/gorm" //引入gorm
_ "github.com/jinzhu/gorm/dialects/mysql" //匿名引入mysql驱动,不直接使用,而是使用其内部一些初始化函数
)
//定义一个结构体(在数据库中对应一个表)
type UserInfo struct {
ID int
Name string
Gender string
Hobby string
}
func main() {
//连接数据库
//注意书写用户名、密码、主机名称、端口号以及数据库名称
db, err := gorm.Open("mysql", "root:xxx@tcp(xxx:3301)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
//操作完之后记得关闭
defer db.Close()
//创建表 自动迁移(把结构体和数据表进行对应)
db.AutoMigrate(&UserInfo{})
//创建数据行,增加数据
u1 := UserInfo{ID: 1, Name: "shi", Gender: "male", Hobby: "swimming"}
db.Create(&u1)
}
mysql> show tables; //查看表是否已经创建
mysql> desc user_infos; //查看表结构
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| gender | varchar(255) | YES | | NULL | |
| hobby | varchar(255) | YES | | NULL | |
+--------+--------------+------+-----+---------+----------------+
mysql> select * from user_infos; //查看main函数中创建好的信息
+----+------+--------+----------+
| id | name | gender | hobby |
+----+------+--------+----------+
| 1 | shi | male | swimming |
+----+------+--------+----------+
查询数据
var u UserInfo
db.First(&u)
fmt.Printf("u:%#v\n", u)
u:main.UserInfo{ID:1, Name:"shi", Gender:"male", Hobby:"swimming"}
更新和删除
//更新,将爱好信息变更
db.Model(&u).Update("hobby","running")
//删除
db.Delete(&u)
mysql> select * from user_infos; //更新结果
+----+------+--------+---------+
| id | name | gender | hobby |
+----+------+--------+---------+
| 1 | shi | male | running |
+----+------+--------+---------+
mysql> select * from user_infos; //删除结果
Empty set (0.00 sec)
11.3 GORM模型定义
定义模型,以后所有操作就只针对于这个模型
type User struct {
gorm.Model //匿名结构体,继承gorm.Model
Name string
Age sql.NullInt64
BirthDate *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"` //设置字段大小为255
MemberNumber *string `gorm:"unique;not null"` //设置会员号,唯一并且不为空
Num int `gorm:"AUTO_INCREMENT"` //设置自增长
Address string `gorm:index:"addr"` //给Address字段设置addr索引
IgnoreMe int `gorm:"-"` //忽略该字段
}
创建表
func main() {
//连接数据库
//注意书写用户名、密码、主机名称、端口号以及数据库名称
db, err := gorm.Open("mysql", "root:15willis,@tcp(shiyivei.com:3301)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
//操作完之后记得关闭
defer db.Close()
//创建表
db.AutoMigrate(&User{})
}
查看表结构,前四个是内嵌结构体的字段
mysql> desc users;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| deleted_at | datetime | YES | MUL | NULL | |
| name | varchar(255) | YES | | NULL | |
| age | bigint | YES | | NULL | |
| birth_date | datetime | YES | | NULL | |
| email | varchar(100) | YES | UNI | NULL | |
| role | varchar(255) | YES | | NULL | |
| member_number | varchar(255) | NO | UNI | NULL | |
| num | int | YES | | NULL | |
| address | varchar(255) | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
GORM中主键、表名和列名的约定
ID作为主键,若无则使用tag指定
表明默认为结构体小些的复数,可以修改
type Animal struct {
AnimalID int64 `gorm:"primary_key"`
Name string
Age int64
}
mysql> desc animals;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| animal_id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| age | bigint | YES | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
db.Table("xiaodongwu").CreateTable(&User{}) //指定表名称
列名也是可以更改的
11.4 创建记录
package main
import (
"fmt"
"github.com/jinzhu/gorm" //引入gorm
_ "github.com/jinzhu/gorm/dialects/mysql" //匿名引入mysql驱动,不直接使用,而是使用其内部一些初始化函数
)
type User struct {
ID int64
Name *string `gorm:"default:'xiaowangzi'"` //默认值,如过传入空值可以使用指针
Age int64
}
func main() {
//1.连接数据库
db, err := gorm.Open("mysql", "root:15willis,@tcp(shiyivei.com:3301)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//2.把模型与数据库中的表对应起来
db.AutoMigrate(&User{})
//show create table users; 查看表的创建语句
//3.创建数据
user := User{Name: new(string), Age: 48}
fmt.Println(db.NewRecord(&user)) //判断主键是否为空
db.Create(&user)
fmt.Println(db.NewRecord(&user)) //判断主键是否为空
}
11.5 查询操作
type User struct {
gorm.Model
Name string
Age int64
}
func main() {
//1.连接数据库
db, err := gorm.Open("mysql", "root:15willis,@tcp(shiyivei.com:3301)/db1?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//2.把模型与数据库中的表对应起来
db.AutoMigrate(&User{})
//show create table users; 查看表的创建语句
//3.创建数据
//user1 := User{Name: "shiyivei", Age: 17}
//db.Create(&user1)
//
//user2 := User{Name: "jinzhu", Age: 27}
//db.Create(&user2)
//4.查询数据
// var user User
// db.First(&user) //查询第一条数据
// fmt.Printf("%#v\n", user)
var users []User
db.Find(&users) //查询所有数据
fmt.Printf("%#v\n", users)
}
更多关于查询的操作可以参考官方文档
11.6 更新
//5.更新
user.Name = "yivei"
user.Age = 27
db.Save(&user) //更新数据
db.Model(&user).Update("name", "xiaowangzi") //更新数据
更多关于查询的操作可以参考官方文档
11.7 删除
gorm默认软删除
//6.删除
user.ID = 1
db.Debug().Delete(&user) //删除数据
select * from users;
+----+------------+------+---------------------+---------------------+---------------------+
| id | name | age | created_at | updated_at | deleted_at |
+----+------------+------+---------------------+---------------------+---------------------+
| 1 | xiaowangzi | 27 | NULL | 2022-05-18 14:19:57 | 2022-05-18 14:19:57 |
| 2 | xiaowangzi | 27 | 2022-05-18 13:29:26 | 2022-05-18 14:21:52 | NULL |
| 3 | jinzhu | 27 | 2022-05-18 13:29:26 | 2022-05-18 13:29:26 | NULL |
+----+------------+------+---------------------+---------------------+---------------------+
注意:当主键为0时,会删除所有数据
更多关于查询的操作可以参考官方文档