การเขียนโปรแกรม Java - คำสั่ง SQL ควรเก็บไว้ที่ไหน? [ปิด]


107

แอปพลิเคชันที่สอดคล้องกับ JDBC ควรเก็บคำสั่ง SQL ไว้ที่ใดและเพราะเหตุใด

จนถึงตอนนี้ฉันสามารถระบุตัวเลือกเหล่านี้ได้:

  • ฮาร์ดโค้ดในวัตถุทางธุรกิจ
  • ฝังอยู่ในส่วนคำสั่งSQLJ
  • ห่อหุ้มในคลาสที่แยกจากกันเช่น Data Access Objects
  • ข้อมูลเมตาขับเคลื่อน (แยกสคีมาออบเจ็กต์ออกจากสคีมาข้อมูล - อธิบายการแมประหว่างพวกเขาในข้อมูลเมตา)
  • ไฟล์ภายนอก (เช่นคุณสมบัติหรือไฟล์ทรัพยากร)
  • กระบวนงานที่จัดเก็บ

“ ข้อดี” และ“ ข้อเสีย” ของแต่ละข้อมีอะไรบ้าง?

ควรพิจารณาโค้ด SQL เป็น“ code” หรือ“ metadata”?

ควรใช้กระบวนงานที่จัดเก็บไว้เพื่อเพิ่มประสิทธิภาพการทำงานเท่านั้นหรือเป็นนามธรรมที่ถูกต้องตามกฎหมายของโครงสร้างฐานข้อมูล?

ประสิทธิภาพเป็นปัจจัยสำคัญในการตัดสินใจหรือไม่? แล้วผู้ขายล็อคอินล่ะ?

อะไรจะดีไปกว่ากัน - ข้อต่อหลวมหรือข้อต่อแน่นและทำไม?

แก้ไข: ขอบคุณทุกคนสำหรับคำตอบ - นี่คือบทสรุป:

เมทาดาทาขับเคลื่อนเช่น Object Relational Mappings (ORM)

ข้อดี:

  • นามธรรมมาก - เซิร์ฟเวอร์ DB สามารถเปลี่ยนได้โดยไม่จำเป็นต้องเปลี่ยนโมเดล
  • การแพร่กระจายกว้าง - เป็นมาตรฐาน
  • ลดจำนวน SQL ที่จำเป็น
  • สามารถจัดเก็บ SQL ในไฟล์ทรัพยากร
  • ประสิทธิภาพ (โดยปกติ) เป็นที่ยอมรับ
  • แนวทางที่ขับเคลื่อนด้วยข้อมูลเมตา
  • (ฐานข้อมูล) ความเป็นอิสระของผู้ขาย

จุดด้อย:

  • ซ่อน SQL และความตั้งใจจริงของนักพัฒนา
  • DBA ตรวจสอบ / เปลี่ยนแปลง SQL ได้ยาก
  • SQL อาจจำเป็นสำหรับกรณีแปลก ๆ
  • สามารถบังคับใช้ภาษาแบบสอบถามที่เป็นกรรมสิทธิ์เช่น HQL
  • ไม่ยืมตัวไปสู่การเพิ่มประสิทธิภาพ (นามธรรม)
  • สามารถขาดความสมบูรณ์อ้างอิง
  • ทดแทนการขาดความรู้ SQL หรือขาดความใส่ใจในการเขียนโค้ดใน DB
  • ไม่ตรงกับประสิทธิภาพของฐานข้อมูลดั้งเดิม (แม้ว่าจะเข้ามาใกล้ก็ตาม)
  • รหัสรุ่นแน่นมากควบคู่ไปกับโมเดลฐานข้อมูล

ฮาร์ดโค้ด / เข้ารหัสในเลเยอร์ DAO

ข้อดี:

  • SQL ถูกเก็บไว้ในวัตถุที่เข้าถึงข้อมูล (การห่อหุ้ม)
  • SQL เขียนง่าย (ความเร็วในการพัฒนา)
  • SQL นั้นง่ายต่อการติดตามเมื่อจำเป็นต้องมีการเปลี่ยนแปลง
  • วิธีแก้ปัญหาง่ายๆ (ไม่มีสถาปัตยกรรมที่ยุ่งเหยิง)

จุดด้อย:

  • DBA ไม่สามารถตรวจสอบ / เปลี่ยนแปลง SQL ได้
  • SQL มีแนวโน้มที่จะกลายเป็นเฉพาะฐานข้อมูล
  • SQL อาจเป็นเรื่องยากที่จะดูแลรักษา

