golang基础-和mysql打交道

mob604756e80bb7 · · 340 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

mysql简介

mysql是关系型数据库RDBMS(Relational database management system)的典型代表,也是后台开发中打交道最多的一个组件。

go-sql-driver访问数据库

插入操作

func InsertUser(user bean.User) (bool){   //开启事务   tx, err := DB.Begin()   if err != nil{       fmt.Println("tx fail")       return false   }   //准备sql语句   stmt, err := tx.Prepare("INSERT INTO nk_user (`name`, `password`) VALUES (?, ?)")   if err != nil{       fmt.Println("Prepare fail")       return false   }   //将参数传递到sql语句中并且执行   res, err := stmt.Exec(user.UserName, user.Password)   if err != nil{       fmt.Println("Exec fail")       return false   }   //将事务提交   tx.Commit()   //获得上一个插入自增的id   fmt.Println(res.LastInsertId())   return true } 复制代码

查询操作

func SelectAllUser() ([]bean.User) {     //执行查询语句     rows, err := DB.Query("SELECT * from nk_user")     if err != nil{         fmt.Println("查询出错了")         }     var users []bean.User     //循环读取结果     for rows.Next(){         var user bean.User         //将每一行的结果都赋值到一个user对象中         err := rows.Scan(&user.Id, &user.UserName, &user.Password)         if err != nil {             fmt.Println("rows fail")         }         //将user追加到users的这个数组中         users = append(users, user)     }     return users } 复制代码

这里会发现,当字段比较多,有二三十个,sql语句都需要自己写,同时scan还得指定每一个字段去接收,如果类型一样的错位了,就是一个难以排查的事故。 同时,sql语句太长,也不好维护。在大型项目开发过程中,几乎所有团队都会选择用orm。

golang 的gorm

什么是orm

ORM全称是:Object Relational Mapping(对象关系映射),其主要作用是在编程中,把面向对象的概念跟数据库中表的概念对应起来。举例来说就是,我定义一个对象,那就对应着一张表,这个对象的实例,就对应着表中的一条记录。

连接数据库

import (     "github.com/jinzhu/gorm"     _ "github.com/jinzhu/gorm/dialects/mysql" ) func main() {   db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")   defer db.Close() } 复制代码

创建记录

user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} db.NewRecord(user) // => returns `true` as primary key is blank db.Create(&user) db.NewRecord(user) // => return `false` after `user` created 复制代码

查询记录

// Get first record, order by primary key db.First(&user) //// SELECT * FROM users ORDER BY id LIMIT 1; // Get last record, order by primary key db.Last(&user) //// SELECT * FROM users ORDER BY id DESC LIMIT 1; // Get all records db.Find(&users) //// SELECT * FROM users; // Get record with primary key (only works for integer primary key) db.First(&user, 10) //// SELECT * FROM users WHERE id = 10; 复制代码

查询条件

// Get first matched record db.Where("name = ?", "jinzhu").First(&user) //// SELECT * FROM users WHERE name = 'jinzhu' limit 1; // Get all matched records db.Where("name = ?", "jinzhu").Find(&users) //// SELECT * FROM users WHERE name = 'jinzhu'; db.Where("name <> ?", "jinzhu").Find(&users) // IN db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users) // LIKE db.Where("name LIKE ?", "%jin%").Find(&users) // AND db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users) // Time db.Where("updated_at > ?", lastWeek).Find(&users) db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users) 复制代码

Save命令

db.Save(&data) gorm支持一个Save命令,其语意是当model中Id主键有值时,更新该model。无值时创建一条。如果是需要先从数据库读model,再更新写入,就很适合用Save操作。

gorm 特性

链式组合

gromdb是链式的结构: 每个操作返回的都是gorm.DB db.Where().Limit().Offset()

在业务开发中,可以灵活运用,比如有type类型,status状态两个字段,如果填了才过滤,不填就返回所有的,可以按下面这样写:

if status != "" {     db.Where("status = ?", status) } if type != 0 "" {     db.Where("type = ?", type) } db.Find([]*Data) 复制代码

callback

callback是一个不得不提的能力,顾名思义,回调,即 通过它可以方便地对gorm进行二次封装。目前gorm 支持如下callback

  • BeforeSave : Save操作之前
  • BeforeCreate :Create操作之前
  • AfterUpdate:Update操作之后
  • AfterSave:Save操作之后
  • BeforeDelete:Delete操作之前
  • AfterDelete:Delete操作之后
  • AfterFind:Find之后

比如,如果有加密需求,就可以在beforeCreate时运用加密。 在afterFind运用解秘。以下是一个简单的条件判断示例:

func (u *User) BeforeUpdate() (err error) {     if u.readonly() {         err = errors.New("read only user")     }     return } // Rollback the insertion if user's id greater than 1000 func (u *User) AfterCreate() (err error) {     if u.Id > 1000 {         err = errors.New("user id is already greater than 1000")     }     return } 复制代码

如果callback中有失败,那么整个事物都会回滚。

开发模式推荐

单独建一个model文件夹,一个model一个文件,可以理解为一个表一个文件。 在其中用类型的方法,封装好针对这个model直接访问的方法。 同时定义个对外暴露的变量Nsp,外面直接通过这个Nsp访问方法。 如果有针对多表的访问和联合,应该再封装一个更高层。这样代码结构会比较清晰。


作者:牛牛码特
链接:https://juejin.cn/post/6844903920003710989
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:mob604756e80bb7

查看原文:golang基础-和mysql打交道

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

340 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传