Database/sql 及GORM解读 | 青训营

113 阅读1分钟

database/sql

基本用法

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql" // 引用driver
)

type Emp struct {
	Id      int
	EmpName string
	Age     int
	Gender  string
	Dept    interface{}
}

func main() {
	db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/ssm")
	if err != nil {
		fmt.Println(err)
	}
	rows, err := db.Query("select * from t_emp where emp_id = ?", 1)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer rows.Close() // 记得释放
	var emps []Emp
	for rows.Next() {
		var emp Emp
		err := rows.Scan(&emp.Id, &emp.EmpName, &emp.Age, &emp.Gender, &emp.Dept)
		if err != nil {
			fmt.Println(err)
			return
		}

		emps = append(emps, emp)
	}
	//
	if rows.Err() != nil {
		fmt.Println(rows.Err())
		return
	}

	for _, v := range emps {
		fmt.Println(v)
	}
}

设计原理:

database/sql 连接池

  • 操作接口给应用程序
  • 连接接口和操作接口给数据库

Driver接口:

// Driver接口
type Driver interface{
    Open(name string) (Conn, error)
}

// 注册全局driver
func Register(name sting, driver driver.Driver){
    driverMu.Lock()
    defer driverMu.UnLock()
    if driver == nil {
        pcnic("sql: Register driver is nil")
    }
    if _, dup := drivers[name]; dup {
        panic("sql:Register called twice for driver" + name)
    }
    drivers[name] = driver
}

业务代码

import _ "github.com/go-sql-driver/mysql"
func main(){
    db, err := sql.Open("mysql","gorm:gorm@tcp(localhost:9910)/gorm")
}
// 注册Driver
func init(){
    sql.Register("mysql",&MySQLDriver{})
}

通过设计结构体来实现驱动的注册等,可以解决一些字符串拼接等的问题

DB连接的几种类型:

  • 直接连接/Conn
  • 预编译/Stmt
  • 事物/Tx

GORM解读

设计简洁,功能强大,自由扩展的全功能的全功能ORM

基本用法:

package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Emp struct {
	EmpId   int
	EmpName string
	// Age     int
	// Gender  string
	// DeptId  int
}

func main() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/ssm?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(1)
	var emps []Emp
	err1 := db.Table("t_emp").Select("emp_id", "emp_name").Find(&emps).Error
	if err1 != nil {
		fmt.Println(err)
	}
	fmt.Println(emps)
}

模型定义

约定优于配置

  • 表名为struct name的 snake_cases的复数格式
  • 字段名为field name的snake——case单数格式
  • ID/Id 字段为主键,如果为数字,则为自增主键
  • CreatedAt 字段,创建时,保存当前时间
  • UpdatedAt 字段,创建,更新时,保存当前时间
  • gorm.DeletedAt 字段,默认开启soft delete模式