1. การแนะนำเกี่ยวกับการดำเนินการกับ Entity ใน ent

คู่มือนี้จะเป็นการนำทางที่ครอบคลุมในการชำระการดำเนินการกับ entity ในกรอบ ent อย่างครอบคลุม ซึ่งรวมถึงกระบวนการที่สมบูรณ์ในการสร้าง ค้นหา อัปเดต และลบ entities มันเหมาะสำหรับผู้เริ่มต้นที่จะศึกษาฟังก์ชันพื้นฐานของ ent ต่อไปนี้

3. การดำเนินการสร้าง Entity

3.1 การสร้าง Entity แบบเดียว

การสร้าง entity คือการดำเนินการพื้นฐานสำหรับคุณลักษณะการถาที่ยังคงอยู่ ด้านข้างหน้าและบันทึกไปยังฐานข้อมูลด้านล่างนี้คือขั้นตอนการสร้าง object ของ entity แบบเดียวโดยใช้กรอบ ent และบันทึกไปยังฐานข้อมูล

  1. ก่อนอื่นนิยามโครงสร้างและฟิลด์ของ entity นั้น กล่าวคือ นิยามโมเดลของ entity ในไฟล์ schema
  2. รันคำสั่ง ent generate เพื่อสร้างรหัสการดำเนินการ entity ที่สอดคล้องกัน
  3. ใช้เมธอด Create ที่สร้างไว้เพื่อสร้าง entity ใหม่ และตั้งค่าฟิลด์ของ entity ผ่านการเรียกต่อและสุดท้ายโทรเข้าที่เมธอด Save เพื่อบันทึก entity ไปยังฐานข้อมูล

ต่อไปนี้คือตัวอย่างที่แสดงให้เห็นถึงวิธีการสร้างและบันทึก entity ของผู้ใช้:

// (โค้ดของตัวอย่างหายไปแล้ว)

ในตัวอย่างนี้ ไคลเอ็นท์ฐานข้อมูล client ถูกสร้างก่อนหน้านี้ จากนั้นใช้ User.Create เพื่อตั้งค่าสมบัติของผู้ใช้ใหม่ และสุดท้ายเรียกใช้เมธอด Save เพื่อบันทึกผู้ใช้ไปยังฐานข้อมูล

3.2 การสร้าง Entity แบบ Batch

ในสถานการณ์บางครั้งอาจจะมีความต้องการที่จะสร้าง entities หลายรายการ เช่น ในขั้นตอนของการเริ่มต้นฐานข้อมูลหรือการดำเนินการนำเข้าข้อมูลเป็นปริมาณมาก กรอบ ent จะให้ความสามารถในการสร้าง entities ในชุดที่ได้ทำให้เกี่ยวกับประสิทธิผลมากขึ้นเมื่อเปรียบเทียบกับการสร้างและบันทึก entities อย่างอิสระ

ขั้นตอนสำหรับการสร้าง entities แบบ batch มีดังนี้

  1. ใช้เมธอด CreateBulk แทนที่เมธอด Create ซึ่งทำให้สามารถสร้าง entities หลายรายการในปฏิบัติการเดียว
  2. เรียกใช้ Create สำหรับแต่ละ entity ที่ต้องการสร้าง
  3. เมื่อสร้าง entities ทั้งหมดเรียบร้อยแล้ว ใช้เมธอด Save เพื่อบันทึก entities ไปยังฐานข้อมูลเป็นชุด

ต่อไปนี้เป็นตัวอย่างของการสร้าง entities แบบ batch:

// (โค้ดของตัวอย่างหายไปแล้ว)

ในตัวอย่างนี้ ไคลเอ็นท์ client ถูกสร้างก่อน และต่อมาชุด Pet ถูกก่อสร้างโดยใช้เมธอด CreateBulk ตั้งค่าชื่อและฟิลด์เจ้าของของทั้งหมด ทุก entities ถูกบันทึกไปยังฐานข้อมูลทั้งหมดในครั้งเดียวเมื่อเมธอด Save ถูกเรียก ทำให้มีความสามารถในการจัดการกับปริมาณข้อมูลที่มากขึ้นได้ดียวกัน

4.1 การ Query พื้นฐาน

การ query ในฐานข้อมูลเป็นวิธีพื้นฐานในการดึงข้อมูลออกมา ใน ent ใช้เมธอด Query เพื่อเริ่มต้น query ดังนี้คือขั้นตอนและตัวอย่างของการ query entity พื้นฐาน:

  1. ตรวจสอบให้แน่ใจว่ามี Client instance ที่สามารถใช้งานได้
  2. ใช้ Client.Query() หรือ entity helper methods เช่น Pet.Query() เพื่อสร้าง query
  3. เพิ่มเงื่อนไขการกรองตามที่จำเป็น เช่น Where
  4. ดำเนินการ query และดึงผลลัพธ์โดยการเรียก All method
