Lập trình Java - Câu lệnh SQL nên được lưu trữ ở đâu? [đóng cửa]


106

Một ứng dụng tuân thủ JDBC nên lưu trữ các câu lệnh SQL của nó ở đâu và tại sao?

Cho đến nay, tôi đã quản lý để xác định các tùy chọn này:

  • Mã cứng trong các đối tượng kinh doanh
  • Được nhúng trong mệnh đề SQLJ
  • Đóng gói trong các lớp riêng biệt, ví dụ: Đối tượng truy cập dữ liệu
  • Theo hướng siêu dữ liệu (tách lược đồ đối tượng khỏi lược đồ dữ liệu - mô tả ánh xạ giữa chúng trong siêu dữ liệu)
  • Các tệp bên ngoài (ví dụ: Thuộc tính hoặc tệp Tài nguyên)
  • Thủ tục lưu trữ

"Ưu điểm" và "Nhược điểm" cho mỗi cái là gì?

Mã SQL nên được coi là “mã” hay “siêu dữ liệu”?

Các thủ tục được lưu trữ có nên được sử dụng chỉ để tối ưu hóa hiệu suất hay chúng là một cấu trúc cơ sở dữ liệu trừu tượng hợp pháp?

Hiệu suất có phải là yếu tố quyết định không? Điều gì về khóa nhà cung cấp ?

Điều gì là tốt hơn - khớp nối lỏng lẻo hoặc khớp nối chặt chẽ và tại sao?

ĐÃ CHỈNH SỬA: Cảm ơn mọi người vì câu trả lời - đây là bản tóm tắt:

Điều khiển siêu dữ liệu tức là Ánh xạ quan hệ đối tượng (ORM)

Ưu điểm:

  • Rất trừu tượng - Máy chủ DB có thể được chuyển đổi mà không cần thay đổi mô hình
  • Phạm vi rộng - thực tế là một tiêu chuẩn
  • Cắt giảm lượng SQL cần thiết
  • Có thể lưu trữ SQL trong các tệp tài nguyên
  • Hiệu suất (thường) chấp nhận được
  • Phương pháp tiếp cận theo hướng siêu dữ liệu
  • (Cơ sở dữ liệu) độc lập với nhà cung cấp

Nhược điểm:

  • Ẩn SQL và ý định thực sự của nhà phát triển
  • SQL khó được DBA xem xét / thay đổi
  • SQL có thể vẫn cần thiết cho các trường hợp kỳ quặc
  • Có thể buộc sử dụng ngôn ngữ truy vấn độc quyền, ví dụ như HQL
  • Không tự cho mình tối ưu hóa (trừu tượng hóa)
  • Có thể thiếu tính toàn vẹn tham chiếu
  • Thay thế cho việc thiếu kiến ​​thức SQL hoặc thiếu cẩn thận để viết mã trong DB
  • Không bao giờ khớp với hiệu suất cơ sở dữ liệu gốc (ngay cả khi nó đến gần)
  • Mã mô hình rất chặt chẽ kết hợp với mô hình cơ sở dữ liệu

Được mã hóa cứng / đóng gói trong lớp DAO

Ưu điểm:

  • SQL được giữ trong các đối tượng truy cập dữ liệu (đóng gói)
  • SQL rất dễ viết (tốc độ phát triển)
  • SQL dễ theo dõi khi cần thay đổi
  • Giải pháp đơn giản (không có kiến ​​trúc lộn xộn)

Nhược điểm:

  • SQL không thể được xem xét / thay đổi bởi DBA
  • SQL có khả năng trở thành DB cụ thể
  • SQL có thể trở nên khó bảo trì

Thủ tục lưu trữ

Ưu điểm:

  • SQL được giữ trong cơ sở dữ liệu (gần với dữ liệu)
  • SQL được phân tích cú pháp, biên dịch và tối ưu hóa bởi DBMS
  • SQL dễ dàng để DBA xem xét / thay đổi
  • Giảm lưu lượng mạng
  • Tăng cường an ninh

Nhược điểm:

  • SQL được gắn với cơ sở dữ liệu (khóa nhà cung cấp)
  • Mã SQL khó duy trì hơn

Các tệp bên ngoài (ví dụ: Thuộc tính hoặc tệp Tài nguyên)

