xorm学习笔记2:在golang中使用xorm

xorm安装

go get github.com/go-xorm/xorm,下载并安装xorm
如果遇到网速等原因造成下载不了,键入命令git config --global core.compression 9,示例如下:

E:\public_gopath>go get github.com/go-xorm/xorm
# cd .; git clone https://github.com/go-xorm/xorm E:\public_gopath\src\github.com\go-xorm\xorm
Cloning into 'E:\public_gopath\src\github.com\go-xorm\xorm'...
fatal: early EOF
fatal: the remote end hung up unexpectedly
fatal: index-pack failed
error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
package github.com/go-xorm/xorm: exit status 128

E:\public_gopath>git config --global core.compression 9

E:\public_gopath>go get github.com/go-xorm/xorm

xorm 连接MySQL

var x *xorm.Engine
x, err = xorm.NewEngine("mysql", "root:123456@/xorm?charset=utf8")

上面的示例中,root是MySQL的账户名,123456是MySQL的密码,xorm是数据库中对应的table名

代码示例

package main

import (
	"fmt"
	"strconv"
)

const prompt = ` 请输入数据选择相应功能:
0. 批量创建测试账户
1. 手动创建账户
2. 显示账号信息
3. 存款 
4. 取钱
5. 转账
6. 根据id排行显示账户 
7. 根据存款排行显示账户
8. 删除账户
9. 删除id大于?的账户
10. 查询银行账户总个数
11. 查询相同金额的账户个数
12. 迭代打印
99. 退出
`

func main() {
	fmt.Println("欢迎来到银行!")

Exit:
	for {
		fmt.Print(prompt)
		var num int
		fmt.Scanf("%d\n", &num)
		switch num {
		case 0:
			fmt.Printf("请输入要创建的【账户个数】")
			var initCount int
			fmt.Scanf("%d\n", &initCount)
			for i := 0; i < initCount; i++ {
				if err := newAccount("testName"+strconv.Itoa(i), float64(i*10)); err != nil {
					fmt.Print(err)
				} else {
					fmt.Printf("创建测试账户成功,i=%d\n", i)
				}
			}
		case 1:
			fmt.Println("请输入【账号】和【钱】")
			var name string
			var balance float64
			fmt.Scanf("%s %f\n", &name, &balance)
			if err := newAccount(name, balance); err != nil {
				fmt.Println("创建账号错误,err=", err)
			}
		case 2:
			fmt.Println("请输入账号【id】,查看账号信息!")
			var id int64
			fmt.Scanf("%d\n", &id)
			if a, err := getAccount(id); err != nil {
				fmt.Println(err)
			} else {
				fmt.Printf("%#v\n", a)
			}
		case 3:
			fmt.Println("请输入【账号id】及【存款金额】")
			var id int64
			var deposit float64
			fmt.Scanf("%d %f\n", &id, &deposit)
			if a, err := makeDeposit(id, deposit); err == nil {
				fmt.Printf("存款成功!你的账户信息:%#v\n", a)
			} else {
				fmt.Print(err)
			}
		case 4:
			fmt.Println("请输入【账号id】及【取款金额】!")
			var id int64
			var withDraw float64
			fmt.Scanf("%d %f\n", &id, &withDraw)
			if a, err := makeWithDraw(id, withDraw); err == nil {
				fmt.Printf("取款成功!你的账户信息:%#v\n", a)
			} else {
				fmt.Print(err)
			}
		case 5:
			fmt.Println("请分别输入【转账账户id】、【转账对象id】及【金额】")
			var id int64
			var targetId int64
			var count float64
			fmt.Scanf("%d %d %f\n", &id, &targetId, &count)
			if err := makeTrans(id, targetId, count); err == nil {
				fmt.Printf("转账成功!")
			} else {
				fmt.Println(err)
			}
		case 6:
			as, err := getAccountAscId()
			if err != nil {
				fmt.Println(err)
			} else {
				for i, a := range as {
					fmt.Printf("%d: %#v\n", i, a)
				}
			}
		case 7:
			as, err := getAccountsByBalance()
			if err != nil {
				fmt.Println(err)
			} else {
				for i, a := range as {
					fmt.Printf("%d: %#v\n", i, a)
				}
			}
		case 8:
			fmt.Println("请输入要删除的【账户id】")
			var id int64
			fmt.Scanf("%d\n", &id)
			if err := deleteAccountById(id); err == nil {
				fmt.Println("删除账户成功!")
			} else {
				fmt.Print(err)
			}
		case 9:
			fmt.Printf("请输入开始删除的【账户id】")
			var id int64
			fmt.Scanf("%d\n", &id)
			if err := deleteAccountByIdGreaterThen(id); err == nil {
				fmt.Println("删除成功")
			} else {
				fmt.Print(err)
			}

		case 10:
			if count, err := getAccountCount(); err == nil {
				fmt.Printf("当前银行总账户数:%d\n", count)
			} else {
				fmt.Print(err)
			}
		case 11:
			fmt.Println("请输入所要查看的【金额数】")
			var banlance float64
			fmt.Scanf("%f\n", &banlance)
			if count, err := getSameBalanceAccountCount(banlance); err == nil {
				fmt.Printf("当前银行中金额为%f的总账户数:%d\n", banlance, count)
			} else {
				fmt.Print(err)
			}
		case 12:
			fmt.Printf("迭代打印开始-------\n")
			x.Iterate(new(Account), func(idx int, bean interface{}) error {
				fmt.Printf("%d:%#v\n", idx, bean.(*Account))
				return nil
			})
		case 99:
			fmt.Println("bye!")
			break Exit
		default:

		}
	}
}

