gorm介绍
一、什么是orm?
Object-Relationl Mapping,即对象关系映射,这里的Relationl指的是关系型数据库
它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
二、gorm
1.Golang写的,GitHub上活跃度很高的orm库
2.特点:
- 全功能ORM(几乎)
- 关联(包含一个,包含多个,属于,多对多,多种包含)
- Callbacks(创建/保存/更新/删除/查找之前/之后)
- 预加载(急加载)
- 事务
- 复合主键
- SQL Builder
- 自动迁移
- 日志
- 可扩展,编写基于GORM回调的插件
- 每个功能都有测试
- 开发人员友好
3.安装
go get github.com/jinzhu/gorm
4.官方文档:http://gorm.book.jasperxu.com/
DDL操作
对数据库,表,字段等的操作,这里指的DDl不包括数据库
一、数据库
- 连接数据库
// 引入gorm及驱动包
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
db,db_err := gorm.Open("mysql","root:Qazwsx123@[tcp](localhost:3306)/test_gorm?charset=utf8&parseTime=True&loc=Local")
if err!= nil{
panic(err)
}
defer db.Close() // 关闭连接
// loc=Local:表示根据本地时区走
// parseTime:处理time.Time
二、表
1.创建表
type User struct {
Id int
Name string
Age int
}
// 创建表
db.Table("user").CreateTable(&User{}) // 指定表名
db.CreateTable(&User{}) // 不指定表名,模型后面会加个s
2.删除表
db.DropTable(&User{}) // 使用模型名
db.DropTable("users") // 直接使用表名
db.DropTableIfExists(&User{}) // 先判断是否存在再删除,可以接受多个参数,模型和字符串都可以
3.检查表是否存在
is_has := db.HasTable(&User{}) // 使用模型
is_has := db.HasTable("users") // 使用表名
fmt.Println(is_has)
三、列(不建议进行操作,直接在模型上指定迁移即可)
1.修改列
// 修改模型`User`的description列的数据类型为`text`
db.Model(&User{}).ModifyColumn("description", "text")
2.删除列
// 删除模型`User`的description列
db.Model(&User{}).DropColumn("description")
3.添加外键
db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
// 第一个参数: 外键字段
// 第二个参数 : 外键表(字段)
// 第三个参数 : ONDELETE
// 第四个参数 : ONUPDATE
4.索引
// 为`name`, `age`列添加索引`idx_user_name_age`
db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
// 为多列添加唯一索引
db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
四、数据库迁移
1.自动迁移
自动迁移仅仅会创建表,添加缺少列和索引,并且不会改变现有列的类型或删除未使用的列以保护数据
db.AutoMigrate(&User{})
db.AutoMigrate(&User{}, &Product{}, &Order{})
// 创建表时添加表后缀
db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
DML操作
是对数据的操作
一、增删改查
1.增
db.Create(&User{Id:1,Name:"hallen",Age:18})
2.查
var user User
db.First(&user,1) // 默认使用id字段
fmt.Println(user)
db.First(&user,"name=?","hallen") // 查询指定字段
fmt.Println(user)
3.改:先查再改
var user User
db.First(&user,1) // 默认使用id字段
db.Model(&user).Update("age",20) // 这里的Model是查询出来的结构体对象user,不是模型
4.删:先查再改
var user User
db.First(&user,1) // 默认使用id字段
db.Delete(&user)
模型定义一
一、模型定义的作用
用作数据库数据转换和自动建表
二、模型名和表名的映射关系
- 规则
- 第一个大写字母变为小写,
- 遇到其他大写字母变为小写并且在前面加下划线,
- 连着的几个大写字母,只有第一个遵循上面的两条规则,其他的大写字母转为小写,不加下划线,遇到小写,前面的第一个大写字母变小写并加下划线
- 复数形式
- 举例
- User --> users 首字母小写,复数
- UserInfo --> user_infos
- DBUserInfo --> db_user_infos
- DBXXXXUserInfo --> dbxxxx_user_infos
三、在默认表名上加其他规则
// 在默认表名前加sys_前缀
gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string {
return "sys_" + defaultTableName;
}
自定义表名:
func (模型) TableName() string{
return "新的表名"
}
四、结构体字段名和列名的对应规则
- 规则 * 列名是字段名的蛇形小写
- 举例
- Name --> name
- CreatedTime --> create_time
- 可以通过gorm标签指定列名,AnimalId int64
gorm:"column:beast_id"
五、gorm.Model
基本模型定义gorm.Model,包括字段ID,CreatedAt,UpdatedAt,DeletedAt
只需要在自己的模型中指定gorm.Model匿名字段,即可使用上面的四个字段
// 添加字段 `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
type User struct {
gorm.Model
Name string
}
ID:主键自增长
CreatedAt:用于存储记录的创建时间
UpdatedAt:用于存储记录的修改时间
DeletedAt:用于存储记录的删除时间
模型定义二
一、结构体标签gorm的使用
type UserInfo struct {
Id int `gorm:"primary_key"`
Name string `gorm:"index"`
Age int
}
二、gorm标签属性值
- -: 忽略,不映射这个字段
gorm:"-"
- primary_key:主键
gorm:"primary_key"
- AUTO_INCREMENT:自增
gorm:"AUTO_INCREMENT"
- not null:不为空,默认为空
gorm:"not null"
- index:索引,
gorm:"index"
- 创建索引并命名:
gorm:"index:idx_name_code"
- 创建索引并命名:
-
- 优化查询,相当于图书的目录
- unique_index:唯一索引
gorm:"unique_index"
- unique:唯一
gorm:"unique"
- column:指定列名
gorm:"column:user_name"
- size:字符串长度,默认为255
gorm:"size:64"
- type:设置sql类型
gorm:"type:varchar(100)"
// 不推荐直接改类型 - default
default:'galeone'
默认值
多个属性值之间用分号分隔(英文的;):gorm:"size:64;not null"
模型定义三
一、一对一
1.属于
// UserProfile属于User,外键是在UserProfile模型,外键字段为:UId
type User struct {
Id int
Name string
Age int
Addr string
}
type UserProfile struct {
Id int
Pic string
CPic string
Phone string
User User `gorm:"ForeignKey:UId;AssociationForeignKey:Id"` // 关联关系
//UserID int // 默认关联字段为Id
UId int // uid
}
注:
// 外键默认使用UserID,如果不指定外键,则使用默认的外键字段,
// 默认关联ID,通过AssociationForeignKey指定关联字段
2.包含
// UserProfile 包含一个 User, 外键在User模型,外键字段为:PId
type User struct {
Id int
Name string
Age int
Addr string
PId int
}
type UserProfile struct {
Id int
Pic string
CPic string
Phone string
User User `gorm:"ForeignKey:PId;AssociationForeignKey:Id"` // 关联关系
}
属于:关系和外键在同一方,有关系的那一方属于另外一个模型
包含:关系和外键不在同一方,有关系的那一方包含另外一个有外键的模型
二、一对多
type User2 struct {
Id int
Name string
Age int
Addr string
Articles []Article `gorm:"ForeignKey:UId;AssociationForeignKey:Id"`
}
type Article struct {
Id int
Title string
Content string
Desc string
// 外键
UId int
}
三、多对多
type Article2 struct {
AId int `gorm:"primary_key:true"`
Title string
Content string
Desc string
Tags []Tag `gorm:"many2many:Article2s2Tags"` // ;ForeignKey:AId;AssociationForeignKey:TId
}
type Tag struct {
TId int `gorm:"primary_key:true"`
Name string
Desc string
}
创建/更新时不会保存关联:gorm:"save_associations:false"
一对一操作
一、增加
user_profile := relate_tables.UserProfile{
Pic:"1.jpg",CPic:"2.jpg",Phone:"xxx",
User:relate_tables.User{Name:"hallen",Age:18,Addr:"xxx"},
}
result := db.Create(&user_profile)
默认是关联创建或更新的
创建/更新时不会保存关联:`gorm:"save_associations:false"`
二、查询
1.第一种方式:Association
// 先查询出来,在根据Association属性值关联查询,Association的值为关联表的模型名称
var u_profile relate_tables.UserProfile
db.First(&u_profile,1)
fmt.Println(u_profile)
db.Model(&u_profile).Association("User").Find(&u_profile.User)
2.第二种方式:Preload
var u_profile relate_tables.UserProfile
db.Debug().Preload("User").First(&u_profile,1) // 关系名
fmt.Println(u_profile)
3.第三种方式:Related
var user_profile3 relate_tables.UserProfile
db.First(&user_profile3,1)
var user relate_tables.User
db.Model(&user_profile3).Related(&user,"User")
三、更新
// 先关联查询出来,再更新关联表中的字段
var u_profile1 relate_tables.UserProfile
db.Debug().Preload("User").First(&u_profile1,1)
fmt.Println(u_profile1)
db.Model(&u_profile1.User).Update("p_id",2)
四、删除
// 通过主表删除关联表中的
var u_profile2 relate_tables.UserProfile
db.Debug().Preload("User").First(&u_profile2,1)
db.Delete(&u_profile2.User)
一对多操作、
一、增加
user := relate_tables.User2{
Name:"halle",
Age:18,
Addr:"xxx",
Articles:[]relate_tables.Article{{
Title:"标题测试",
Content:"内容测试",
Desc:"描述测试",
},{
Title:"标题测试2",
Content:"内容测试2",
Desc:"描述测试2",
},
},
}
ret := db.Create(&user)
fmt.Println(ret.RowsAffected)
fmt.Println(ret.Error)
二、查询
1.Preload
var user2 relate_tables.User2
db.Preload("Articles").Find(&user2,2) // 关系名
fmt.Println(user2)
2.Association
var user2 relate_tables.User2
db.First(&user2,2)
db.Model(&user2).Association("Articles").Find(&user2.Articles)
fmt.Println(user2)
3.Related
var user2 relate_tables.User2
db.First(&user2,1)
var articles []relate_table.Article
db.Model(&user2).Related(&articles, "Articles") // 关系名称
三、更新
// 先查询
var user2 relate_tables.User2
db.Preload("Articles").Find(&user2,2) // 关系名
// 再更新,更新指定条件,不然会把所有满足条件的都更新
db.Model(&user2.Articles).Where("title=? and uid=?","标题测试2",2).Update("uid",3) // name和uid限制条件
// update只能更新一个字段,如果想同时更新多个字段,使用save,后面会讲
四、删除
// 先查询
var user2 relate_tables.User2
db.Preload("Articles").Find(&user2,2) // 关系名
// 再删除,删除要指定条件,不然会把所有满足条件的都删除
db.Delete(&user2.Articles,"title=? and uid=?","标题测试3",3)
// 或者使用where
db.Where("title=? and uid=?","标题测试3",3).Delete(&user2.Articles)
多对多操作
一、增加
// 一篇文章有多个帖子
article := relate_tables.Article2{
Title:"测试多对多标题1",
Content:"测试多对多内容1",
Desc:"测试多对多描述1",
Tags:[]relate_tables.Tag{{
Name:"django",
Desc:"django标签",
},
{
Name:"python",
Desc:"python标签",
},
},
}
ret := db.Create(&article)
fmt.Println(ret.Error)
或者先插入单表的,再关联插入
tag := relate_tables.Tag{Name:"beego2",Desc:"beego2标签"}
db.Create(&tag)
article := relate_tables.Article2{
Title:"测试多对多标题4",
Content:"测试多对多内容5",
Desc:"测试多对多描述5",
Tags:[]relate_tables.Tag{
tag,
},
}
db.Create(&article) // 这里不会重复插入前面create的数据
二、查询
1.Preload
var article relate_tables.Article2
db.Preload("Tags").Find(&article,1)
fmt.Println(article)
2.Association
var article relate_tables.Article2
db.First(&article,1)
db.Model(&article).Association("Tags").Find(&article.Tags)
fmt.Println(article)
3.Related
var article relate_tables.Article2
db.First(&article,1)
var tags []relate_table.Tag
db.Model(&article).Related(&tags, "Tags")
三、更新
// 先查询
var article relate_tables.Article2
db.Preload("Tags").Find(&article,1)
// 再更新,记得加条件
db.Model(&article.Tags).Where("name = ?","beego").Update("name","xxx")
四、删除
// 先查询
var article relate_tables.Article2
db.Preload("Tags").Find(&article,1)
// 再删除,记得加条件
db.Where("name = ?","xxx").Delete(&article.Tags)
DB接口
First:
// 按照主键顺序的第一条记录,(主键升序)
var user model.User
result := db.First(&user)
fmt.Println(user)
result.RowsAffected // 返回找到的记录数
result.Error // returns error
// sql语句:SELECT * FROM users ORDER BY id LIMIT 1;
FirstOrCreate
// 未找到 user,则根据给定条件创建一条新纪录
var user model.User
db.FirstOrCreate(&user, User{Name: "hallen"})
// 找到了 `name` = `hallen` 的 user
db.Where(User{Name: "hallen"}).FirstOrCreate(&user)
Last
// 获取最后一条记录(主键降序)
var user model.User
// 按照主键顺序的最后一条记录
db.Last(&user)
fmt.Println(user)
// sql语句:SELECT * FROM users ORDER BY id DESC LIMIT 1;
Take
// 获取一条记录,没有指定排序字段
var user model.User
db.Take(&user)
// sql语句:SELECT * FROM users LIMIT 1;
Find
var user model.User
// 所有记录
db.Find(&users, []int{1,2,3})
// sql语句:// SELECT * FROM users WHERE id IN (1,2,3);
result := db.Find(&users)
// sql语句:SELECT * FROM users;
// 根据指定条件查询
db.Find(&user, "name = ?", "hallen")
//或者结合where
db.Where("name = ?", "hallen").Find(&users)
// sql语句:SELECT * FROM users WHERE name = 'hallen';
db.Where("name LIKE ?", "%ha%").Find(&users)
// sql语句:SELECT * FROM users WHERE name LIKE '%hal%';
Where
var user model.User
// 根据条件查询得到满足条件的第一条记录
db.Where("role_id = ?", "2").First(&user)
fmt.Println(user)
var users []model.User
// 根据条件查询得到满足条件的所有记录
db.Where("user_id = ?", "1").Find(&users)
fmt.Println(users)
// like模糊查询
db.Where("role_id like ?", "%2").Find(&users)
fmt.Println(users)
db.Where("updated_at > ?", "2019-02-08 18:08:27").Find(&users)
fmt.Println(users)
// struct结构查询条件
db.Where(&DqmUserRole{RoleId: "1,2", UserId: "1"}).First(&user)
fmt.Println(user)
条件:
=
LIKE
IN:Where("name IN ?", []string{"hallen", "hallen2"})
AND:Where("name = ? AND age >= ?", "jinzhu", "22")
Time:Where("updated_at > ?", lastWeek)
BETWEEN:Where("created_at BETWEEN ? AND ?", lastWeek, today)
Select
指定要从数据库检索的字段,默认情况下,将选择所有字段;
db.Select("name, age").Find(&users)
SELECT name, age FROM users;
db.Select([]string{"name", "age"}).Find(&users)
SELECT name, age FROM users;
db.Table("users").Select("COALESCE(age,?)", 42).Rows() // COALESCE:聚合
SELECT COALESCE(age,'42') FROM users;
Create
1.插入单条
user := models.User{Name:"李四",Age:18,Addr:"xxx",Pic:"/static/upload/pic111.jpg",Phone:"13411232312"}
result := db.Create(&user)
user.ID // 返回插入数据的主键
result.Error // 返回 error
result.RowsAffected // 返回插入记录的条数
2.批量插入:暂不支持
user4 := []relate_tables.User{
{
Name:"hallen8",
Age:18,
Addr:"xxx",
},
{
Name:"hallen9",
Age:18,
Addr:"xxx",
},
}
db.Create(&user4) // 这种方式不支持
save
var user model.User
db.First(&user)
user.Name = "jinzhu 2"
user.Age = 100
db.Save(&user)
update
var users []model.User
db.Where("active = ?", true).find(&users).Update("name", "hello")
db.Where("active = ?", true).find(&users).Updates(User{Name: "hello", Age: 18})
// update也可以使用map:map[string]interface{}{"name": "hello", "age": 18}
// 也可以使用save更新
delete
db.Delete(&user,1)
// 批量删除
db.Where("age = ?", 20).Delete(&User{})
Unscoped:软删除
// 也就是逻辑删除
// gorm.Model 将DeletedAt 字段设置为当前时间
// 需要再模型中指定
type User struct {
ID int
Deleted `gorm:"DeletedAt"` // 如果设置了所有的删除都将是逻辑删除
Name string
}
// 在查询时会忽略被软删除的记录
db.Where("age = 20").Find(&user)
// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL;
// 查询逻辑删除的数据
db.Unscoped().Where("age = 20").Find(&users)
// SELECT * FROM users WHERE age = 20;
// 想要物理删除的办法
db.Unscoped().Delete(&user)
Not
var user model.User
db.Not(User{Name: "hallen", Age: 18}).First(&user)
// SELECT * FROM `users` WHERE (`users`.`name` <> 'hallen6') AND (`users`.`age` <> 19);
Or
var users []model.User
db.Where("name = 'hallen'").Or(User{Name: "hallen2", Age: 18}).Find(&users)
// SELECT * FROM users WHERE name = 'hallen' OR (name = 'jinzhu 2' AND age = 18);
Order
var users []model.User
db.Order("age desc").Find(&users) // 注意这里的order要在find前面,否则不生效
fmt.Println(users)
// SELECT * FROM users ORDER BY age desc;
默认为asc
Limit和Offset
Limit 指定获取记录的最大数量 Offset 指定在开始返回记录之前要跳过的记录数量
var users []model.User
db.Limit(3).Find(&users) // 三条
// SELECT * FROM users LIMIT 3;
db.Limit(10).Offset(5).Find(&users) // 从5开始的10条数据
// SELECT * FROM users OFFSET 5 LIMIT 10;
Scan
将结果扫描到另一个结构中。
type Result struct {
Id int64
}
var results []Result
db.Select("id").Where("user_id in (?)", []string{"1", "2"}).Find(&dqmUserRole20).Scan(&results)
fmt.Println(results)
Count
获取模型的记录数
db.Where("name = ?", "hallen").Find(&users).Count(&count)
// SELECT count(*) FROM users WHERE name = 'jinzhu'
db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count)
// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)
db.Table("deleted_users").Count(&count)
// SELECT count(*) FROM deleted_users;
Group & Having
GROUP BY语句用来与聚合函数(aggregate functions such as COUNT, SUM, AVG, MIN, or MAX.)联合使用,只返回一个单个值
HAVING语句通常与GROUP BY语句联合使用,用来过滤由GROUP BY语句返回的记录集。
HAVING语句的存在弥补了WHERE关键字不能与聚合函数联合使用的不足
type result struct {
Date time.Time
Total int
}
db.Select("name, count(*)").Group("name").Find(&result)
// select name,count(*) FROM users GROUP BY `age`
db.Select("name, count(*)").Group("name").Having("add = ?","xxx").Find(&result)
// select name,count(*) FROM users GROUP BY `age` 后面不能用where限制条件,只能使用having
// select name,count(age) FROM users GROUP BY `age` HAVING addr='xxx'
Distinct:暂无
db.Distinct("name", "age").Order("name, age desc").Find(&results)
Join
left join … on …
right join … on …
db.Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&result{})
高级查询
FirstOrInit和Attrs
FirstOrInit:获取第一个匹配的记录,或者使用给定的条件初始化一个新的记录(仅适用于struct,map条件)
Attrs:如果没有找到记录,则使用Attrs中的数据来初始化一条记录:
var user model.User
// 查不到该条记录,则使用attrs值替换,// 查到记录,则使用数据库中的值
db.Where(User{Name:"hallen"}).Attrs(User{Name:"hallen",Age:18}).FirstOrInit(&user)
FirstOrInit和Assign
Assign:不管是否找的到,最终返回结构中都将带上Assign指定的参数,有则代替,没有则添加
var user model.User
// 不管是否找到对应记录,使用Assign值替代查询到的值
db.Where("id = ?", "1").Assign(model.User{Id: "15"}).FirstOrInit(&user)
Pluck
Pluck 用于从数据库查询单个列,并将结果扫描到切片。如果您想要查询多列,您应该使用 Select 和 Scan
var ages []int64
db.Find(&users).Pluck("age", &ages)
var names []string
db.Model(&User{}).Pluck("name", &names)
// 超过一列的查询,应该使用 `Scan` 或者 `Find`,例如:
db.Select("name", "age").Scan(&users)
db.Select("name", "age").Find(&users)
Scopes
Scopes 允许你指定常用的查询,可以在调用方法时引用这些查询
func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
return db.Where("amount > ?", 1000)
}
func PaidWithCreditCard(db *gorm.DB) *gorm.DB {
return db.Where("pay_mode_sign = ?", "C")
}
func PaidWithCod(db *gorm.DB) *gorm.DB {
return db.Where("pay_mode_sign = ?", "C")
}
func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
return func (db *gorm.DB) *gorm.DB {
return db.Where("status IN (?)", status)
}
}
db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders)
// 查找所有金额大于 1000 的信用卡订单
db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders)
// 查找所有金额大于 1000 的货到付款订单
db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
// 查找所有金额大于 1000 且已付款或已发货的订单
LogMode
Gorm有内置的日志记录器支持,默认情况下,它会打印发生的错误。
// 启用Logger,显示详细日志
db.LogMode(true)
// 也可以查看单语句的信息
db.Debug().Where("name = ?", "hallen").First(&User{})
错误处理
如果在执行SQL查询的时候,出现错误,GORM 会将错误信息保存到 *gorm.DB 的Error字段,我们只要检测Error字段就可以知道是否存在错误。
一、处理单个错误
err := db.Where("name = ?", "tizi365").First(&user).Error
if err != nil {
// 错误处理
}
// 或者
result := db.Where("name = ?", "jinzhu").First(&user)
if result.Error != nil {
// 错误处理
}
二、处理多个错误
通过GetErrors获取错误列表
errors := db.First(&user).Limit(10).Find(&users).GetErrors()
fmt.Println(len(errors)) // 打印错误数量
// 遍历错误内容
for _, err := range errors {
fmt.Println(err)
}
三、错误种类
gorm.错误类型进行判断,如gorm.ErrRecordNotFound
1.RecordNotFound:查询不到数据,不适用于切片
gorm.IsRecordNotFoundError(err) {
// 没有查询到数据
}
2.ErrInvalidSQL:无效sql
3.ErrInvalidTransaction:事务有错
4.ErrCantStartTransaction:无法开启事务,出现在使用Begin的情况下
5.ErrUnaddressable:使用不可寻址的值,传递的指针值不对
事务
用 db.Begin() 声明开启事务,结束的时候调用 tx.Commit(),异常的时候调用 tx.Rollback()
ct := db.Begin() // 开启事务
ret3 := ct.Commit()
if ret3.Error != nil {
ct.Rollback() // 回滚
}
复合主键
联合主键、组合主键
type Product struct {
ID int `gorm:"primary_key"`
ERPID int `gorm:"primary_key"`
}
原生sql
一、查询用Raw
var users []relate_tables.User
db.Raw("select * from users").Find(&users)
二、增改删用 Exec
db.Exec("insert into users (name,age) values(?,?)","hallen222",111)
db.Exec("update users set name = ? where id = ?","hallen111",1)
db.Exec("delete from users where id = ?",1)
三、返回单条
row,_ := db.Raw("select * from users").Row()
四、返回多条
row,_ := db.Raw("select * from users").Rows()
配置文件
一、配置信息:mysql.json
{
"host":"localhost",
"port":"3306",
"user_name":"root",
"password":"Qazwsx123",
"database":"gin_project",
"logo_mode":true
}
二、加载配置文件
package data_source
import (
"os"
"io/ioutil"
"encoding/json"
)
type MysqlConf struct {
Host string `json:"host"`
Port string `json:"port"`
UserName string `json:"user_name"`
Password string `json:"password"`
DataBase string `json:"database"`
LogoMode bool `json:"logo_mode"`
}
func LoadMysqlConf() *MysqlConf {
mysql_conf := MysqlConf{}
file,err := os.Open("conf/mysql.json")
if err != nil {
panic(err)
}
defer file.Close()
byte_data,err2 := ioutil.ReadAll(file)
if err2 != nil {
panic(err2)
}
err3 := json.Unmarshal(byte_data,&mysql_conf)
if err3 != nil {
panic(err3)
}
return &mysql_conf
}
三、使用配置信息
package data_source
import (
"github.com/jinzhu/gorm"
"gin_project/models"
_ "github.com/jinzhu/gorm/dialects/mysql"
"fmt"
)
var Db *gorm.DB
var err error
func init() {
mysql_conf := LoadMysqlConf()
logo_mode := mysql_conf.LogoMode
data_source := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=true&loc=Local",
mysql_conf.UserName,
mysql_conf.Password,
mysql_conf.Host,
mysql_conf.Port,
mysql_conf.DataBase,
)
Db,err = gorm.Open("mysql",data_source)
if err != nil {
panic(err)
}
Db.LogMode(logo_mode)
Db.DB().SetMaxOpenConns(100) // 最大连接数
Db.DB().SetMaxIdleConns(50) // 最大空闲数
Db.AutoMigrate(&models.User{})
}
代码示例抽取:
实现接口:D:\go\workspace\src\gin-vue-admin\common\datasource
base结构体:D:\go\workspace\src\gin-vue-admin\repository\BaseRepository.go
集成结构体:D:\go\workspace\src\gin-vue-admin\repository\UserRepository.go