今天接触了orm的概念。orm 全程 object relation mapping 对象映射关系,这到底是做什么的呢?orm是为了解决面向对象和关系数据库之间存在的互不匹配的现象的技术,c++里边我们经常说面向对象,也就是说我的操作都是可以看成以某个对象为基础,让这个对象进行一系列的操作,但是当我们在程序中进行数据库操作的时候,确实在和复杂的sql打交道,我们在程序中操作数据库的时候是通过一些库文件,然后将一些特定的sql语句输入给我们的数据库,这里很容易想到我们之前所说的防sql注入问题,orm就很好的解决了这些问题,这样让我们的开发不再关注这些数据库的细节,而是专心在业务逻辑上,甚至程序员不用懂数据库就可以进行开发,并且有了这个中间层之后,数据库的迁移操作也变得非常简单,当然orm也是由缺点的,并不是说orm能够帮你生成所有的业务语句,有些复杂的还是需要sql并且orm的性能也是要低于直接使用sql语句的。
比如说我们想要创建一张表的时候,在sql中我们就需要使用语句
orm的框架有很多,甚至很多人自己搭建了自己的框架,其实这就是一个程序和数据库之间的一个中间层,这里我们要说的是gorm是golang的一个orm框架。
CREATE TABLE users(“name” VARCHAR(45) NULL,’age’ INT NULL);
但是我们在使用gorm的时候
type User struct{
name string
age int
}
db.Table(“users”).CreateTable(&User{})
这两个语句意思是一样的,这里我们创建了名字叫做users的表,表的内容gorm是通过结构体来定义的。
当我们想要往表中插入数据的时候 sql实现方式为
INSERT INTO users(“name”,”age“) values(”ee“,’18’);
在表中users的name列和age列插入了对应的ee,18数据。
但是当我们用gorm的时候就简单了很多
user:=User{name:”ee”,age: 18}
db.Create(&user)
首先定一个User类的结构体user,然后调用gorm的Create函数参数为user就可以插入到数据库中。
进行查询语句的时候sql实现方式
SELECT * FROM users WHERE name=“ee”;筛选出users中的名字为ee的数据
var users [ ]User//定义一个User类型的数组名字叫做users
1.db.Where(“name=?”,”ee”).Find(&users)//这里会将查询出来的所有数据放到users这个数组中。
2.db.Where(&User{name:”ee”,age:18}).Find(&users)
3.db.Where(map[string] interface{}{“name”:”ee”,”age”:18}).Find(&users)
这是三种gorm中的查询方式分别是通过sql、struct、map来查询数据。
当获取第一条匹配记录的时候 sql会通过limit条件来筛选
SELECT * FROM users WHERE name=“ee“ limit 1筛选出第一条匹配的记录
在gorm有一个单独的函数来获取第一条数据
var user User
db.Where(“name=?”,”ee”).First(&user)
这里和批量查询类似,批量查询需要创建一个数组来接受数据,这里需要创建一个单个变量来接受查询出来的数据。
同样如果要limit多条数据的时候SELECT * FRIN users LIMIT 3
db.Limit(3).Find(&users)
同样gorm里边也实现了like and in 等实现
db.Where(“name LIKE ?”,”%ee%”).Find(&user)
db.Where(“name=?AND age>=?” ,”ee”,”18”).Find(&users)
db.Where(“name in (?)”,[ ]string{“ee”,”sh”}).Find(&usere)
SELECT * FROM users WHERE name <> “ee"来表示查询users表中name不是ee的选项
db.Not(“name”,”ee”).First(&users)
SELECT * FROM users WHERE role=‘admin’ OR role =‘super_admin’;
db.Where(“role=?”,”admin”).Or(“role=?”,:super_admin”).FInd(&users)
并且gorm也是支持查询链 的
db.Where(“name=?”,”ee”).Or(“name=?”,”sh”).Not(“age=?”,18).Find(&users)
我们在查询数据库的时候几乎很少select * 而是选择部分字段。
SELECT name ,age FROM users;
db.Select(“name, age”).Find(&users)
db.Select([ ]string{“name”,”age”}).Find(&users
可以选择指定的字段来进行获取。
SELECT * FROM users ORDER BY age desc ,name
对数据进行排序 在 gorm中
db.Order(“age desc”).Order(“name”).Find(&users)
sql中可以通过count函数获取记录条数,SELECT count(*) FROM users WHERE name =“ee”
gorm中同样需要一个变量来接受值,所以需要提前创建一个int类型的变量
var count int
db.Where(“name=?”,”ee”).Count(&count) 这里将创建的int类型以指针的方式传入,不传指针的话 修改不起作用
对数据进行更新的时候gorm的操作就复杂了一些
UPDATE users SET name=“hello” WHERE id=111
var user User
db.Where(“id=?”,“111”).First(&user)
Db.Model(&user).Update(“name”,”hello”)
更新的时候也是需要先取出来然后再去对他进行修改
当进行多个属性修改的时候
db.Model(&user).Updates(map[string]interface{}{“name”:”hello”,”age”:18})
db.Model(&user).Update(User{name:”hello”,age:18})
删除数据的时候
DELETE from users where id=10;
在gorm也是需要先找到我要删除的数据 取出来然后传入到删除函数中去
var user User
db.Where(“id=?”,”10”).First(&user)
db.Delete(&user)
先找到id为10的数据保存到user中然后将数据传入到删除函数中,批量删除和查询是对应的, 先批量查询出来然后批量传入到删除数据中。
db.Where(“name=?”,”ee”).Delete(User{})
这里最后再引入一个软删除的概念,很多模型中有DeletedAt字段,那么就自动获取到了软删除的功能,那么在调用Delete的时候 数据并不会从数据库中永久删除而是将字段DeletedAt的值设置成当前的时间。
并且gorm也是支持事务的,我们都知道在数据库中的事务是很必要的一个事情,在grom中是支持事务的,不过是需要我们自己来简单的实现一些,假如说我们的事务是三步,我们要做的操作是1,2,3在执行操作前我们需要执行的是tx:=db.Begin()代表事务开始了,然后进行tx.Create()操作,之后对操作进行判断,如果成功执行了的话就执行2,继续3,如果在这之间有一个操作失败了,这里是需要我们通过if来进行判断的,如果失败就调用tx.Rollback来进行回滚操作,如果整个事务执行完了就要进行提交tx.commit()操作将整个事务过程就进行提交