Ưu điểm

  • SQL có thể được thay đổi mà không cần phải xây dựng lại ứng dụng
  • Tách logic SQL khỏi logic nghiệp vụ ứng dụng
  • Kho lưu trữ trung tâm của tất cả các câu lệnh SQL - dễ bảo trì hơn
  • Dễ hiểu

Nhược điểm:

  • Mã SQL có thể trở nên không thể bảo trì được
  • Khó kiểm tra mã SQL để tìm lỗi (cú pháp)

Được nhúng trong mệnh đề SQLJ

Ưu điểm:

  • Kiểm tra cú pháp tốt hơn

Nhược điểm:

  • Liên kết quá chặt chẽ với Java
  • Hiệu suất thấp hơn JDBC
  • Thiếu truy vấn động
  • Không phổ biến lắm

Những câu hỏi hay nhưng có thể hơi nhiều để trả lời tất cả cùng một lúc. Nó sẽ mất một vài trang để trả lời tất cả các IMHO: p
NickDK

+1 Câu hỏi hay! Bạn nên thêm "ORM" cho mỗi @ocdecio. Cũng thêm "rắc ở khắp mọi nơi trong mã Java của bạn" (mà tôi đã thấy và phải nói là tồi tệ nhất).
Jim Ferrans

2
Tôi hoàn toàn không đồng ý với "Mã SQL khó bảo trì hơn" trong Quy trình lưu trữ. Trong XP của tôi, SQL dễ bảo trì hơn khi nó đi vào cơ sở dữ liệu. Một phần vì lý do được sử dụng trong các tệp Bên ngoài (Kho lưu trữ trung tâm của tất cả các câu lệnh SQL - dễ bảo trì hơn), cộng với các tham số dễ quản lý hơn.
Michael Lloyd Lee mlk

1
Theo tôi, bạn đã bỏ qua một lựa chọn: Việc sử dụng các lượt xem. Bạn có thể thể hiện SQL phức tạp trong các khung nhìn và sau đó chỉ cần thể hiện các lựa chọn đơn giản trên các khung nhìn đó (sử dụng bất kỳ kiểu trừu tượng nào: DAO, SQLJ, ORM, v.v.). Bạn sẽ có những ưu tương tự như với các thủ tục lưu trữ, nhưng tôi dont't nghĩ rằng bạn sẽ có bất kỳ khuyết điểm của họ ...
Lukas Eder

Câu trả lời:


31

Thông thường, ứng dụng càng phát triển về kích thước và / hoặc khả năng tái sử dụng, thì nhu cầu ngoại hóa / trừu tượng hóa các câu lệnh SQL càng nhiều.

Hardcoded (dưới dạng hằng số tĩnh cuối cùng) là bước đầu tiên. Lưu trữ trong một tệp (thuộc tính / tệp xml) là bước tiếp theo. Điều khiển siêu dữ liệu (được thực hiện bởi ORM như Hibernate / JPA) là bước cuối cùng.

Hardcoded có nhược điểm là mã của bạn có khả năng trở thành dành riêng cho DB và bạn cần phải viết lại / xây dựng lại / phân phối lại mỗi lần thay đổi. Lợi thế là bạn có nó ở 1 nơi.

Được lưu trữ trong một tệp có nhược điểm là nó có thể trở nên không thể truy cập được khi ứng dụng phát triển. Ưu điểm là bạn không cần phải viết lại / xây dựng lại ứng dụng, trừ khi bạn cần thêm một phương thức DAO bổ sung.