package main

import (
	"errors"
	"log"
	"strconv"

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

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

var x *xorm.Engine

func init() {
	log.Println("init")
	var err error
	x, err = xorm.NewEngine("mysql", "root:123456@/xorm?charset=utf8")
	if err != nil {
		log.Fatalf("Fail to create engine: %v", err)
	}

	if err = x.Sync(new(Account)); err != nil {
		log.Fatalf("Fail to sync database: %v", err)
	}
}

//创建账户
func newAccount(name string, balance float64) error {
	_, err := x.Insert(&Account{Name: name, Balance: balance})
	return err
}

//通过id得到账户信息
func getAccount(id int64) (*Account, error) {
	a := &Account{}
	has, err := x.Id(id).Get(a)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, errors.New("Account not found by id ,id:" + strconv.FormatInt(id, 10))
	}
	return a, nil
}

//存款
func makeDeposit(id int64, deposit float64) (*Account, error) {
	if a, err := getAccount(id); err == nil {
		a.Balance += deposit
		_, err = x.Update(a)
		return a, err
	} else {
		return nil, err
	}
}

//取款
func makeWithDraw(id int64, withDraw float64) (*Account, error) {
	if a, err := getAccount(id); err == nil {
		if a.Balance < withDraw {
			return a, errors.New("您的账户余额不足\n")
		}
		a.Balance -= withDraw
		_, err = x.Update(a)
		return a, err
	} else {
		return nil, err
	}
}

//转账
func makeTrans(id1, id2 int64, count float64) error {
	a1, err := getAccount(id1)
	if err != nil {
		return err
	}

	a2, err := getAccount(id2)
	if err != nil {
		return err
	}

	if a1.Balance <= count {
		return errors.New("账户余额不够转账!")
	}

	a1.Balance -= count
	a2.Balance += count

	//初始化一个事务
	sess := x.NewSession()
	defer sess.Close()

	//开始一个事务
	if err = sess.Begin(); err != nil {
		return err
	}

	//事务更新账户1
	if _, err = sess.Update(a1); err != nil {
		//失败回滚数据
		sess.Rollback()
		return err
	}

	//事务更新账户2
	if _, err = sess.Update(a2); err != nil {
		//失败回滚数据
		sess.Rollback()
		return err
	}

	//提交事务
	return sess.Commit()
}

//根据id显示账户
func getAccountAscId() (accountSlice []*Account, err error) {
	err = x.Asc("id").Find(&accountSlice)
	return accountSlice, err
}

//根据id显示账户
func getAccountsByBalance() (accountSlice []*Account, err error) {
	err = x.Asc("Balance").Find(&accountSlice)
	return accountSlice, err
}

func deleteAccountById(id int64) error {
	_, err := x.Delete(&Account{Id: id})
	return err
}

//删除id大于?的账户
func deleteAccountByIdGreaterThen(value int64) error {
	targets := make([]Account, 0)
	if err := x.Where("id>=?", value).Find(&targets); err != nil {
		return err
	}
	for _, value := range targets {
		deleteAccountById(value.Id)
	}
	return nil
}

//获取数据库中所有账户个数
func getAccountCount() (int64, error) {
	return x.Count(new(Account))
}

//获取相同存款金额的账户个数
func getSameBalanceAccountCount(balance float64) (int64, error) {
	return x.Count(&Account{Balance: balance})
}

你可能感兴趣的:(golang,游戏服务器,xorm,golang)