เหตุใดฉันจึงไม่ต้องการ ORM ในภาษาที่ใช้งานได้เช่น Scala


30

ฉันสงสัยว่าฉันสามารถเปลี่ยนจาก Java เป็น Scala ในโครงการ Spring + Hibernate เพื่อใช้ประโยชน์จากคุณสมบัติ Scala บางอย่างเช่นการจับคู่รูปแบบตัวเลือกและสิ่งที่ฉันคิดว่าเป็นไวยากรณ์ที่สะอาดกว่าโดยทั่วไป ฉันกำลังมองหา ORM เป็นค่าเริ่มต้นในระบบนิเวศของ Scala และฉันพบว่าคิดว่าเปิดใช้งาน (แต่ส่วนใหญ่ฉันพยายามค้นหาว่าไฮเบอร์เนตสามารถใช้กับ Scala ได้หรือไม่) ค้นหาสิ่งนี้ฉันได้อ่านสิ่งนี้ในเอกสารประกอบการเล่นเกี่ยวกับ JPA + Scala

แต่ประเด็นที่สำคัญที่สุดคือ: คุณต้องการ Relationnal to mapper Objects จริงๆหรือไม่เมื่อคุณมีพลังของภาษาที่ใช้งานได้? อาจจะไม่. JPA เป็นวิธีที่สะดวกในการสรุปการขาดพลังงานในการแปลงข้อมูลของ Java แต่ก็รู้สึกผิดเมื่อคุณเริ่มใช้จาก Scala

ฉันไม่มีความเข้าใจอย่างลึกซึ้งเกี่ยวกับวิธีการใช้การเขียนโปรแกรมเชิงฟังก์ชั่นเพื่อสร้างแอปพลิเคชันที่สมบูรณ์ (นั่นเป็นเหตุผลที่ฉันตั้งใจจะใช้ Scala เพื่อที่ฉันจะได้เข้าใจสิ่งที่เพิ่มขึ้นเนื่องจากมันรวม OO + Functional) ทำไมฉันไม่ต้องการ ORM ด้วยภาษาที่ใช้งานได้และอะไรคือแนวทางการทำงานเพื่อแก้ไขปัญหาการคงอยู่ของโมเดลโดเมน

แนวทาง DDD สำหรับตรรกะทางธุรกิจยังคงสมเหตุสมผลกับ Scala ใช่ไหม


3
นี่คือคำถามตามความคิดเห็น สกาล่าไม่ทำงานอย่างหมดจด แต่ก็เป็นภาษา OO ดังนั้นจะอธิบายได้ว่าทำไมคุณยังต้องการใช้เครื่องมือ ORM สำหรับการทำแผนที่ DB, ดูตัวอย่าง: Slick , SORM , Anorm
Jesper

ฉันไม่ได้มองหาความเห็นฉันกำลังขอบางสิ่งบางอย่างที่มีความเข้าใจอย่างลึกซึ้งเกี่ยวกับกระบวนทัศน์การทำงานสิ่งที่เป็นวิธีการบรรลุความเพียร ฉันรู้ว่า Scala เป็นลูกผสมและฉันต้องการใช้ส่วน OO สำหรับ DDD ดังนั้นคุณบอกว่าถ้าฉันใช้วิธี DDD แม้กับ Scala ORM เป็นวิธีที่จะไป?
gabrielgiussi

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


5
คุณไม่ต้องการ ORM ในภาษาหลักใด ๆ
GrandmasterB

คำตอบ:


30

ดีสิ่งหนึ่งที่เป็นสิ่งสำคัญที่จะทำเมื่อใดก็ตามที่เรามีการอภิปรายเช่นนี้คือการแยกแยะความแตกต่างอย่างชัดเจนระหว่างทำแผนที่เชิงวัตถุสัมพันธ์ ( "ออม") และชั้น abstraction ฐานข้อมูล ORM เป็นเลเยอร์ abstraction ของฐานข้อมูล แต่เลเยอร์ abstraction ของฐานข้อมูลนั้นไม่ใช่ ORM ทั้งหมด เครื่องมือที่ดีอย่างหนึ่งในการศึกษาเพื่อเข้าใจสิ่งนี้คือคลังSQLAlchemyยอดนิยมของ Python ที่เก็บเงินตัวเองว่าเป็น "ชุดเครื่องมือ SQL และเครื่องมือทำแผนที่วัตถุสัมพันธ์" (ตัวหนาของฉัน) ด้วยแนวคิดที่ว่าสิ่งเหล่านี้แตกต่างกัน ตามที่วางไว้ในหน้าคุณสมบัติหลัก :

ไม่ต้องใช้ ORM

SQLAlchemy ประกอบด้วยสององค์ประกอบที่แตกต่างกันที่รู้จักกันเป็นหลักและการออม ตัวแกนหลักเป็นชุดเครื่องมือที่เป็นนามธรรมของ SQL อย่างสมบูรณ์โดยให้เลเยอร์ที่ราบรื่นของนามธรรมผ่านการใช้งานและพฤติกรรม DBAPI ที่หลากหลายรวมถึงภาษา SQL Expression Language ซึ่งช่วยให้การแสดงออกของภาษา SQL ผ่านนิพจน์ทั่วไปของไพ ธ อน ระบบการแทนสคีมาที่สามารถเปล่งคำสั่ง DDL เช่นเดียวกับการหยั่งรู้สคีมาที่มีอยู่และระบบประเภทที่ช่วยให้การแมปประเภทหลามใด ๆ กับประเภทฐานข้อมูลปัดเศษระบบ Object Relational Mapper นั้นเป็นแพ็คเกจเสริมที่สร้างขึ้นบนแกน