กระบวนงานที่จัดเก็บ

ข้อดี:

  • SQL เก็บไว้ในฐานข้อมูล (ใกล้เคียงกับข้อมูล)
  • SQL ถูกแยกวิเคราะห์รวบรวมและปรับให้เหมาะสมโดย DBMS
  • SQL เป็นเรื่องง่ายสำหรับ DBA ในการตรวจสอบ / เปลี่ยนแปลง
  • ลดปริมาณการใช้งานเครือข่าย
  • เพิ่มความปลอดภัย

จุดด้อย:

  • SQL เชื่อมโยงกับฐานข้อมูล (ล็อกผู้ขาย)
  • รหัส SQL รักษายากกว่า

ไฟล์ภายนอก (เช่นคุณสมบัติหรือไฟล์ทรัพยากร)

ข้อดี

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

จุดด้อย:

  • โค้ด SQL อาจไม่สามารถบำรุงรักษาได้
  • ตรวจสอบโค้ด SQL เพื่อหาข้อผิดพลาด (ไวยากรณ์) ได้ยากขึ้น

ฝังอยู่ในส่วนคำสั่ง SQLJ

ข้อดี:

  • การตรวจสอบไวยากรณ์ที่ดีขึ้น

จุดด้อย:

  • ผูกติดกับ Java มากเกินไป
  • ประสิทธิภาพต่ำกว่า JDBC
  • ขาดการสืบค้นแบบไดนามิก
  • ไม่ค่อยเป็นที่นิยม

คำถามที่ดี แต่อาจจะมากเกินไปที่จะตอบพร้อมกัน จะใช้เวลาไม่กี่หน้าในการตอบ imho ทั้งหมดนี้: p
NickDK

+1 คำถามดีๆ! คุณควรเพิ่ม "ORM" ต่อ @ocdecio เพิ่ม "โรยทุกที่ในโค้ด Java ของคุณ" (ซึ่งฉันเคยเห็นและต้องแย่ที่สุด)
Jim Ferrans

2
ฉันไม่เห็นด้วยอย่างยิ่งกับ "รหัส SQL ยากต่อการบำรุงรักษา" ภายใต้ Stored Procedures ใน XP SQL ของฉันง่ายต่อการบำรุงรักษาเมื่อเข้าสู่ฐานข้อมูล ส่วนหนึ่งเป็นเหตุผลที่ใช้ในไฟล์ภายนอก (ที่เก็บส่วนกลางของคำสั่ง SQL ทั้งหมด - ดูแลรักษาง่ายกว่า) บวกกับพารามิเตอร์นั้นง่ายต่อการจัดการ
Michael Lloyd Lee mlk

