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
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})
}