Điều khiển siêu dữ liệu có nhược điểm là mã mô hình của bạn kết hợp rất chặt chẽ với mô hình cơ sở dữ liệu. Đối với mọi thay đổi trong mô hình cơ sở dữ liệu, bạn sẽ cần viết lại / xây dựng lại / phân phối lại mã. Ưu điểm là nó rất trừu tượng và bạn có thể dễ dàng chuyển đổi từ máy chủ DB mà không cần phải thay đổi mô hình của mình (nhưng hãy tự hỏi bản thân ngay bây giờ: tần suất một công ty chuyển từ máy chủ DB là bao lâu? Có thể ít nhất chỉ một lần mỗi 3 năm, isn ' t nó?).

Tôi sẽ không gọi các thủ tục được lưu trữ là giải pháp "tốt" cho việc này. Họ có một mục đích hoàn toàn khác. Mặc dù vậy, mã của bạn sẽ phụ thuộc vào DB / cấu hình được sử dụng.


21

Tôi không biết liệu điều này có phải là tối ưu hay không, nhưng theo kinh nghiệm của tôi, chúng kết thúc được mã hóa cứng (tức là chuỗi ký tự) trong lớp DAO.


5
Nó có lẽ không phải là tối ưu nhưng đó là những gì tôi làm. Dễ viết, dễ theo dõi và không cần lo lắng về kiến ​​trúc lộn xộn.
James Cronen

21
Và tất cả thời gian dành cho việc theo dõi SQL được mã hóa cứng là bảo mật công việc. Nếu bạn là người duy nhất biết SQL ở đâu, bạn không thể bị sa thải.
S.Lott

11
Tôi luôn ngạc nhiên rằng nhiều người cẩn thận xây dựng mã OO Java sạch sẽ, được kiến ​​trúc độc đáo lại là những người chịu đựng việc viết SQL lộn xộn, không hiệu quả và chỉ dán nó như một chuỗi ở những nơi ngẫu nhiên. Nếu SQL của bạn chỉ là các chuỗi trong lớp DAO của bạn, thì tôi có thể đảm bảo rằng bạn không có DBA trong nhóm của mình. Ít nhất không phải là một DBA tốt .
Daniel Pryden

3
-1. Có thể có DAO nhưng ít nhất hãy di chuyển các truy vấn đến một tệp thuộc tính ở đâu đó để DBA có thể xem xét và điều chỉnh chúng cho phù hợp!
cethegeek

3
Kinh nghiệm của tôi là, nếu bạn đang thực hiện JDBC thẳng, đặt chuỗi truy vấn trong lớp Đối tượng truy cập dữ liệu có lẽ là cách tiếp cận tốt nhất nếu bạn không thể sử dụng giải pháp ORM. Một khi cảnh báo là hãy đảm bảo rằng mọi người trên cùng một trang với các tiêu chuẩn mã hóa cho các lớp DAO nếu bạn đi theo cách đó. Tôi đã gỡ bỏ cả gói tài nguyên và các tuyến quy trình được lưu trữ và cả hai đều là cơn ác mộng bảo trì tuyệt đối vì nó trải rộng logic truy cập dữ liệu qua nhiều lớp, vì vậy việc thêm một cột vào truy vấn yêu cầu bạn thay đổi mọi thứ ở những nơi khác nhau.
Jason Gritman

12

Tôi không nghĩ rằng bất cứ ai sẽ cung cấp cho bạn sự phá vỡ chuyên nghiệp / con bạn muốn vì nó là một câu hỏi khá lớn. Vì vậy, thay vào đó, đây là những gì tôi đã sử dụng trong quá khứ và những gì tôi sẽ sử dụng trong tương lai.

Tôi sử dụng để sử dụng mã cứng SQL trong DAL. Tôi nghĩ rằng điều này là tốt cho đến khi các DBA muốn chơi với SQL. Sau đó, bạn phải đào nó ra, định dạng nó và chuyển nó sang DBA. Ai sẽ cười nó và thay tất cả. Nhưng không có dấu chấm hỏi đẹp, hoặc dấu hỏi không đúng thứ tự và khiến bạn phải gắn nó lại trong mã Java.

Chúng tôi cũng đã sử dụng ORM, và mặc dù điều này rất tốt cho các nhà phát triển DBA của chúng tôi ghét nó vì không có SQL để họ cười. Chúng tôi cũng sử dụng một ORM kỳ quặc (một ORM tùy chỉnh từ nhà cung cấp bên thứ 3) có thói quen giết cơ sở dữ liệu. Tôi đã sử dụng JPA kể từ đó và rất tuyệt vời, nhưng việc sử dụng nó bất cứ thứ gì phức tạp trong quá khứ DBA là một cuộc chiến khó khăn.

Bây giờ chúng tôi sử dụng Thủ tục lưu trữ (với câu lệnh gọi được mã hóa cứng). Bây giờ điều đầu tiên mà mọi người sẽ phàn nàn là bạn bị ràng buộc với cơ sở dữ liệu. Bạn là. Tuy nhiên bạn đã thay đổi cơ sở dữ liệu bao lâu một lần? Tôi biết thực tế là chúng tôi thậm chí không thể thử nó, số lượng mã khác phụ thuộc vào nó cộng với việc đào tạo lại DBA của chúng tôi cộng với việc di chuyển dữ liệu. Nó sẽ là một hoạt động rất tốn kém. Tuy nhiên, nếu trong thế giới của bạn thay đổi DBs mà không cần thiết thì các SP có thể bị loại bỏ.

Trong tương lai, tôi muốn sử dụng các thủ tục được lưu trữ với các công cụ tạo mã để tạo các lớp Java từ các gói Oracle.

Chỉnh sửa 2013-01-31 : Vài năm sau và DBAs và bây giờ chúng tôi sử dụng Hibernate, chuyển sang SQL (procs được lưu trữ trong DB) chỉ khi thực sự cần thiết. Điều này tôi nghĩ là giải pháp tốt nhất. 99% các DB không cần phải lo lắng về SQL và 1% họ làm điều đó ở một nơi mà họ đã cảm thấy thoải mái.


1
+1 cho ý tưởng viết các thủ tục được lưu trữ và sau đó tạo mã Java từ chúng, chứ không phải ngược lại.
Daniel Pryden

Ý kiến ​​của tôi là lớp Java KHÔNG nên bắt chước hoặc ánh xạ theo bất kỳ cách nào đối với lớp DB. Tôi nghĩ nếu bạn đang cố gắng tóm tắt gói Oracle, thì hãy tạo một gói khác hoặc nhiều thủ tục gói hơn. Tôi cố gắng và hoàn toàn tách biệt một cách hợp lý bằng cách thực hành.
Jé Queue

2
@Xepoch: Tôi thực sự đồng ý - có lẽ tôi nên nói lời nhận xét của mình theo cách khác. Cơ sở dữ liệu của bạn phải phản ánh mô hình dữ liệu của bạn (mô hình mối quan hệ thực thể) và mô hình đối tượng của bạn cũng phải phản ánh mô hình dữ liệu của bạn (mặc dù không nhất thiết phải giống hệt nhau). Vì vậy, chúng nên có liên quan ít nhất. Về mặt tạo mã Java từ các thủ tục được lưu trữ, điểm mấu chốt là API để truy cập vào cơ sở dữ liệu của bạn phải được bắt nguồn từ cấu trúc của mô hình dữ liệu của bạn, chứ không phải mô hình dữ liệu của bạn được bắt nguồn từ cấu trúc của các đối tượng của bạn.
Daniel Pryden

Bạn có thể quan tâm đến việc sử dụng jooq.org . Nó thực hiện chính xác những gì bạn đã nói: "tạo mã để tạo các lớp Java từ các gói Oracle". Ngoài ra, nó còn đi kèm với một DSL giống SQL, tương tự như LINQ trong C #, nếu bạn cần diễn đạt SQL bằng Java, điều mà bạn không thể đặt bên trong một thủ tục được lưu trữ.
Lukas Eder

10

Bằng cách sử dụng ORM (chẳng hạn như hibernate), bạn hy vọng sẽ không có câu lệnh SQL nào phải lo lắng. Hiệu suất thường được chấp nhận và bạn cũng nhận được sự độc lập của nhà cung cấp.


13
-1 bạn sẽ có các câu lệnh HQL và hầu hết các vấn đề vẫn còn liên quan đến HQL. Chúng sẽ nằm bên trong mã (chuỗi ký tự), truy vấn được đặt tên trong chú thích, truy vấn được đặt tên trong tệp xml, được lưu trữ trong tệp thuộc tính?
flybywire

1
@flybywire - với Hibernate, hiếm khi sử dụng đến HQL. Đối với 98% trường hợp, truy vấn theo ví dụ và theo tiêu chí (tức là sử dụng các đối tượng) là tất cả những gì cần thiết.
SingleShot

2
@SingleShot, tôi không đồng ý. Nếu nó là một cái gì đó phức tạp hơn chọn theo id, tôi nghĩ rằng nó được thực hiện với HQL. Tôi muốn nói rằng các tiêu chí và ví dụ được sử dụng khi thực hiện tìm kiếm theo hướng giao diện người dùng như trong màn hình tìm kiếm trong danh mục thư viện. Nhưng hãy xem những gì người khác nghĩ.
flybywire

3
@SingleShot - Tôi rất không đồng ý. Chúng tôi sử dụng rất nhiều HQL, đặc biệt là cho các truy vấn báo cáo. Một số tính năng HQL hoàn toàn không được hỗ trợ bởi tiêu chí (sử dụng các hàm SQL tùy chỉnh, các hàm tạo trong mệnh đề lựa chọn). QBE đôi khi có thể dẫn đến nhiều vấn đề hơn sau đó nó sẽ giải quyết được.
javashlook

4
"Với Hibernate, hiếm khi phải dùng đến HQL" cho đến nay là điều thú vị nhất mà tôi đã nghe hôm nay. QBE là vô lý; và trong khi bạn có thể phải dùng đến Tiêu chí cho các truy vấn UI, các truy vấn được xác định rõ ràng (báo cáo / tương tác dịch vụ / v.v.) đều phải ở trong HQL.
ChssPly76

10

Mã SQL nên được coi là “mã” hay “siêu dữ liệu”?

Mã.

Các thủ tục được lưu trữ có nên được sử dụng chỉ để tối ưu hóa hiệu suất hay chúng là một cấu trúc cơ sở dữ liệu trừu tượng hợp pháp?

Các thủ tục được lưu trữ cho phép sử dụng lại, bao gồm cả bên trong các thủ tục được lưu trữ khác. Điều này có nghĩa là bạn có thể thực hiện một chuyến đi đến cơ sở dữ liệu và để nó thực thi các hướng dẫn hỗ trợ - lý tưởng là lưu lượng truy cập ít nhất. ORM hoặc Spc, thời gian lên dây về db ​​& back là điều bạn không thể lấy lại được.

ORM không tự cho mình tối ưu hóa vì tính trừu tượng của nó. IME, ORM cũng có nghĩa là thiếu tính toàn vẹn tham chiếu - làm cho cơ sở dữ liệu khó báo cáo. Những gì đã được lưu trong độ phức tạp, giờ đây đã tăng lên để có thể lấy dữ liệu ra theo cách khả thi.

Hiệu suất có phải là yếu tố quyết định không? Điều gì về khóa nhà cung cấp?

Không, đơn giản là vậy. Khoá của nhà cung cấp cũng xảy ra với cơ sở dữ liệu - SQL tương đối được tiêu chuẩn hoá, nhưng vẫn có những cách thực hiện cụ thể của nhà cung cấp.


4
+1 để gọi mã SQL. Quá nhiều công cụ ORM cố gắng ẩn SQL, trong khi trên thực tế, nó thường là ngôn ngữ tốt nhất để diễn đạt những gì bạn đang cố gắng thực hiện. Và tôi đồng ý với ý kiến ​​của bạn rằng các thủ tục được lưu trữ tốt hơn ORM, mặc dù tôi nghi ngờ đó sẽ là một ý kiến ​​phổ biến ở đây.
Daniel Pryden

9

Nỗi sợ hãi về việc nhà cung cấp bị khóa trong thế giới java thật thú vị.

Tôi hy vọng bạn chưa trả $ 50000 pr CPU cho Oracle Enterprise và sau đó chỉ sử dụng mẫu số chung nhỏ nhất để chuyển sang Mysql bất kỳ phút nào. Như bất kỳ DBA tốt nào sẽ cho bạn biết, có sự khác biệt nhỏ giữa các cơ sở dữ liệu tên tuổi khác nhau, đặc biệt là về mô hình khóa và cách chúng đạt được tính nhất quán.

Vì vậy, đừng đưa ra quyết định về cách triển khai các lệnh gọi SQL của bạn chỉ dựa trên nguyên tắc SQL bất khả tri của nhà cung cấp - hãy có lý do thực sự (kinh doanh) để làm như vậy.


1
Ồ, không có gì giống như vậy! Mối quan tâm chính là cho phép nhóm hỗ trợ thay đổi các câu lệnh SQL (ví dụ: để điều chỉnh, các tác vụ liên quan đến DBA) và cải thiện khả năng hiển thị về những gì ứng dụng làm (liên quan đến cơ sở dữ liệu. Nhóm hỗ trợ không có bí quyết Java và họ sẽ không rất vui khi xem chi tiết về mã. Ứng dụng sẽ là một bổ sung mới cho một khối lớn các ứng dụng hiện có, tất cả đều sử dụng cơ sở dữ liệu Ingres.
Adrian

6

SQL bên trong Thủ tục được lưu trữ được tối ưu hóa bởi hệ thống cơ sở dữ liệu và được biên dịch để tăng tốc độ - đó là ngôi nhà tự nhiên của nó. SQL được hiểu bởi hệ thống cơ sở dữ liệu, được phân tích cú pháp bởi hệ thống cơ sở dữ liệu. Giữ SQL của bạn trong cơ sở dữ liệu nếu bạn có thể; bọc nó trong các thủ tục hoặc hàm được lưu trữ hoặc bất kỳ đơn vị logic nào mà hệ thống cơ sở dữ liệu cung cấp và thực hiện các lệnh gọi đơn giản đến nó bằng bất kỳ công cụ nào mà bạn hoặc bất kỳ ai khác đã đề cập.

Tại sao phải lưu trữ mã SQL cho hệ thống cơ sở dữ liệu bên ngoài db? Thường cho tốc độ phát triển. Tại sao sử dụng ánh xạ ORM? - Một số người nói ánh xạ ORM cung cấp khả năng tương thích trên các hệ thống cơ sở dữ liệu khác nhau; tuy nhiên hiếm khi trong thế giới thực một ứng dụng nào đó rời khỏi nền tảng cơ sở dữ liệu khi nó được xây dựng, đặc biệt là khi nó bắt đầu sử dụng các tính năng nâng cao như sao chép và trong một số trường hợp hiếm hoi xảy ra trường hợp hệ thống cơ sở dữ liệu bị hoán đổi, một số công việc được đảm bảo . Tôi tin rằng một trong những nhược điểm của ORM, nó thường thay thế cho việc thiếu kiến ​​thức SQL hoặc thiếu cẩn thận để viết mã trong db. Ngoài ra ORM sẽ không bao giờ khớp với hiệu suất cơ sở dữ liệu gốc ngay cả khi nó đến gần.

Tôi đang đứng về phía giữ mã SQL trong cơ sở dữ liệu và thực hiện các lệnh gọi đơn giản đến nó thông qua bất kỳ API hoặc giao diện nào bạn muốn sử dụng. Đồng thời trừu tượng hóa điểm mà tại đó các lệnh gọi cơ sở dữ liệu của bạn được thực hiện bằng cách đặt các lệnh gọi đó sau một lớp trừu tượng hoặc giao diện OO (được thể hiện bằng các phương thức), vì vậy nếu bạn hoán đổi trong một loại nguồn dữ liệu mới, nó sẽ liền mạch với lớp nghiệp vụ .


+1 Quan điểm tốt đẹp. Bạn sẽ quan tâm đến bài đăng trên blog này, tôi nghĩ: database-programmer.blogspot.com/2010/12/… .
Lukas Eder

5

Câu hỏi duy nhất bạn hỏi có câu trả lời chắc chắn là "Là mã SQL hay siêu dữ liệu?" Nó chắc chắn nhất là mã và như vậy nên được giữ trong một số loại kiểm soát mã nguồn và có một hệ thống để dễ dàng cập nhật lên phiên bản mới nhất và quay lại khi không xảy ra sự cố.

Tôi đã thấy ba cách thực hiện SQL trong một ứng dụng và mỗi cách đều có ưu và nhược điểm. Không có cách nào tốt nhất, nhưng điều tốt nhất là chỉ cần chọn một cách hoạt động tốt với ứng dụng của bạn và gắn bó với nó.

  • ORM - điều này cắt giảm lượng SQL bạn cần viết và xử lý rất nhiều chi tiết cho bạn. Bạn sẽ cần thực hiện một số SQL tùy chỉnh. Đảm bảo bạn có ORM xử lý việc này một cách linh hoạt.
  • Đối tượng truy cập dữ liệu - giữ SQL trong các đối tượng truy cập dữ liệu. Điều này đóng gói cơ sở dữ liệu của bạn và làm cho nó để phần còn lại của ứng dụng của bạn không cần biết về cấu trúc DB bên dưới, chỉ cần giao diện với các đối tượng này.
  • Thủ tục lưu trữ - điều này giữ tất cả SQL của bạn trong cơ sở dữ liệu và giúp DBA của bạn dễ dàng biết được điều gì đang xảy ra. Tất cả những gì bạn cần làm là gọi mã của bạn đến các procs được lưu trữ

4

Chúng tôi tình cờ sử dụng trình ánh xạ iBatis SQL, gần với kim loại hơn các ORM như Hibernate. Trong iBatis, bạn đặt các câu lệnh SQL vào các tệp tài nguyên (XML), các tệp này cần phải nằm trong classpath.

Danh sách các phương pháp tiếp cận của bạn có vẻ khá toàn diện nếu bạn thêm tùy chọn ORM của @ ocdecio. Tôi muốn nói rằng sử dụng ORM và sử dụng trình ánh xạ SQL và các tệp tài nguyên là hai cách tiếp cận tốt nhất. Tôi muốn tránh xa SQLJ, vốn không được nhiều người quan tâm và ràng buộc bạn quá chặt chẽ với Java. Cũng tránh xa các thủ tục được lưu trữ, vì chúng ràng buộc bạn với một nhà cung cấp cơ sở dữ liệu cụ thể (các tiêu chuẩn hầu như không tồn tại cho các thủ tục được lưu trữ).


4

Giống như hầu hết chúng ta, tôi đã thấy toàn bộ âm giai nhưng chúng ta cần coi SQL là một ngôn ngữ hạng nhất. Tôi thậm chí đã thấy SQL được lưu trữ trong DB được kéo xuống sau đó được thực thi sao lưu.

Các hệ thống thành công nhất mà tôi đã thấy sử dụng các thủ tục, chức năng và khung nhìn được lưu trữ.

Các procs được lưu trữ giữ văn bản SQL trở lại DB và cho phép thay đổi tương đối ngay lập tức bằng cách TRIỂN KHAI và TÙY CHỈNH đó (đòi hỏi nhiều thiết kế thích hợp để hỗ trợ nó).

Tất cả các phép chiếu phải thông qua các khung nhìn và các lựa chọn đơn giản vì những lý do giống nhau, tất cả logic của phép chiếu phải được chứa trong khung nhìn.


+1 để đề cập đến lượt xem. Này chưa phản ánh trong bản tóm tắt của câu hỏi
Lukas Eder

2

Tôi đề nghị sử dụng DAO với bố cục nhà máy. Vì vậy, các đối tượng ví dụ bạn cần sẽ là:

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

Kiểu này tạo lớp tương tác dữ liệu, vì vậy bạn chỉ phải thay đổi một lớp mã nếu bạn chuyển đổi cơ sở dữ liệu hoặc chuyển sang công nghệ ORM.


2

Thực sự không có bất kỳ sự khác biệt đáng kể nào giữa ba điều này:

  1. Mã cứng trong các đối tượng kinh doanh
  2. Được nhúng trong mệnh đề SQLJ
  3. Đóng gói trong các lớp riêng biệt, ví dụ: Đối tượng truy cập dữ liệu

Tôi giả định rằng bạn sẽ nhúng mã SQL ở dạng chuỗi trực tiếp vào mã Java của mình. Trong khi 1 và 3 có thể sẽ sử dụng JDBC trực tiếp (hoặc một số công cụ như Apache DbUtils ), 2 thêm một công nghệ tiền xử lý vào ngăn xếp, tạo mã JDBC có liên quan trước khi biên dịch.

Vì vậy, về cơ bản, nếu các giải pháp này liên quan đến việc nhúng SQL, bạn cũng có thể sử dụng bất kỳ công nghệ nào sau đây:

  • API tiêu chí JPA , lập mô hình JPQL như một ngôn ngữ dành riêng cho miền nội bộ trong Java
  • jOOQ , lập mô hình SQL như một ngôn ngữ dành riêng cho miền nội bộ trong Java

Cũng có thể có các công cụ khác giúp bạn nhúng SQL vào Java theo cách an toàn về kiểu chữ hơn là thông qua SQLJ hoặc thông qua nối chuỗi thực tế.


1

Theo kinh nghiệm, tôi đã có, các câu lệnh sql mã hóa cứng trong các đối tượng DAO là thứ được sử dụng rộng rãi, tuy nhiên, tôi nghĩ nó phải là phương pháp ít được ưa thích nhất. Cách tốt nhất là lưu trữ các câu lệnh sql trong một tệp thuộc tính. Và lấy các câu lệnh trong đối tượng DAO thông qua một giao diện với các tệp thuộc tính, chẳng hạn như java.util.Properties . Các câu lệnh sql có thể được xen kẽ với '?' Để chuyển các tham số, thông qua một Câu lệnh Chuẩn bị cách tiếp cận .

Cách tiếp cận như vậy giúp tách logic sql khỏi logic nghiệp vụ ứng dụng. Điều này cung cấp một kho lưu trữ trung tâm của tất cả các câu lệnh sql, giúp sửa đổi dễ dàng hơn, loại bỏ nhu cầu tìm kiếm các câu lệnh cơ sở dữ liệu trong logic ứng dụng.


Một số người có thể phản đối rằng điều này sẽ dẫn đến nguy cơ tiêm SQL. Ý kiến ​​của bạn về điều đó là gì?
Adrian

2
Nếu bạn vẫn đang lưu trữ mã SQL bên ngoài ứng dụng, thì lợi ích của việc lưu trữ nó dưới dạng chuỗi ở đâu đó thay vì lưu trữ nó trong lớp cơ sở dữ liệu (dưới dạng các thủ tục được lưu trữ)? Các thủ tục được lưu trữ có thể sử dụng hiệu quả hơn trình tối ưu hóa cơ sở dữ liệu của bạn, vì vậy chúng gần như luôn hoạt động tốt hơn các câu lệnh đã chuẩn bị.
Daniel Pryden

1
Xin chào Daniel, tôi không có ý, bạn không viết procs sql, tôi chỉ muốn nói, bạn gọi procs được lưu trữ, theo cách mà tôi đã đề cập. Nó giúp bạn kiểm soát tốt hơn, cũng như truyền các tham số cho proc được lưu trữ.
Máy

1

Cuối cùng của tôi trong các gói tài nguyên. Tôi biết điều đó không bình thường nhưng đó là điều dễ dàng nhất đối với tôi và bất kỳ ai "ngoài tôi" để duy trì. Nó đơn giản và logic.

Tôi thực sự tò mò muốn biết liệu có ai cũng sử dụng cách tiếp cận của tôi không.


Tò mò tại sao bạn không giữ SQL ở DB?
Jé Queue

@Xepoch - Ý bạn là như thế nào? Các câu lệnh nằm trong gói tài nguyên (tệp thuộc tính) nằm trong cùng một gói với các thực thể, do đó, customer.properties liên quan đến Customer.class. Dữ liệu được lưu trữ trong DB.
Brett Ryan

1

Như một rexem đã viết, các trạng thái SQL là mã - chúng phải được coi như mã, không được ngoại hóa (trừ khi bạn có lý do chính đáng) nhưng được đặt với mã xử lý dữ liệu SQL từ / đến các câu lệnh đó. Khung Todays ORMs / iBatis cung cấp rất nhiều đơn giản hóa để phát triển JDBC hàng ngày.

Một số câu trả lời cho câu hỏi của bạn mà bạn sẽ tìm thấy trong câu hỏi này :) Vấn đề làm thế nào các trạng thái SQL của bạn sẽ được lưu trữ phụ thuộc vào vua của ứng dụng của bạn. Nhu cầu của bạn là gì? Bảo mật cao, dễ viết mã hoặc bảo trì, định dạng chéo hoặc khóa nhà cung cấp? Câu hỏi tiếp theo bạn cần SQL thuần túy hay khung ORM sẽ tốt?

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

Dung dịch đơn giản nhất (P), khó duy trì (C)

* Embedded in SQLJ clauses

Kiểm tra cú pháp Beter (P), thiếu truy vấn động od (C), hiệu suất thấp hơn JDBC (C), không quá phổ biến (C)

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

Đó phải là trường hợp cụ thể bạn nên làm điều đó (C) hoặc nếu bạn có nghĩa là ORM (P);)

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

Dễ nhớ (P) nhưng khó kiểm tra lỗi hơn (C)

* Stored Procedures

Độ bảo mật cao (P), mã khó giải quyết vấn đề khóa nhà cung cấp (C)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.