1
ในความคิดของฉันคุณพลาดทางเลือกหนึ่ง: การใช้มุมมอง คุณสามารถแสดง SQL ที่ซับซ้อนในมุมมองจากนั้นแสดงการเลือกอย่างง่ายในมุมมองเหล่านั้น (โดยใช้นามธรรมประเภทใดก็ได้: DAO, SQLJ, ORM's ฯลฯ ) คุณจะมีข้อดีเหมือนกันกับขั้นตอนการจัดเก็บ แต่ฉันไม่คิดว่าคุณจะมีข้อเสียใด ๆ ...
Lukas Eder

คำตอบ:


31

โดยปกติแล้วยิ่งแอปพลิเคชันเติบโตขึ้นในแง่ของขนาดและ / หรือการนำกลับมาใช้ใหม่มากเท่าไหร่ความจำเป็นในการทำให้คำสั่ง SQL เป็นภายนอก / นามธรรม

Hardcoded (เป็นค่าคงที่สุดท้ายแบบคงที่) เป็นขั้นตอนแรก เก็บไว้ในไฟล์ (ไฟล์ properties / xml) เป็นขั้นตอนต่อไป ข้อมูลเมตาที่ขับเคลื่อน (ซึ่งทำโดย ORM เช่น Hibernate / JPA) เป็นขั้นตอนสุดท้าย

Hardcoded มีข้อเสียตรงที่โค้ดของคุณมีแนวโน้มที่จะกลายเป็น DB เฉพาะและคุณต้องเขียนใหม่ / สร้างใหม่ / แจกจ่ายซ้ำทุกครั้งที่เปลี่ยนแปลง ข้อดีคือคุณมีไว้ในที่เดียว

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

ข้อมูลเมตาที่ขับเคลื่อนด้วยมีข้อเสียตรงที่รหัสโมเดลของคุณแน่นมากควบคู่ไปกับโมเดลฐานข้อมูล สำหรับทุกการเปลี่ยนแปลงในโมเดลฐานข้อมูลคุณจะต้องเขียน / สร้างใหม่ / แจกจ่ายรหัสใหม่ ข้อดีคือมันเป็นนามธรรมมากและคุณสามารถเปลี่ยนจากเซิร์ฟเวอร์ DB ได้อย่างง่ายดายโดยไม่จำเป็นต้องเปลี่ยนโมเดลของคุณ (แต่ถามตัวเองตอนนี้: บริษัท จะเปลี่ยนจากเซิร์ฟเวอร์ DB บ่อยแค่ไหนน่าจะอย่างน้อยเพียงหนึ่งครั้งต่อ 3 ปีเท่านั้น t มัน?).

ฉันจะไม่เรียกขั้นตอนการจัดเก็บว่าเป็นโซลูชันที่ "ดี" สำหรับสิ่งนี้ พวกเขามีจุดประสงค์ที่แตกต่างกันอย่างสิ้นเชิง แม้ว่าโค้ดของคุณจะขึ้นอยู่กับ DB / configuration ที่ใช้


22

ฉันไม่รู้ว่าสิ่งนี้ดีที่สุดหรือไม่ แต่จากประสบการณ์ของฉันพวกเขาลงท้ายด้วยฮาร์ดโค้ด (เช่น String literals) ในเลเยอร์ DAO


5
มันอาจจะไม่ดีที่สุด แต่ก็เป็นสิ่งที่ฉันทำด้วย เขียนง่ายติดตามง่ายและไม่มีสถาปัตยกรรมที่ยุ่งเหยิงให้ต้องกังวล
James Cronen

21
และเวลาทั้งหมดที่ใช้ในการติดตาม SQL แบบฮาร์ดโค้ดคือความปลอดภัยของงาน หากคุณเป็นคนเดียวที่รู้ว่า SQL อยู่ที่ไหนคุณจะไม่ถูกไล่ออก
ล็อต

11
ทำให้ฉันประหลาดใจอยู่เสมอว่าหลาย ๆ คนที่ระมัดระวังในการสร้างโค้ด OO Java ที่ออกแบบมาอย่างสวยงามและสะอาดเป็นคนเดียวกับที่ทนต่อการเขียน SQL ที่ยุ่งเหยิงและไม่มีประสิทธิภาพและเพียงแค่ยึดเป็นสตริงในที่สุ่ม หาก SQL ของคุณเป็นเพียงสตริงในเลเยอร์ DAO ของคุณฉันสามารถรับประกันได้ว่าคุณจะไม่มี DBA ในทีมของคุณ อย่างน้อยก็ไม่ใช่DBA ที่ดี
Daniel Pryden

3
-1. เป็นเรื่องปกติที่จะมี DAO แต่อย่างน้อยที่สุดก็ให้ย้ายแบบสอบถามไปยังไฟล์คุณสมบัติที่ใดที่หนึ่งเพื่อให้ DBA สามารถตรวจสอบและปรับแต่งได้ตามความเหมาะสม!
cethegeek

3
ประสบการณ์ของฉันคือถ้าคุณทำ JDBC แบบตรงการวางสตริงการสืบค้นในเลเยอร์ Data Access Object น่าจะเป็นแนวทางที่ดีที่สุดหากคุณไม่สามารถใช้โซลูชัน ORM ได้ เมื่อมีข้อแม้คือให้แน่ใจว่าทุกคนในหน้าเดียวกันด้วยมาตรฐานการเข้ารหัสสำหรับคลาส DAO ถ้าคุณไปทางนั้น ฉันได้ลงทั้งชุดทรัพยากรและเส้นทางกระบวนงานที่จัดเก็บไว้และทั้งคู่เป็นฝันร้ายในการบำรุงรักษาอย่างแท้จริงเนื่องจากมันกระจายตรรกะการเข้าถึงข้อมูลออกไปในหลายชั้นดังนั้นการเพิ่มคอลัมน์ลงในแบบสอบถามทำให้คุณต้องเปลี่ยนสิ่งต่างๆในที่ต่างๆ
Jason Gritman

12

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

ฉันใช้เพื่อใช้ SQL ฮาร์ดโค้ดใน DAL ฉันคิดว่ามันใช้ได้ดีจนกระทั่ง DBA ต้องการเล่นกับ SQL จากนั้นคุณจะต้องขุดออกจัดรูปแบบและเริ่มการทำงานไปยัง DBA ใครจะหัวเราะเยาะและแทนที่มันทั้งหมด แต่ไม่มีเครื่องหมายคำถามที่ดีหรือเครื่องหมายคำถามในลำดับที่ไม่ถูกต้องและปล่อยให้คุณติดกลับเข้าไปในโค้ด Java

เราได้ใช้ ORM ด้วยและในขณะที่นี่เป็นสิ่งที่ดีสำหรับนักพัฒนา DBA ของเราที่เกลียดมันเนื่องจากไม่มี SQL ให้พวกเขาหัวเราะ เรายังใช้ ORM แปลก ๆ (แบบกำหนดเองจากซัพพลายเออร์บุคคลที่สาม) ซึ่งมีนิสัยชอบฆ่าฐานข้อมูล ฉันเคยใช้ JPA มาแล้วและยอดเยี่ยมมาก แต่การได้รับอะไรที่ซับซ้อนโดยใช้มันผ่าน DBA เป็นการต่อสู้บนเนินเขา

ตอนนี้เราใช้ Stored Procedures (ด้วยรหัสคำสั่งการโทร) ตอนนี้สิ่งแรกที่ทุกคนจะบ่นคือคุณผูกติดอยู่กับฐานข้อมูล คุณคือ. คุณเปลี่ยนฐานข้อมูลบ่อยแค่ไหน? ฉันรู้ว่าเราไม่สามารถแม้แต่จะลองใช้มันได้จำนวนของรหัสอื่น ๆ ขึ้นอยู่กับมันรวมถึงการฝึก DBA ของเราอีกครั้งรวมถึงการย้ายข้อมูล มันจะเป็นการดำเนินการที่มีราคาแพงมาก อย่างไรก็ตามหากในโลกของคุณเปลี่ยนฐานข้อมูลโดยใช้หมวกเพียงหยดเดียวก็จำเป็นต้องใช้ SPs

นับจากนี้ไปฉันต้องการใช้โพรซีเดอร์ที่เก็บไว้กับเครื่องมือสร้างโค้ดเพื่อสร้างคลาส Java จากแพ็คเกจ Oracle

แก้ไข 2013-01-31 : ไม่กี่ปีและ DBA ต่อมาและตอนนี้เราใช้ Hibernate ไปที่ SQL (procs ที่เก็บไว้ใน DB) เมื่อจำเป็นเท่านั้น นี่ฉันคิดว่าเป็นทางออกที่ดีที่สุด 99% ของเวลาที่ DB ไม่จำเป็นต้องกังวลเกี่ยวกับ SQL และ 1% ที่พวกเขาทำนั้นอยู่ในที่ที่พวกเขาคุ้นเคยอยู่แล้ว


1
+1 สำหรับแนวคิดในการเขียนโพรซีเดอร์ที่จัดเก็บไว้แล้วสร้างโค้ด Java จากพวกเขาไม่ใช่วิธีอื่น
Daniel Pryden

สิ่งที่ฉันใช้คือเลเยอร์ Java ไม่ควร mimmick หรือแมปเลเยอร์ DB ในลักษณะใด ๆ ฉันคิดว่าถ้าคุณกำลังพยายามสรุปแพ็คเกจ Oracle ให้สร้างแพ็คเกจอื่นหรือขั้นตอนการห่อเพิ่มเติม ฉันพยายามแยกทั้งสองอย่างมีเหตุผลโดยการฝึกฝน
จ่อคิว

2
@ Xepoch: ฉันเห็นด้วยจริงๆ - บางทีฉันควรจะพูดความคิดเห็นของฉันแตกต่างออกไป ฐานข้อมูลของคุณควรเป็นภาพสะท้อนของโมเดลข้อมูลของคุณ (แบบจำลองความสัมพันธ์เอนทิตี) และโมเดลอ็อบเจ็กต์ของคุณควรเป็นภาพสะท้อนของโมเดลข้อมูลของคุณด้วย (แม้ว่าจะไม่จำเป็นต้องเหมือนกันก็ตาม) ดังนั้นพวกเขาควรจะเกี่ยวข้องกันอย่างน้อย ในแง่ของการสร้างโค้ด Java จากโพรซีเดอร์ที่จัดเก็บประเด็นก็คือ API สำหรับการเข้าถึงฐานข้อมูลของคุณควรได้มาจากโครงสร้างของโมเดลข้อมูลของคุณไม่ใช่โมเดลข้อมูลของคุณที่ได้มาจากโครงสร้างของอ็อบเจ็กต์ของคุณ
Daniel Pryden

คุณอาจจะสนใจในการใช้jooq.org มันทำตามที่คุณพูด: "การสร้างโค้ดเพื่อสร้างคลาส Java จากแพ็คเกจ Oracle" นอกจากนั้นยังมาพร้อมกับ DSL แบบ SQL คล้ายกับ LINQ ใน C # หากคุณต้องการแสดง SQL ใน Java ซึ่งคุณไม่สามารถใส่ไว้ในโพรซีเดอร์ที่เก็บไว้ได้
Lukas Eder

10

การใช้ ORM (เช่น hibernate) คุณหวังว่าจะไม่มีคำสั่ง SQL ที่ต้องกังวล โดยปกติประสิทธิภาพจะเป็นที่ยอมรับและคุณได้รับความเป็นอิสระจากผู้ขายเช่นกัน


13
-1 คุณจะมีคำสั่ง HQL และปัญหาส่วนใหญ่ยังคงเกี่ยวกับ HQL พวกเขาจะอยู่ในโค้ด (ตัวอักษรสตริง), ตั้งชื่อคิวรีในคำอธิบายประกอบ, ตั้งชื่อคิวรีในไฟล์ xml, เก็บไว้ในไฟล์คุณสมบัติหรือไม่
flybywire

1
@flybywire - ด้วย Hibernate มันเป็นสิ่งที่หายากที่จะใช้ HQL สำหรับ 98% ของกรณีและปัญหาการสืบค้นตามตัวอย่างและตามเกณฑ์ (เช่นการใช้วัตถุ) เป็นสิ่งที่จำเป็น
SingleShot

2
@SingleShot ผมไม่เห็นด้วย ถ้ามันเป็นสิ่งที่มีความซับซ้อนกว่าการเลือกของคุณ id ผมคิดว่ามันจะทำกับ HQL ฉันจะบอกว่าเกณฑ์และตัวอย่างถูกใช้เมื่อทำการค้นหาที่ขับเคลื่อนด้วยอินเทอร์เฟซผู้ใช้เช่นเดียวกับในหน้าจอค้นหาในแคตตาล็อกไลบรารี แต่มาดูกันว่าคนอื่นคิดอย่างไร
flybywire

3
@SingleShot - ฉันไม่เห็นด้วยมาก เราใช้ HQL จำนวนมากโดยเฉพาะอย่างยิ่งสำหรับการรายงานแบบสอบถาม คุณสมบัติบางอย่างของ HQL ไม่ได้รับการสนับสนุนตามเกณฑ์เลย (โดยใช้ฟังก์ชัน SQL ที่กำหนดเองตัวสร้างในส่วนคำสั่งที่เลือก) QBE บางครั้งอาจนำไปสู่ปัญหามากขึ้นจากนั้นก็จะคลี่คลาย
javashlook

4
"ไฮเบอร์เนตเป็นสิ่งที่หายากที่จะหันมาใช้ HQL" เป็นสิ่งที่สนุกที่สุดที่ฉันเคยได้ยินมาในปัจจุบัน QBE ไร้สาระ และในขณะที่คุณอาจจะต้องหันไปเกณฑ์สำหรับการค้นหา UI แบบสอบถามที่ดีที่กำหนด (ปฏิสัมพันธ์รายงาน / บริการ / etc ... ) ทั้งหมดควรจะอยู่ใน HQL
ChssPly76

10

ควรพิจารณาโค้ด SQL เป็น“ code” หรือ“ metadata”?

รหัส.

ควรใช้กระบวนงานที่จัดเก็บไว้เพื่อเพิ่มประสิทธิภาพการทำงานเท่านั้นหรือเป็นนามธรรมที่ถูกต้องตามกฎหมายของโครงสร้างฐานข้อมูล?

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

ORM ไม่ได้ยืมตัวไปสู่การเพิ่มประสิทธิภาพเนื่องจากเป็นนามธรรม IME, ORM ยังหมายถึงการขาดความสมบูรณ์ของการอ้างอิง - ทำให้ฐานข้อมูลยากต่อการรายงาน สิ่งที่บันทึกไว้ในความซับซ้อนได้เพิ่มขึ้นเพื่อให้สามารถนำข้อมูลออกมาใช้งานได้

ประสิทธิภาพเป็นปัจจัยสำคัญในการตัดสินใจหรือไม่? แล้วผู้ขายล็อคอินล่ะ?

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


4
+1 สำหรับการเรียกรหัส SQL เครื่องมือ ORM มากเกินไปพยายามซ่อน SQL ซึ่งในความเป็นจริงมักเป็นภาษาที่ดีที่สุดในการแสดงสิ่งที่คุณกำลังพยายามทำ และฉันเห็นด้วยกับความคิดเห็นของคุณว่าขั้นตอนการจัดเก็บนั้นดีกว่า ORM แม้ว่าฉันสงสัยว่าจะเป็นความคิดเห็นยอดนิยมที่นี่
Daniel Pryden

9

ความกลัวของผู้ขายที่ล็อคอินในโลก java นั้นน่าสนใจ

ฉันหวังว่าคุณจะไม่ได้จ่ายซีพียูราคา $ 50000 สำหรับ Oracle Enterprise จากนั้นใช้เฉพาะตัวส่วนร่วมน้อยที่สุดเพื่อเปลี่ยนเป็น Mysql ได้ทุกนาที ดังที่ DBA ที่ดีจะบอกคุณว่ามีความแตกต่างเล็กน้อยระหว่างฐานข้อมูลชื่อใหญ่ที่แตกต่างกันโดยเฉพาะอย่างยิ่งในเรื่องการล็อคโมเดลและวิธีที่พวกเขาบรรลุความสอดคล้องกัน

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


1
โอ้ไม่มีอะไรอย่างนั้น! ข้อกังวลหลักคือการอนุญาตให้ทีมสนับสนุนแก้ไขคำสั่ง SQL (เช่นสำหรับการปรับแต่งงานที่เกี่ยวข้องกับ DBA) และปรับปรุงการมองเห็นเกี่ยวกับสิ่งที่แอปพลิเคชันทำ (เกี่ยวข้องกับฐานข้อมูลทีมสนับสนุนไม่มีความรู้ Java และพวกเขาจะไม่ มีความสุขที่ได้ดูโค้ดแบบเจาะลึกแอปพลิเคชั่นนี้จะเป็นส่วนเสริมใหม่ของอสังหาริมทรัพย์ขนาดใหญ่ที่มีอยู่ทั้งหมดโดยใช้ฐานข้อมูล Ingres
เอเดรียน

6

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

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

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


+1 มุมมองที่ดี คุณจะสนใจในบล็อกโพสต์นี้ฉันคิดว่า: database-programmer.blogspot.com/2010/12/… .
Lukas Eder

5

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

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

  • ORM - สิ่งนี้จะลดจำนวน SQL ที่คุณต้องใช้ในการเขียนและจัดการกับรายละเอียดมากมายสำหรับคุณ คุณจะต้องทำ SQL แบบกำหนดเอง ตรวจสอบให้แน่ใจว่าคุณมี ORM ที่จัดการสิ่งนี้ได้อย่างสง่างาม
  • Data Access Objects - เก็บ SQL ไว้ในวัตถุที่เข้าถึงข้อมูล สิ่งนี้จะห่อหุ้มฐานข้อมูลของคุณและทำให้แอปพลิเคชันที่เหลือของคุณไม่จำเป็นต้องรู้เกี่ยวกับโครงสร้างฐานข้อมูลพื้นฐานเพียงแค่ส่วนต่อประสานกับวัตถุเหล่านี้
  • Stored Procedures - สิ่งนี้จะเก็บ SQL ทั้งหมดของคุณไว้ในฐานข้อมูลของคุณและทำให้ DBA ของคุณรู้ว่าเกิดอะไรขึ้นได้ง่าย สิ่งที่คุณต้องทำคือให้รหัสของคุณโทรหา procs ที่เก็บไว้

4

เราใช้ตัวทำแผนที่ iBatis SQL ซึ่งอยู่ใกล้โลหะมากกว่า ORM เช่น Hibernate ใน iBatis คุณใส่คำสั่ง SQL ลงในไฟล์ทรัพยากร (XML) ซึ่งจำเป็นต้องอยู่ใน classpath

รายการวิธีการของคุณดูเหมือนจะค่อนข้างครอบคลุมหากคุณเพิ่มตัวเลือก ORM ของ @ ocdecio ฉันจะบอกว่าการใช้ ORM และการใช้ SQL mapper และไฟล์ทรัพยากรเป็นสองวิธีที่ดีที่สุด ฉันจะหลีกเลี่ยงจาก SQLJ ซึ่งไม่ได้เห็นการรับรู้มากนักและเชื่อมโยงคุณกับ Java มากเกินไป หลีกเลี่ยงขั้นตอนที่จัดเก็บไว้ด้วยเนื่องจากพวกเขาผูกคุณกับผู้จัดจำหน่ายฐานข้อมูลที่เฉพาะเจาะจง (มาตรฐานแทบจะไม่มีอยู่สำหรับกระบวนงานที่จัดเก็บ)


4

เช่นเดียวกับพวกเราส่วนใหญ่ฉันเคยเห็น Gammut ทั้งหมด แต่เราต้องพิจารณาว่า SQL เป็นภาษาชั้นหนึ่ง ฉันเคยเห็น SQL ที่เก็บไว้ในฐานข้อมูลที่ดึงลงมาแล้วดำเนินการสำรอง

ระบบที่ประสบความสำเร็จที่สุดที่ฉันเคยเห็นใช้กระบวนงานฟังก์ชันและมุมมองที่เก็บไว้

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

การคาดการณ์ทั้งหมดควรผ่านมุมมองและการเลือกอย่างง่ายด้วยเหตุผลเดียวกันตรรกะการฉายภาพทั้งหมดควรมีอยู่ในมุมมอง


+1 สำหรับการกล่าวถึงการดู สิ่งนี้ยังไม่สะท้อนในบทสรุปของคำถาม
Lukas Eder

2

ฉันขอแนะนำให้ใช้ DAO ที่มีเค้าโครงจากโรงงาน ดังนั้นวัตถุตัวอย่างที่คุณต้องการคือ:

public class CoolBusinessObject
public class DAOFactory.java
public implementation CoolBusinessOjectDAO
public class CoolBusinessOjectDAOOracleImpl implements CoolBusinessOjectDAO

สไตล์นี้จะแบ่งชั้นการโต้ตอบกับข้อมูลดังนั้นคุณควรเปลี่ยนโค้ดเพียงชั้นเดียวหากคุณเปลี่ยนฐานข้อมูลหรือย้ายไปที่เทคโนโลยี ORM


2

ไม่มีความแตกต่างที่สำคัญระหว่างสามสิ่งนี้:

  1. ฮาร์ดโค้ดในวัตถุทางธุรกิจ
  2. ฝังอยู่ในส่วนคำสั่งSQLJ
  3. ห่อหุ้มในคลาสที่แยกจากกันเช่นData Access Objects

ฉันสมมติว่าคุณกำลังจะฝังโค้ด SQL ในรูปแบบสตริงลงในโค้ด Java ของคุณโดยตรง ในขณะที่ 1 และ 3 อาจใช้ JDBC โดยตรง (หรือเครื่องมือบางอย่างเช่นApache DbUtils ) แต่ 2 จะเพิ่มเทคโนโลยีตัวประมวลผลล่วงหน้าให้กับสแต็กโดยสร้างรหัส JDBC ที่เกี่ยวข้องก่อนการคอมไพล์

ดังนั้นโดยพื้นฐานแล้วหากโซลูชันเหล่านี้เกี่ยวข้องกับการฝัง SQL คุณอาจใช้เทคโนโลยีเหล่านี้ด้วยเช่นกัน:

  • JPA Criteria APIสร้างแบบจำลอง JPQL เป็นภาษาเฉพาะโดเมนภายในใน Java
  • jOOQสร้างโมเดล SQL เป็นภาษาเฉพาะโดเมนภายในใน Java

นอกจากนี้ยังอาจมีเครื่องมืออื่น ๆ ที่ช่วยคุณฝัง SQL ใน Java ในลักษณะที่ปลอดภัยกว่าการใช้ SQLJ หรือผ่านการต่อสายอักขระจริง


1

จากประสบการณ์ที่ฉันมีคำสั่ง sql การเข้ารหัสอย่างหนักในวัตถุ DAO เป็นสิ่งที่ใช้กันอย่างแพร่หลายแม้ว่าฉันคิดว่าควรเป็นวิธีที่ต้องการน้อยที่สุด แนวทางปฏิบัติที่ดีที่สุดคือการจัดเก็บคำสั่ง sql ในไฟล์คุณสมบัติ และได้รับงบในวัตถุ DAO ผ่านอินเตอร์เฟซไฟล์คุณสมบัติการพูดjava.util.Properties งบ SQL สามารถสลับกับ '?' S เพื่อส่งผ่านพารามิเตอร์ผ่านงบเตรียมวิธีการ

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


บางคนอาจคัดค้านว่าสิ่งนี้จะทำให้เกิดความเสี่ยงของการแทรก SQL คุณมีความคิดเห็นอย่างไรเกี่ยวกับเรื่องนี้?
Adrian

2
หากคุณจัดเก็บรหัส SQL ไว้นอกแอปพลิเคชันแล้วข้อดีของการจัดเก็บเป็นสตริงที่ใดที่หนึ่งมากกว่าการจัดเก็บในชั้นฐานข้อมูล (ตามขั้นตอนที่จัดเก็บ) กระบวนงานที่จัดเก็บไว้สามารถใช้เครื่องมือเพิ่มประสิทธิภาพฐานข้อมูลของคุณได้อย่างมีประสิทธิภาพมากขึ้นดังนั้นขั้นตอนเหล่านี้มักจะมีประสิทธิภาพดีกว่างบที่เตรียมไว้
Daniel Pryden

1
สวัสดี Daniel ฉันไม่ได้หมายความว่าคุณไม่ได้เขียน sql procs ฉันแค่หมายถึงคุณเรียก procs ที่เก็บไว้ในแบบที่ฉันพูดถึง ช่วยให้คุณสามารถควบคุมได้ดีขึ้นผ่านการส่งผ่านพารามิเตอร์ไปยัง proc ที่จัดเก็บไว้เช่นกัน
The Machine

1

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

ฉันอยากรู้จริงๆว่ามีใครใช้แนวทางของฉันด้วย


อยากรู้ว่าทำไมคุณไม่เก็บ SQL ไว้ที่ DB?
จ่อคิว

@Xepoch - หมายความว่าไง? คำสั่งอยู่ในรีซอร์สบันเดิล (ไฟล์คุณสมบัติ) ซึ่งอยู่ภายในแพ็กเกจเดียวกับเอนทิตีดังนั้น customer.properties จึงเกี่ยวข้องกับ Customer.class ข้อมูลถูกเก็บไว้ในฐานข้อมูล
Brett Ryan

1

เนื่องจากrexemเขียนสถิติ SQL เป็นรหัส - ควรถือว่าเป็นรหัสไม่ใช่ภายนอก (คุณมีเหตุผลที่ดี) แต่วางด้วยรหัสที่ประมวลผลข้อมูล SQL จาก / ไปยังคำสั่งนั้น วันนี้กรอบ ORMs / iBatis เสนอความเรียบง่ายมากมายสำหรับการพัฒนา JDBC แบบวันต่อวัน

บางคำตอบสำหรับคำถามของคุณคุณจะพบในคำถามนี้ :) ปัญหาในการจัดเก็บสถิติ SQL ของคุณขึ้นอยู่กับราชาของแอปพลิเคชันของคุณ ความต้องการของคุณคืออะไร? ความปลอดภัยสูงความสะดวกในการเขียนโค้ดหรือการบำรุงรักษาข้ามแพลตฟอร์มหรือล็อคอินผู้ขาย? คำถามต่อไปคุณต้องใช้ SQL หรือ ORM framework ล้วนๆจะดีหรือไม่?

* Hardcoded in business objects
* Encapsulate in separate classes e.g. Data Access Objects

วิธีแก้ไขที่ง่ายที่สุด (P) บำรุงรักษายาก (C)

* Embedded in SQLJ clauses

การตรวจสอบไวยากรณ์ของ Beter (P) ไม่มีการสืบค้นแบบไดนามิก od (C) ประสิทธิภาพต่ำกว่า JDBC (C) ไม่เป็นที่นิยม (C)

* Metadata driven (decouple the object schema from the data schema - describe the mappings between them in metadata)

ต้องเป็นกรณีเฉพาะที่คุณควรทำเช่นนั้น (C) หรือถ้าคุณหมายถึง ORM (P);)

* External files (e.g. Properties or Resource files)

ง่ายต่อการติดตั้ง (P) แต่ตรวจสอบข้อผิดพลาดได้ยากกว่า (C)

* Stored Procedures

มีความปลอดภัยสูง (P) รหัสยากที่จะรักษาปัญหาการล็อคอินของผู้ขาย (C)

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