การแทรกและอัปเดต
เขียนข้อมูลเชิงฟังก์ชัน
การแทรกและอัปเดต เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
Update0 สำหรับการเขียนข้อมูล
การเขียนข้อมูลใช้ตัวแทรกสตริง sql แบบเดียวกัน แต่เรียก .update เพื่อรับ Update0 แทน .query
การเรียก .run กับ Update0 จะคืนค่า ConnectionIO[Int] ซึ่งเป็นจำนวนแถวที่ได้รับผลกระทบ
import doobie.implicits._
def insert(name: String, age: Int): ConnectionIO[Int] =
sql"insert into users (name, age) values ($name, $age)".update.runจำนวนแถวที่ได้รับผลกระทบ
Int จาก .run คือจำนวนแถวที่ JDBC อัปเดต สำหรับ UPDATE หรือ DELETE ค่านี้จะบอกจำนวนแถวที่ตรงเงื่อนไข
คุณสามารถใช้ค่านี้แยกเส้นทางการทำงานเพื่อตรวจพบกรณีต่าง ๆ เช่น การอัปเดตที่ไม่ตรงกับแถวใดเลย
def deactivate(id: Long): ConnectionIO[Int] =
sql"update users set active = false where id = $id".update.runการคืนค่าคีย์ที่สร้างขึ้น
หากต้องการรับคีย์หลักที่สร้างขึ้นโดยอัตโนมัติ ให้ใช้ .withUniqueGeneratedKeys พร้อมระบุชื่อคอลัมน์ที่ฐานข้อมูลจะส่งคืน
การทำงานนี้จะแทรกข้อมูลและอ่านค่าที่สร้างขึ้นกลับมาในรอบการเดินทางไปกลับครั้งเดียว
def insertReturningId(name: String, age: Int): ConnectionIO[Long] =
sql"insert into users (name, age) values ($name, $age)"
.update
.withUniqueGeneratedKeys[Long]("id")การคืนค่าทั้งแถว
คุณสามารถคืนค่าหลายคอลัมน์ที่สร้างขึ้นหรือใช้ค่าเริ่มต้นพร้อมกันได้ โดยอ่านค่าเหล่านั้นเข้าสู่ทูเพิลหรือคลาสกรณี
เหมาะอย่างยิ่งสำหรับการรับค่าเริ่มต้นที่ฝั่งเซิร์ฟเวอร์กำหนด เช่น เวลา หลังจากการแทรกข้อมูลทันที
case class User(id: Long, name: String, createdAt: java.time.Instant)
def create(name: String): ConnectionIO[User] =
sql"insert into users (name) values ($name)"
.update
.withUniqueGeneratedKeys[User]("id", "name", "created_at")คลาส Update สำหรับชุดข้อมูล
Update[A] คือคำสั่งที่เตรียมไว้และมีพารามิเตอร์ ซึ่งคุณสามารถเรียกใช้ซ้ำได้หลายครั้ง คุณกำหนด SQL ครั้งเดียวด้วยตัวยึดตำแหน่ง ? แล้วส่งค่าชนิด A
สิ่งนี้สร้างจากสตริง SQL พร้อมอินสแตนซ์ Write[A]
val ins: Update[(String, Int)] =
Update[(String, Int)]("insert into users (name, age) values (?, ?)")การแทรกข้อมูลเป็นชุดอย่างมีประสิทธิภาพ
updateMany จะส่งคอลเลกชันทั้งหมดในชุดคำสั่ง JDBC เดียว ซึ่งเร็วกว่าการวนลูปแทรกทีละรายการมาก
ฟังก์ชันนี้คืนค่าจำนวนแถวที่ได้รับผลกระทบทั้งหมด ใช้เมื่อคุณโหลดข้อมูลหลายแถวพร้อมกัน
val rows = List(("Ada", 36), ("Linus", 54))
val batch: ConnectionIO[Int] = ins.updateMany(rows)การแทรกข้อมูลเป็นชุดพร้อมคีย์
Update ยังสามารถสตรีมคีย์ที่สร้างขึ้นสำหรับชุดข้อมูลผ่าน updateManyWithGeneratedKeys โดยคืนค่าหนึ่งแถวต่อระเบียนที่แทรก
วิธีนี้รวมการโหลดข้อมูลจำนวนมากเข้ากับการอ่านตัวระบุที่ได้รับมอบหมายกลับมา
import fs2.Stream
val keyed: Stream[ConnectionIO, Long] =
ins.updateManyWithGeneratedKeys[Long]("id")(rows)การทำ Upsert ด้วย ON CONFLICT
การทำ upsert เฉพาะของฐานข้อมูลสามารถใช้ผ่าน Doobie ได้ตามปกติ บน PostgreSQL ให้เขียน insert ... on conflict ... do update เป็น SQL ตามปกติ
Doobie เพียงผูกพารามิเตอร์ให้คุณ ส่วนความหมายของ upsert เป็นหน้าที่ของฐานข้อมูล
def upsert(email: String, name: String): ConnectionIO[Int] =
sql"""insert into accounts (email, name) values ($email, $name)
on conflict (email) do update set name = excluded.name"""
.update.runอินสแตนซ์ Write และค่าเริ่มต้น
พารามิเตอร์จะถูกเข้ารหัสด้วย typeclass Write[A] ซึ่งสร้างได้สำหรับชนิดพื้นฐาน ทูเพิล และคลาสกรณี แต่ละฟิลด์ต้องมีอินสแตนซ์ Put
หากคุณละเว้นคอลัมน์จากการแทรกข้อมูล ฐานข้อมูลจะใช้ค่า DEFAULT ของคอลัมน์ ซึ่งเป็นวิธีที่เวลาแบบสร้างขึ้นจะปรากฏขึ้น
case class NewUser(name: String, age: Int)
val mk = Update[NewUser](
"insert into users (name, age) values (?, ?)"
)การแมปคอลัมน์แบบกำหนดเองด้วย Meta
หากต้องการจัดเก็บชนิดข้อมูลแบบกำหนดเอง ให้กำหนด Meta[A] โดยแมปชนิดข้อมูลนั้นกับชนิดคอลัมน์ที่มีอยู่ผ่าน imap (หรือ timap)
Meta มีทั้งความสามารถในการอ่านและเขียน จึงใช้ชนิดข้อมูลนี้ได้ทั้งในคิวรีและการอัปเดต
import doobie.util.meta.Meta
case class UserId(value: Long)
implicit val uidMeta: Meta[UserId] =
Meta[Long].imap(UserId.apply)(_.value)การลบก็เป็นการอัปเดตเช่นกัน
คำสั่ง DELETE ก็ใช้ .update.run และคืนค่าจำนวนแถวที่ลบออก
การจัดการการแทรก การอัปเดต และการลบในรูปแบบเดียวกันด้วย Update0 ทำให้ส่วนติดต่อการใช้งานมีขนาดเล็กและนำมาประกอบกันได้
def purgeInactive: ConnectionIO[Int] =
sql"delete from users where active = false".update.runตรวจสอบอย่างรวดเร็ว
เลือกแนวทางที่มีประสิทธิภาพสูงสุด
สรุปทบทวน
การเขียนข้อมูลใช้ .update เพื่อสร้าง Update0 โดย .run จะคืนค่าแถวที่ได้รับผลกระทบ และ .withUniqueGeneratedKeys จะอ่านค่าที่สร้างขึ้นกลับมา
สำหรับงานจำนวนมาก Update[A].updateMany จะจัดชุดข้อมูลได้อย่างมีประสิทธิภาพ ชนิดข้อมูลแบบกำหนดเองใช้อินสแตนซ์ Meta และ upsert ก็เป็นเพียง SQL ปกติของฐานข้อมูลที่ Doobie ผูกพารามิเตอร์ให้
คำถามที่พบบ่อย
บทเรียน “การแทรกและอัปเดต” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแทรกและอัปเดต” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแทรกและอัปเดต”
เขียนข้อมูลเชิงฟังก์ชัน คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การแทรกและอัปเดต” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เชื่อมต่อด้วยทรานแซกเตอร์
- เรียกใช้คำสั่งค้นหา
- การแทรกและอัปเดต
- ประกอบธุรกรรม