หน้าแรกอธิบาย ORM ดังนี้:

SQLAlchemy มีชื่อเสียงมากที่สุดสำหรับ object-relational mapper (ORM) ซึ่งเป็นส่วนประกอบทางเลือกที่จัดเตรียม data mapper pattern ซึ่งคลาสสามารถถูกแม็พกับฐานข้อมูลในปลายเปิดได้หลายวิธี - อนุญาตให้โมเดลวัตถุและสคีมาฐานข้อมูลพัฒนาใน แยกชิ้นส่วนอย่างหมดจดตั้งแต่ต้น

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

ในทางตรงกันข้ามเลเยอร์นามธรรมของเลเยอร์นามธรรมที่ไม่ใช่ ORM นั้นมีแนวโน้มที่จะมีความมุ่งมั่นมากขึ้นกับโมเดลข้อมูลเชิงสัมพันธ์และ SQL ดังนั้นแทนที่จะมี "การแมป" ระหว่างตารางและคลาสและซ่อนสคีมาฐานข้อมูลจากโปรแกรมเมอร์พวกเขามักจะเปิดเผยฐานข้อมูลไปยังโปรแกรมเมอร์ แต่มี API และ abstractions ที่ดีกว่า ตัวอย่างเช่นตัวสร้างเคียวรี SQL อนุญาตให้คุณสร้างเคียวรี SQL ที่ซับซ้อนโดยทางโปรแกรมโดยไม่มีการจัดการสตริงเช่นนี้ ( ตัวอย่างจากไลบรารี jOOQ สำหรับ Java ):

// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result =
    create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
          .from(BOOK)
          .join(AUTHOR)
          .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
          .where(BOOK.PUBLISHED_IN.equal(1948))
          .fetch();

ตอนนี้กรอบการเล่นดูเหมือนจะไม่ 100% ในลีกกับสิ่งที่ฉันเพิ่งอธิบายแต่ข้อโต้แย้งของพวกเขาดูเหมือนจะอยู่ในพื้นที่ทั่วไปนี้: ทำงานกับโมเดลเชิงสัมพันธ์โดยตรงแทนที่จะแปลเป็นคลาสและย้อนกลับจากพวกเขา

ห้องสมุด jOOQเป็นมูลค่าการศึกษาเป็นความแตกต่างที่จะ ORMs นอกจากนี้ยังมีรายการบล็อกที่เกี่ยวข้องที่ควรค่าแก่การอ่าน:


19

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

ORMs ได้รับการออกแบบโดยทั่วไปในกระบวนทัศน์นั้น คุณดึงข้อมูลบางส่วนจากฐานข้อมูลรวมเข้าไว้ในวัตถุอาจแก้ไขมันเป็นพวงและเมื่อคุณทำเสร็จแล้วคุณยังมีวัตถุเดียวกันที่คุณสามารถเขียนกลับไปยังฐานข้อมูล

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


1
+1000 คนที่ยืนยันในการใช้ Scala ราวกับว่าเป็น Java ++ ทำให้ฉันกลัวสำหรับอนาคตของภาษา :(
Andres F.

9

ในสกาล่ามันยังคงมีประโยชน์ในการแมปตารางฐานข้อมูลกับวัตถุและมีหลายวิธีในการทำมัน

หนึ่งในกรอบที่นิยมในโลกของ Scala คือเนียน มันไม่ได้เป็น ORM เพราะมันทำน้อย (กล่าวคือมันไม่ได้ดึงความสัมพันธ์โดยไม่ได้รับคำสั่งให้เข้าร่วมอย่างชัดเจน)

ดังนั้นคุณยังคงแมปวัตถุไปยังแถวฐานข้อมูล แต่วัตถุของคุณไม่เปลี่ยนรูป (จึงไม่มีการล้างข้อมูลสถานะ) และคุณเรียกใช้คิวรีอย่างชัดเจนโดยใช้ monadic DSL ผลลัพธ์คือคุณได้รับส่วน "ดี" ของ ORM จำนวนมากโดยไม่มีปัญหาเกี่ยวกับความไม่แน่นอนและปัญหา N + 1 ที่คาดเดาไม่ได้

เราควรทราบว่าผู้คนประสบความสำเร็จอย่างมากในการใช้ห้องสมุดที่บางกว่าเดิมเช่นanormหรือ JDBC โดยตรงเช่นกันโดยใช้เทคนิคการใช้งานเพื่อรักษารหัสให้สวยงาม

หนึ่งในห้องสมุดที่ยอดเยี่ยมที่ใช้เทคนิคการทำงานที่ด้านบนของ JDBC ยังเป็นDoobie

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


0

คุณไม่ต้องการ ORM แม้แต่ในภาษาเชิงวัตถุ

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

สอง - วิธีที่ดีที่สุดในการบรรลุนั้นคืออะไร ฉันขอแนะนำให้ระบุวัตถุของคุณตามความรับผิดชอบของพวกเขาและไม่ควรคิดถึงข้อมูลที่มี หากคุณเคยได้ยินเกี่ยวกับวิธีการใช้บัตร CRC มันถูกใช้อย่างถูกต้อง

และสุดท้ายในกรณีที่คุณเคยจะกลับไปที่สนาม OO นี่คือวิธีการที่จะใช้มัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.