package main

import (
    "context"
    "log"
    "entdemo/ent"
    "entdemo/ent/user"
)

func main() {
    client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("ไม่สามารถเปิดการเชื่อมต่อกับฐานข้อมูล: %v", err)
    }
    defer client.Close()
    ctx := context.Background()

    // Query ผู้ใช้ทั้งหมดที่ชื่ือ "a8m"
    users, err := client.User.
        Query().
        Where(user.NameEQ("a8m")).
        All(ctx)
    if err != nil {
        log.Fatalf("ไม่สามารถ query ผู้ใช้: %v", err)
    }

    for _, u := range users {
        log.Printf("พบผู้ใช้: %#v\n", u)
    }
}

ตัวอย่างนี้แสดงให้เห็นวิธีการค้นหาผู้ใช้ทั้งหมดที่ชื่อ "a8m"

4.2 การแบ่งหน้าและเรียงลำดับ

การแบ่งหน้าและเรียงลำดับเป็นคุณลักษณะขั้นสูงที่ใช้บ่งความเรียงลำดับและปริยายข้อมูล นี่คือวิธีที่ใช้สำหรับการ query แบบแบ่งหน้าและเรียงลำดับโดยใช้ ent:

  1. ใช้เมธอด Limit เพื่อกำหนดจำนวนสูงสุดของผลลัพธ์ที่จะ return
  2. ใช้เมธอด Offset เพื่อข้ามผลลัพธ์ก่อนหน้าบางส่วน
  3. ใช้เมธอด Order เพื่อกำหนดฟิลด์ที่ใช้เรียงลำดับและทิศทาง

นี่คือตัวอย่างของ query แบบแบ่งหน้าและเรียงลำดับ:

package main

import (
    "context"
    "log"
    "entdemo/ent"
    "entdemo/ent/pet"
)

func main() {
    client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("ไม่สามารถเปิดการเชื่อมต่อกับฐานข้อมูล: %v", err)
    }
    defer client.Close()
    ctx := context.Background()

    // Query Pets ที่เรียงลำดับลำดับจากอายุมากไปน้อยพร้อมกับการแบ่งหน้า
    pets, err := client.Pet.
        Query().
        Order(ent.Desc(pet.FieldAge)).
        Limit(10).
            Offset(0).
        All(ctx)
    if err != nil {
        log.Fatalf("ไม่สามารถ query Pets: %v", err)
    }

    for _, p := range pets {
        log.Printf("พบสัตว์เลี้ยง: %#v\n", p)
    }
}

ตัวอย่างนี้แสดงให้เห็นวิธีที่จะเรียกหน้าแรก มากถึง 10 บันทัั่งการแบ่งหน้าและเรียงลำดับโดยอายุจากมากไปน้อย โดยการเปลี่ยนค่าของ Limit และ Offset คุณสามารถทำให้ได้ผลลัพธ์ที่ชัดเจนถึงตัวข้อมูลทั้งหมดที่มีให้

5. การดำเนินการอัปเดต Entity

5.1 การปรับปรุง Entity เดียว

ในแอปพลิเคชันส่วนใหญ่ การปรับปรุง entity เป็นส่วนสำคัญของการดำเนินการประจำวัน ในบทนี้ เราจะแสดงวิธีในการใช้ Ent framework เพื่อที่จะทำการปรับปรุง entity เดียวในฐานข้อมูล

ตัวอย่างเช่น ถ้าเราต้องการที่จะปรับปรุงอายุของผู้ใช้ เราสามารถใช้ Update method ที่ถูก generate โดย Ent

// สมมติว่าเรามี entity ของผู้ใช้ 'a8m' และ context 'ctx'

a8m, err := a8m.Update().         // สร้าง user update builder
    SetAge(30).                   // กำหนดอายุของผู้ใช้เป็น 30 ปี
    Save(ctx)                     // ดำเนินการบันทึกและ return ผลลัพธ์
if err != nil {
    log.Fatalf("ไม่สามารถปรับปรุงผู้ใช้: %v", err)
}

คุณสามารถที่จะปรับปรุงหลายฟิลด์พร้อมกัน:

a8m, err := a8m.Update().
    SetAge(30).                    // ปรับปรุงอายุ
    SetName("Ariel").              // ปรับปรุงชื่อ
    AddRank(10).                   // เพิ่มลำดับอันดับขึ้น 10
    Save(ctx)
