MySQL基础及GORM框架

SQL概念

  • 什么是SQL

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

  • 为什么需要数据库

程序运行时使用到的数据通常保存在内存中,一旦关闭就消失了

想要将数据保存下来只能存到文件里,带来很多重复性的保存、解析代码

数据库可以帮助持久化数据这一过程

也就是应用程序不需要知道数据底层的存储情况,只需要使用数据库提供的接口就可以实现

  • 什么是关系型数据库

可以把每一类数据看成一个二维表格,每一行是一个记录,每一列是一个字段

不同的关系表之间可以用一对多、多对多等关系

每一个属性需要定义数据类型,比如INT、BIGINT、DOUBLE、CHAR(N)、DATETIME等

  • 关系模型

字段定义:

  1. 数据类型
  2. 是否允许为NULL(NULL表示数据不存在)
  • 关系表的主键

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

主键的几个特点:

  1. 主键一定是唯一的
  2. 主键(最好)不再被修改,通常用一个自增的ID或者GUID

联合主键就是同时存在多个主键,只需一个不重复即可

  • 关系表的外键

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

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

索引用于对记录进行预排序,从而加快查询速度

通过唯一索引可以增加唯一性约束

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对象关系映射,也就是将程序中送到的对象(类)映射到数据库的关系表上

  • 什么是GORM

  • 连接数据库

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可以加查询条件

  1. 可以加上IN、LIKE、AND、BETWEEN等
  2. 可以用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创建约束
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用 GORM 框架中,可以使用 Go 语言的协程(goroutine)来实现并发操作。下面是一个示例: ```go package main import ( "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type User struct { ID int Name string } func main() { db, err := gorm.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local") if err != nil { panic("failed to connect database") } defer db.Close() // 创建一个协程来执行查询操作 go func() { var user User db.First(&user, 1) fmt.Println(user) }() // 创建另一个协程来执行插入操作 go func() { newUser := User{Name: "Alice"} db.Create(&newUser) }() // 等待一段时间,以确保协程有足够的时间执行 time.Sleep(time.Second) // 查询所有用户 var users []User db.Find(&users) fmt.Println(users) } ``` 在上面的示例中,我们使用了两个协程来执行数据库操作。第一个协程执行了查询操作,第二个协程执行了插入操作。通过使用协程,我们可以并发地执行这些操作,提高程序的性能。 需要注意的是,在使用协程时,我们需要确保数据库连接是线程安全的。在上面的示例中,我们使用了 `defer db.Close()` 来关闭数据库连接,以确保资源的释放。另外,为了确保协程有足够的时间执行,我们使用了 `time.Sleep(time.Second)` 来进行等待。 当然,具体的实现方式可能因为业务需求的不同而有所差异,上述示例仅供参考。在实际使用中,你可以根据自己的需求来选择合适的并发方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值