使用 GORM 连接数据库| 青训营

170 阅读6分钟

SQL概念

什么是SQL

即Structured Query Language结构化查询语言,访问和处理关系型数据库的计算机语言 

 为什么需要数据库 

程序运行时使用到的数据通常保存在内存中,一旦关闭就消失了 想要将数据保存下来只能存到文件里,带来很多重复性的保存、解析代码 数据库可以帮助持久化数据这一过程 也就是应用程序不需要知道数据底层的存储情况,只需要使用数据库提供的接口就可以实现 

 什么是关系型数据库 

可以把每一类数据看成一个二维表格,每一行是一个记录,每一列是一个字段 不同的关系表之间可以用一对多、多对多等关系 每一个属性需要定义数据类型,比如INT、BIGINT、DOUBLE、CHAR(N)、DATETIME等 

关系模型 

字段定义: 

  •  数据类型 
  • 是否允许为NULL(NULL表示数据不存在) 

关系表的主键 :

在关系表中,不能存在两条完全一样的记录,主键就是用于区分不同记录的字段 主键的几个特点:

  •  主键一定是唯一的 
  • 主键(最好)不再被修改,通常用一个自增的ID或者GUID 
  • 联合主键就是同时存在多个主键,只需一个不重复即可 

关系表的外键 

外键用于维护表与表之间的关系 

  •  一对多:如果想在表A中关联表B,只需要在表A的字段中加上表B的主键作为外键 
  • 多对多:通过一个中间表,维护两个一对多的关系即可 
  • 一对一:和一对多类似,可以把一个大表中一些经常查询的信息拆分出来,并设置一对一关系,从而加快查询速度 

关系表的索引 

  • 索引用于对记录进行预排序,从而加快查询速度 
  •  通过唯一索引可以增加唯一性约束

 SQL语法 

语法特点

不区分大小写 

查询数据SELECT 

查询表中的所有列

SELECT * FROM table_name;

SELECT表示一次查询,*表示所有字段 

 FROM [table_name]指出在哪个表中查询 

条件查询

SELECT * FROM table_name WHERE condition; 
SELECT * FROM table_name WHERE condition1 AND condition2; 
SELECT * FROM table_name WHERE condition1 OR condition2; 
SELECT * FROM table_name WHERE NOT condition;

优先级:NOT > AND > OR,可以加小括号改变条件运算顺序 

 条件表达式: 

 >       <       =	>=	   <=	 <>	LIKE 
大于	小于	等于	大于等于	小于等于	不等于	使用通配符

投影查询

即只查询表中的特定列 

SELECT col1, col2 FROM table_name;
SELECT col1, col2 id FROM table_name; 

 可以在列名后面加上一个别名 

 排序 默认从低到高,使用DESC反序 

SELECT * FROM table_name ORDER BY col1, col2;
SELECT * FROM table_name ORDER BY col1, col2 DESC; 

分页显示 

从第i个记录开始取(i从1开始),最多取出n条(可能少于n或为空),(i, n+i] 

SELECT * FROM table_name LIMIT n OFFSET i;
SELECT * FROM tbale_name LIMIT i, n; 

聚合查询

可以用COUNT函数查询关系表的行数

SELECT COUNT(*) FROM table_name;
SELECT COUNT(*) num FROM table_name;

 查询的结果仍然是一个表,只有一个字段"COUNT(*)"(一般加上别名),和一个记录N(行数) 

 聚合函数: 

SUM()               	AVG()	                MAX()   MIN()
只能用于数值类型,和	只能用于数值类型,平均值	最大值	最小值 

分组: 

 SELECT id, COUNT(*) num FROM table_name GROUP BY id; 

可以先将记录分组,然后再做聚合统计(比如样例中每个id的记录数) 

 多表查询 

SELECT * FROM table1 t1, table2 t2; 

会产生M*N条查询 

 连接查询 

也是一种多表的查询,但是是直接把另一个表的其中几个字段加入到当前的表中 

 SELECT *, t2.name FROM table1 t1
	INNER JOIN talb2 t2
	ON t2.id == t1.t2_id; 

还有**[RIGHT/LEFT/FULL] OUT JOIN**等连接方式 

插入数据INSERT

插入记录 

INSERT INTO table_name (col1, col2) VALUES 
	(val1, val2), 
	(val3, val4); 

更新数据UPDATE 

更新记录 