if err != nil {
    log.Fatalf("ไม่สามารถปรับปรุงผู้ใช้: %v", err)
}

การดำเนินการปรับปรุงสามารถเชื่อมต่อหลายครั้ง เป็นเรื่องเหมาะสมและอ่านง่าย การเรียกใช้ Save method จะดำเนินการปรับปรุงและคืน entity ที่ปรับปรุงแล้ว หรือข้อกผิดพลาดที่เกิดขึ้นได้

5.2 การอัปเดตที่มีเงื่อนไข

Ent ช่วยให้คุณสามารถทำการอัปเดตโดยขึ้นอยู่กับเงื่อนไขได้ ต่อไปนี้คือตัวอย่างที่เฉพาะบุคคลที่ตรงตามเงื่อนไขบางอย่างจะถูกอัปเดตเท่านั้น

// สมมติว่าเรามี `id` ของผู้ใช้และเราต้องการทำเครื่องหมายว่าผู้ใช้คน đóทำแล้วสำหรับเวอร์ชันปัจจุบัน

err := client.Todo.
    UpdateOneID(id).          // สร้างตัวสร้างเพื่อทำการอัปเดตโดยใช้ ID ของผู้ใช้
    SetStatus(todo.StatusDone).
    AddVersion(1).
    Where(
        todo.Version(currentVersion),  // การดำเนินการที่จะถูกปฏิบัติเมื่อเวอร์ชันปัจจุบันตรง
    ).
    Exec(ctx)
switch {
case ent.IsNotFound(err):
    fmt.Println("ไม่พบ Todo")
case err != nil:
    fmt.Println("ข้อผิดพลาดในการอัปเดต:", err)
}

ในการใช้การอัปเดตที่มีเงื่อนไข จะต้องมีการใช้ .Where() method เข้ามา นี้ช่วยให้คุณสามารถกำหนดว่าการอัปเดตควรทำตามค่าปัจจุบันในฐานข้อมูล ซึ่งเป็นสิ่งสำคัญสำหรับการรักษาความสอดคล้องและความคงเองของข้อมูล

6. ปฏิบัติการลบ Entity

6.1 การลบ Entity แบบเดียว

การลบ Entity เป็นการทำงานสำคัญอีกอย่างหนึ่งในการดำเนินการของฐานข้อมูล Ent framework ให้ API ที่เรียบง่ายสำหรับการดำเนินการการลบ

ตัวอย่างต่อไปนี้แสดงถึงวิธีการลบ Entity ของผู้ใช้ที่กำหนด:

err := client.User.
    DeleteOne(a8m).  // สร้างตัวสร้างการลบผู้ใช้
    Exec(ctx)        // ดำเนินการลบ
if err != nil {
    log.Fatalf("ลบผู้ใช้ล้มเหลว: %v", err)
}

6.2 การลบที่มีเงื่อนไข

คล้ายกับการดำเนินการอัปเดต เราสามารถดำเนินการลบ Entity โดยดูจากเงื่อนไขเฉพาะบางอย่าง ในสถานการณ์บางอย่างเราอาจต้องการลบ Entity ที่ตรงตามเงื่อนไขเท่านั้น การใช้ .Where() method สามารถกำหนดเงื่อนไขเหล่านี้:

// สมมติว่าเราต้องการลบไฟล์ทั้งหมดที่มีเวลาอัพเดทก่อนวันที่ที่กำหนด

affected, err := client.File.
    Delete().
    Where(file.UpdatedAtLT(date)).  // ดำเนินการลบเฉพาะถ้าเวลาอัพเดทของไฟล์เป็นก่อนวันที่ที่กำหนด
    Exec(ctx)
if err != nil {
    log.Fatalf("ลบไฟล์ล้มเหลว: %v", err)
}

// การดำเนินการนี้คืนค่าจำนวนเรคคอร์ดที่ได้รับผลกระทบจากการดำเนินการลบ
fmt.Printf("%d ไฟล์ถูกลบ\n", affected)

การใช้การลบที่มีเงื่อนไข ช่วยให้คุณมีควบคุมที่แม่นยำเกี่ยวกับการดำเนินการข้อมูลของเรา ซึ่งทำให้มั่นใจได้ว่าเพียงเพียง Entity ที่ตรงตามเงื่อนไขจริงๆ ถูกลบ ส่งผลให้ความปลอดภัยและความเชื่อถือของการดำเนินการในฐานข้อมูลของเราอย่างมาก