Go 语言 实现简单的ORM框架示例

Go阿木 发布于 22 天前 7 次阅读


简单Go语言ORM框架示例实现

对象关系映射(Object-Relational Mapping,简称ORM)是一种编程技术,它将对象模型映射到关系模型,从而简化了数据库操作。在Go语言中,虽然有一些成熟的ORM库,如GORM、XORM等,但为了更好地理解ORM的工作原理,我们可以自己实现一个简单的ORM框架。本文将围绕Go语言,展示如何实现一个简单的ORM框架。

ORM框架设计

在实现ORM框架之前,我们需要明确以下几个关键点:

1. 模型定义:如何定义数据库表对应的Go语言结构体。

2. 映射规则:如何将结构体字段映射到数据库表的列。

3. 数据库操作:如何实现增删改查(CRUD)操作。

1. 模型定义

我们可以使用Go语言的`struct`来定义模型,并在结构体中使用标签(Tags)来指定数据库表名和列名。

go

type User struct {


ID int `db:"id"`


Name string `db:"name"`


Age int `db:"age"`


}


2. 映射规则

为了简化映射规则,我们假设每个结构体的字段名与数据库列名完全一致,并且字段类型可以直接映射到数据库类型。

3. 数据库操作

我们将实现基本的CRUD操作,包括:

- `Create`:创建记录

- `Read`:读取记录

- `Update`:更新记录

- `Delete`:删除记录

实现ORM框架

下面是一个简单的ORM框架实现:

go

package main

import (


"database/sql"


"fmt"


"log"


"reflect"


"strings"


)

// ORM 实例


type ORM struct {


db sql.DB


}

// NewORM 创建ORM实例


func NewORM(db sql.DB) ORM {


return &ORM{db: db}


}

// Create 创建记录


func (orm ORM) Create(model interface{}) error {


v := reflect.ValueOf(model)


if v.Kind() != reflect.Struct {


return fmt.Errorf("model must be a struct")


}

typ := v.Type()


table := typ.Name()


fields := typ.NumField()

// 构建插入语句


var columns, values []string


for i := 0; i < fields; i++ {


field := typ.Field(i)


tag := field.Tag.Get("db")


if tag == "" {


continue


}


columns = append(columns, tag)


values = append(values, "?")


}


stmt := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)", table, strings.Join(columns, ","), strings.Join(values, ","))

// 执行插入操作


_, err := orm.db.Exec(stmt, v.Field(0).Interface())


return err


}

// Read 读取记录


func (orm ORM) Read(model interface{}, id int) error {


v := reflect.ValueOf(model)


if v.Kind() != reflect.Ptr {


return fmt.Errorf("model must be a pointer")


}


v = v.Elem()


if v.Kind() != reflect.Struct {


return fmt.Errorf("model must be a struct")


}

typ := v.Type()


table := typ.Name()


fields := typ.NumField()

// 构建查询语句


var columns []string


for i := 0; i < fields; i++ {


field := typ.Field(i)


tag := field.Tag.Get("db")


if tag == "" {


continue


}


columns = append(columns, tag)


}


stmt := fmt.Sprintf("SELECT %s FROM %s WHERE id = ?", strings.Join(columns, ","), table)

// 执行查询操作


row := orm.db.QueryRow(stmt, id)


err := row.Scan(v.Field(0).Addr().Interface())


return err


}

// Update 更新记录


func (orm ORM) Update(model interface{}) error {


v := reflect.ValueOf(model)


if v.Kind() != reflect.Ptr {


return fmt.Errorf("model must be a pointer")


}


v = v.Elem()


if v.Kind() != reflect.Struct {


return fmt.Errorf("model must be a struct")


}

typ := v.Type()


table := typ.Name()


fields := typ.NumField()

// 构建更新语句


var columns []string


for i := 0; i < fields; i++ {


field := typ.Field(i)


tag := field.Tag.Get("db")


if tag == "" {


continue


}


columns = append(columns, fmt.Sprintf("%s = ?", tag))


}


stmt := fmt.Sprintf("UPDATE %s SET %s WHERE id = ?", table, strings.Join(columns, ","))

// 执行更新操作


_, err := orm.db.Exec(stmt, v.Field(0).Interface())


return err


}

// Delete 删除记录


func (orm ORM) Delete(model interface{}) error {


v := reflect.ValueOf(model)


if v.Kind() != reflect.Ptr {


return fmt.Errorf("model must be a pointer")


}


v = v.Elem()


if v.Kind() != reflect.Struct {


return fmt.Errorf("model must be a struct")


}

typ := v.Type()


table := typ.Name()


stmt := fmt.Sprintf("DELETE FROM %s WHERE id = ?", table)

// 执行删除操作


_, err := orm.db.Exec(stmt, v.Field(0).Interface())


return err


}

func main() {


// 假设数据库连接已经建立


db, err := sql.Open("mysql", "user:password@/dbname")


if err != nil {


log.Fatal(err)


}


defer db.Close()

// 创建ORM实例


orm := NewORM(db)

// 创建User实例


user := &User{


Name: "John Doe",


Age: 30,


}

// 创建记录


err = orm.Create(user)


if err != nil {


log.Fatal(err)


}

// 读取记录


userRead := &User{}


err = orm.Read(userRead, user.ID)


if err != nil {


log.Fatal(err)


}


fmt.Printf("Read User: %+v", userRead)

// 更新记录


userRead.Age = 31


err = orm.Update(userRead)


if err != nil {


log.Fatal(err)


}

// 删除记录


err = orm.Delete(userRead)


if err != nil {


log.Fatal(err)


}


}


总结

本文通过Go语言实现了一个简单的ORM框架,展示了如何定义模型、映射规则以及实现基本的CRUD操作。这个简单的ORM框架可以作为学习和理解ORM原理的起点。在实际应用中,ORM框架会更加复杂,包括但不限于事务管理、关联映射、自定义查询等高级功能。