Golang名库 xorm讲解

Xorm - Github
Api - 文档

2. 学习记录

2.1 目录结构

记录文件托管于 coding 平台

file

2.2 db/init.go

package db

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/go-xorm/xorm"
    "log"
    "os"
    "xorm_leaning/logs"
)

var X *xorm.Engine

func init()  {
    var err error
    // 创建 mysql 引擎
    X, err = xorm.NewEngine("mysql", "root:root@tcp(127.0.0.1:3306)/dbtest?charset=utf8")
    if err != nil {
        log.Fatalf("Fail to create engin %v", err)
    }

    // 将日志保存到文件
    filename, err := logs.CreateTimeDir("mysql")
    if err != nil {
        log.Fatalf("Fail to mkdir %v", err)
    } else if(filename != ""){
        //file, err := os.Create(filename);
        file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
        if err != nil {
            log.Fatalln(err)
            return
        }
        X.SetLogger(xorm.NewSimpleLogger(file))
    }
    // 开启日志
    X.ShowSQL(true)

    // 设置默认 URL 缓存
    // 启动一个全局的内存缓存(缓存最大上限 1000)
    // cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 1000)
    // X.SetDefaultCacher(cacher)

    fmt.Println("testing ====================== begin")
    tables, err := X.DBMetas()
    if err != nil {
        fmt.Println(err)
        return
    }
    for k, v := range tables{
        fmt.Printf("key:%#v,val: %#v\n", k, v)
    }
    fmt.Println("testing ====================== end")
}

2.3 logs/init.go

package logs

import (
    "os"
    "path"
    "time"
)

// @title 创建日志目录
// @params classification string mysql
// @return string 文件名(月份+日期)
func CreateTimeDir(classification string) (string, error) {
    now := time.Now();
    dir := "logs/" + classification + "/" + now.Format("2006")
    filename := path.Join(dir, now.Format("0102")+".log")
    err := os.MkdirAll(dir, 0666)
    if err != nil {
        return "", err
    }
    return filename, nil
}

2.4 model/AccountModel.go

package model

import (
    "encoding/json"
    "errors"
    "fmt"
    "log"
    "xorm_leaning/db"
)

type Account struct {
    Id int64
    Name string `xorm:"unique"`
    Balance float64
    Version int `xorm:"version"`    // 乐观锁
}

func init()  {
    // 自动同步数据结构
    if err := db.X.Sync2(new(Account)); err != nil {
        log.Fatalf("Fail to Sync2 database: %v", err)
    }
}

// @title 增【新增记录】
// @parasms name string 用户名
// @parasms balance float64 存款
// @return int64 新增记录 id
func NewAccount(name string, balance float64) (int64, error) {
    mod := &Account{
        Name:    name,
        Balance: balance,
    }
    _, err := db.X.Insert(mod)
    return mod.Id, err
}

// @title 删【删除记录】
func DeleteAccount(id int64) error {
    _, err := db.X.Delete(&Account{
        Id:      id,
    })
    return err
}

// @title 改【更新】
// @parasms id int64 Id
// @parasms data []byte Json
// @return *Account 结构体
func SetAccount(id int64, data []byte) (*Account, error) {
    mod, err := GetAccount(id)
    if err != nil {
        return nil, err
    }
    // json 转 struct
    err = json.Unmarshal(data, &mod)
    if err != nil {
        log.Fatalln(err)
    }
    _, err = db.X.Update(mod)
    return mod, err
}

// @title 查【获取】
// @parasms id int64 Id
// @return *Account 结构体
func GetAccount(id int64) (*Account, error) {
    mod := &Account{}
    has, err := db.X.Id(id).Get(mod)
    if err != nil {
        return nil, err
    } else if !has {
        return nil, errors.New("Account not found")
    }
    return mod, nil
}

// @title 事物及回滚
// @title 用户转账
// @parasms balance float64 转帐金额
func MakeTransfer(id1, id2 int64, balance float64) error {
    a1, err := GetAccount(id1)
    if err != nil {
        return err
    }
    a2, err := GetAccount(id2)
    if err != nil {
        return err
    }
    if a1.Balance < balance {
        return errors.New("没有足够的余额")
    }

    a1.Balance -= balance
    a2.Balance += balance

    // 创建事物 Session 对象
    sess := db.X.NewSession()
    defer sess.Close()
    // 开启事物
    if err = sess.Begin(); err != nil{
        return err
    }
    // 通过 Session 操作数据库
    if _, err = sess.Update(a1); err != nil {
        // 事物回滚
        return sess.Rollback()
    } else if _, err = sess.Update(a2); err != nil{
        // 事物回滚
        return sess.Rollback()
    }
    // 提交事物
    return sess.Commit()
}

// @title 统计记录条数
// @return int64 统计结果:条目数
func GetAccountCount() (int64, error) {
    // return db.X.Where("id > 10").Count(new(Account))
    return db.X.Count(new(Account))
}

// @title 迭代查询
func IterativeQuery(method int) error {
    if method == 1 {
        // x.Iterate
        return db.X.Iterate(new(Account), func(idx int, bean interface{}) error {
            fmt.Printf("%d: %#v\n", idx, bean.(*Account))
            return nil
        })
    } else {
        // x.Rows
        a :=  new(Account)
        rows, err := db.X.Rows(new(Account))
        if err != nil {
            log.Fatalf("Fail to get rows: %v\n", err)
        }
        defer rows.Close()
        for rows.Next() {
            if err = rows.Scan(a); err != nil {
                log.Fatalf("Fali to get row: %v\n", err)
            }
            fmt.Printf("%#v\n", a)
        }
        return nil
    }
}

// @title 常用查询方法
// @ methods_1 只取某一列的值
// x.Cols("name").Iterate(new(Account), ...)

// @ methods_2 忽略某一列的值
// x.Omit("name").Iterate(new(Account), ...)

// @ methods_3 查询结果偏移(常用于分页)
// @ 第 3 页,每页取 20 条数据
// x.Limit(20, 2).Iterate(new(Account), ...)

// @title 事件钩子
// @title 插入之前
func (this *Account) BeforeInsert() {
    fmt.Println("Account - BeforeInsert...");
}
// @title 插入之后
func (this *Account) AfterInsert() {
    fmt.Println("Account - AfterInsert...");
}

2.5 main.go

package main

import (
    "fmt"
    "log"
    "xorm_leaning/model"
)

func main() {
    fmt.Println("main begin ....")

    count, err := model.GetAccountCount()
    if err != nil {
        log.Fatalf("Fail to get count: %v\n", err)
    }
    // 填充 10 条假数据
    for i:=count; i<10;i++ {
        if _, err = model.NewAccount(fmt.Sprintf("joe%d", i), float64(i)*100); err != nil {
            log.Fatalf("Fail to create account: %v\n", err)
        }
    }
    fmt.Println("   |----", "假数据填充完毕;")

    // 迭代查询
    fmt.Println("   |----", "迭代查询开始:")
    fmt.Println(model.IterativeQuery(1))
    fmt.Println()
    fmt.Println(model.IterativeQuery(2))
    fmt.Println("   |----", "迭代查询结束;")

    fmt.Println("main end ....")
}
讨论数量: 0

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!