はじめに
前回に続いて、xorm使い方その②です。
前回の続きですので、xormの導入などは終わっている程で話を進めます。
今回はいろんなメソッドを解説しようと思います。
今回解説するのは、以下の通りです。
目次
- 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の方が使いやすそうです。
さいごに
他にも色々ありますが、今回はこの辺で。
参考