🌱

【Go】Xormの使い方 その② CRUD以外の色々

2021/09/06に公開

はじめに

前回に続いて、Xorm使い方その②です。
その①の続きですので、Xormの導入などは終わっている程で話を進めます。
https://zenn.dev/a_ichi1/articles/5d9fbf3fbfea38
今回はいろんなメソッドを解説しようと思います。
今回解説するのは、以下の通りです。

目次

  • Table
  • Select
  • Sum, SumInt
  • Where, And, Or
  • OrderBy, Asc, Desc
  • SQL, Query

環境

go 1.15
github.com/go-sql-driver/mysql v1.6.0
xorm.io/xorm v1.2.3

DBのデータ

今回はこちらのデータを使用します。

enginの用意

package main

import (
	"fmt"
	"log"
	"time"

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

type User struct {
	Id       int64 `xorm:"id"`
	Name     string
	Age      int
	Password string    `xorm:"password"`
	Created  time.Time `xorm:"created"`
	Updated  time.Time `xorm:"updated"`
}

func main() {
	engine, err := xorm.NewEngine("mysql", "root:root@tcp([127.0.0.1]:3306)/sample_db?charset=utf8mb4&parseTime=true")
	if err != nil {
		log.Fatal(err)
	}

	err = engine.Sync2(new(User))
	if err != nil {
		log.Fatal(err)
	}

	// メソッドを実行します
	// Table(*engine)
	// Select(*engine)
	// SetID(*engine)
	// Sum(*engine)
	// SumsInt(*engine)
	// WhereAnd(*engine)
	// WhereOr(*engine)
	// OrderBy(*engine)
	// Asc(*engine)
	// Desc(*engine)
	// SQL(*engine)
	// Query(*engine)
}

これでenginの用意が整いました。
以下は、main.goにメソッドを作成したら、こうなるというのを解説していきます。

Table

これは操作するテーブルを指定するだけです。
簡単です。

func Table(engine xorm.Engine) {
	user := User{}
	// ここでテーブルをユーザーテーブルを指定します。
	session := engine.Table("user")
	_, err := session.Where("id = ?", 1).Get(&user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("user:", user)
}

出力結果

user: {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}

テーブルを指定して、sessionに入れます。
それをWhereで条件を指定し、Getでマッピングします。
Tableでテーブルを指定しなくても、構造体から勝手に判断してくれます。
前回やった下記のコードでも同じように取得出来ます。

func Get(engine xorm.Engine) {
	user := User{}
	_, err := engine.Where("id = ?", 1).Get(&user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("user:", user)
}

結果は同じですが、Tableを使った方が明示的で分かりやすいです。

Select

SQLのSELECTと同じです。カラム名を指定します。

func Select(engine xorm.Engine) {
	user := User{}
	// ここでテーブルをユーザーテーブルを指定します。
	session := engine.Table("user")
	result, err := session.Select("name").Get(&user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("user:", user)
	fmt.Println("result:", result)
}

出力結果

user: {0 花子 0  0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC}
result: true

カラムを指定しても、Getの返り値resultはtrueかfalseです。
構造体Userにはnameのカラムだけ入るので、結果は名前だけ更新されています。

Sum, SumInt

指定したカラムの値を合計します。
カラムの数を数えるのではないのでご注意ください。

func Sum(engine xorm.Engine) {
	user := User{}
	sumFloat64, _ := engine.Sum(user, "id")
	print(" sumFloat64: ", sumFloat64)
}

func SumsInt(engine xorm.Engine) {
	user := User{}
	sumInt, _ := engine.SumInt(user, "id")
	print(" sumInt: ", sumInt)
}

出力結果

sumFloat64: +6.000000e+000
sumInt: 6 

普通のSumはFloat64が返ってきます。
intで返して欲しい場合は、SumIntを使います。

Where, And, Or

この3つはSQLと同じように使います。

func WhereAnd(engine xorm.Engine) {
	users := []User{}
	session := engine.Table("user")
	err := session.Where("id > ?", 1).And("age = ?", 30).Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("whereAndUsers:", users)
}

func WhereOr(engine xorm.Engine) {
	users := []User{}
	session := engine.Table("user")
	err := session.Where("id > ?", 1).Or("age = ?", 30).Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("whereOrUsers:", users)
}

WhereAndはidが1より大きく、かつ、ageが30のユーザーを取得します。
WhereOrはidが1より大きい、もしくは、ageが30のユーザーを取得します。

出力結果

whereAndUsers: [{2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST}]
whereOrUsers: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]

OrderBy, Asc, Desc

これも基本的には、ほとんどSQLと同じです。

func OrderBy(engine xorm.Engine) {
	users := []User{}
	session := engine.Table("user")
	err := session.OrderBy("id DESC").Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("users:", users)
}

出力結果

users: [{3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}]
func Asc(engine xorm.Engine) {
	users := []User{}
	session := engine.Table("user")
	err := session.Asc("id").Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("AscUsers:", users)
}

出力結果

AscUsers: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]
func Desc(engine xorm.Engine) {
	users := []User{}
	session := engine.Table("user")
	err := session.Desc("id").Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("DescUsers:", users)
}

出力結果

DescUsers: [{3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}]

.OrderByでidだけを指定すると、ASCになります。
.OrderByのidの後ろのDESCはDescでもdesc大丈夫です。
ただ単に昇順や降順にするだけなら、.Ascか.Descを使った方が分かりやすいですね。

SQL, Query

Xormは生のSQLのQueryも実行出来ます。

func SQL(engine xorm.Engine) {
	users := []User{}
	err := engine.SQL("select * from user").Find(&users)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("users:", users)
}

出力結果

users: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]
func Query(engine xorm.Engine) {
	results, err := engine.Query("select * from user")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("results:", results)
}

出力結果

results: [map[age:[51 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 55 58 50 52 90] id:[49] name:[232 138 177 229 173 144] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 55 58 50 52 90]] map[age:[51 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 56 58 52 50 90] id:[50] name:[227 129 159 227 129 145 227 129 151] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 56 58 52 50 90]] map[age:[50 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 57 58 51 53 90] id:[51] name:[229 164 170 233 131 142] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 57 58 51 53 90]]]

SQLもQueryもどちらも生のSQL文を使えますが、Queryはbyteで返って来ます。
SQLの方が使いやすそうです。

さいごに

他にも色々ありますが、今回はこの辺で。
良かったら、その③も見てください。
https://zenn.dev/a_ichi1/articles/2d5837d1ef610b

参考

https://pkg.go.dev/github.com/go-xorm/xorm

https://www.kancloud.cn/xormplus/xorm/167087

Discussion