UPDATE table_name SET col1=val1, col2=val2 WHERE condition; 

删除数据DELETE 

删除记录 

DELETE FROM table_name;
DELETE FROM table_name WHERE condition; 

管理 MySQL

登录mysql-client

mysql -u[username] -p 

退出myql 

EXIT; 

查看所有用户

其实就是mysql数据库user表的user和host字段 

 SELECT user, host FROM mysql.user; 

创建用户 

CREATE USER '[name]'@'[ip]' IDENTIFIED BY '[password]'

显示所有数据库 

SHOW DATABASES; 

创建数据库 

CREATE DATABASE dbname; 

删除数据库 

DROP DATABASE dbname; 

操作数据库 

USE name; 

显示所有关系表 

SHOW TABLES; 

查看表结构 

DESC table_name; 

创建表 

CREATE TABLE table_name;
CREATE TABLE table_name(
	col type features
); 

删除表 

DROP TABLE table_name; 

在表中添加列 

ALTER TABLE [table_name] ADD COLUMN [col_name] [type] [features]

在表中删除列 

ALTER TABLE [table_name] DROP COLUMN [col_name]

GORM 

什么是ORM 

Object Relation Mapping对象关系映射,也就是将程序中送到的对象(类)映射到数据库的关系表上

连接数据库 

 db, err := gorm.Open("mysql", "root:root@(localhost:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local") 

关闭数据库 

db.Close() 

GORM增删查改

type Student struct{
    Name 	string
    Age		int
}
var student Student
var students []Student 

创建表 

db.AutoMigrate(&Student{}) 

就可以在数据库中创建一个字段和Student中对应的表 

 插入记录 

db.Create(&Student{Name: "name", Age: 18})
db.Create(&student)
db.Create(&students)
db.Model(&Student{}).Create([]map[string] interface{}{
    {Name: "name", Age: 18},
}) 

 查询记录 

// 第一条记录(主键升序)
db.First(&student)
db.First(&student, 1)	// id=1
db.First(&student, []int{1, 2, 3})
db.First(&student, "Age = ?", 18)
// 获取一条记录
db.Take(&student)
// 最后一条记录
db.Last(&student)
// 查询全部记录
db.Find(&students) 

条件查询 

Where可以加查询条件 

  •  可以加上IN、LIKE、AND、BETWEEN等 

  • 可以用struct和map查询 

    db.Where("Name = ?", "zhiyu").Find(&students)

Not和Or方法

db.Not("Age = ?", 18).Find(&students)
db.Where(...).Or(...).Find(&students) 

Select只检索出特定字段

db.Select("name", "age").Find(&students) 

 Order方法指定排序方式 

 db.Order("age DESC, name").Find(&students) 

同样支持Limit&Offset和Group By 

 更新记录 

db.Model(&student).Update("Age", 19) 

 删除记录 

db.Delete(&student) 

GORM约定 

主键 

  • 默认使用ID作为表的主键 

  •  如果需要设置其他的主键,就用primaryKey标签 

    type User struct { ID string UUID string gorm:"primaryKey" Name string Age int }

表名 

默认是蛇形命名法(小写+下划线) 

 通过实现Tabler接口可以自定义 

type Tabler interface {
    TableName() string
}
// user -> user_profile
func (User) TableName() stromg {
    return "user_profile"
}

列名 

默认也是蛇形命名法 

 type User struct {
    ID 		string
    UUID	string `gorm:"column:universally_unique_identifier"`
    Name 	string
    Age		int
} 

时间戳 

直接在结构体中加指定字段 

 CreatedAt:创建时间 

 UpdatedAt:更新时间 

 DeletedAt:删除时间 

 // gorm.Model
type Model struct {
  ID        uint           `gorm:"primaryKey"`
  CreatedAt time.Time
  UpdatedAt time.Time
  DeletedAt gorm.DeletedAt `gorm:"index"`
}
type User struct {
    gorm.Model
    ID 		string
    UUID	string 
    Name 	string
    Age		int
} 

gorm.Model会直接将其中的字段嵌入到User中,也可以用embeded标签嵌入其他的结构体

 权限控制 

控制只读、只写、只创建、只更新或忽略等 

 字段标签 

标签名	       描述
column	       列名
type	       列数据类型
primaryKey     主键
unique	       唯一,不可重复
default	       默认值
not mull       不为空
autoIncrement  自动增长
embeded	       嵌入字段
index	       索引
check	       创建约束