Bạn thích loại ORM nào của Java và tại sao? [đóng cửa]


262

Đó là một câu hỏi kết thúc khá mở. Tôi sẽ bắt đầu một dự án mới và đang xem xét các ORM khác nhau để tích hợp với truy cập cơ sở dữ liệu.

Bạn có yêu thích nào không? Có bất cứ điều gì bạn sẽ khuyên ở lại?



Hãy xem trên vi orms - giấy gói mỏng xung quanh công nghệ truy cập DB nền tảng - như sql2o cho Java github.com/aaberg/sql2o hoặc ServiceStack.OrmLite cho .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki

3
Sau khi sử dụng ORM được hơn 5 năm, lựa chọn cá nhân của tôi là Spring JDBC so với ORM và thứ hai tốt nhất là iBatis (MyBatis), tôi không thích ngủ đông vì học đường cong, ít kiểm soát và các vấn đề về hiệu suất.

Dưới đây là (cũng đã đóng) danh sách các hàm bao jdbc nhẹ có thể được sử dụng thay thế cho các quả cầu đầy đủ: stackoverflow.com/questions/7137929/
Lỗi

Câu trả lời:


237

Tôi đã ngừng sử dụng ORM.

Lý do không phải là bất kỳ lỗ hổng lớn trong khái niệm. Hibernate hoạt động tốt. Thay vào đó, tôi đã thấy rằng các truy vấn có chi phí thấp và tôi có thể điều chỉnh nhiều logic phức tạp thành các truy vấn SQL lớn và chuyển rất nhiều xử lý của tôi vào cơ sở dữ liệu.

Vì vậy, hãy xem xét chỉ sử dụng gói JDBC.


81
Đó là câu chuyện tương tự lặp đi lặp lại với ORM: sự phát triển ban đầu nhanh chóng và rất nhiều tài nguyên của bạn trong dự án khi theo dõi các lỗi và sự thiếu hiệu quả liên quan đến ORM. Tôi cũng ghét thực tế rằng nó dường như cung cấp cho các nhà phát triển ý tưởng rằng họ không bao giờ phải viết các truy vấn tối ưu hóa cụ thể.
Eelco

7
Này, điều này có đúng với các dự án lớn trong đời thực không?
santiagobasulto

30
Tôi đồng ý. Tôi đã sử dụng ORM được hơn 3 năm và tôi không thể biết mình đã lãng phí bao nhiêu thời gian để giải quyết các vấn đề liên quan. Chúng tôi không kiểm soát được bất cứ điều gì đang xảy ra "dưới mui xe", cấu hình có quá nhiều để được quản lý hiệu quả và có những hành vi có thể khiến một người phát điên. Mặt khác, tôi có hỗ trợ cho các cơ sở dữ liệu lớn và không bao giờ phải lo lắng về sự khác biệt của chúng.
marcolopes

58
Tại sao không sử dụng cả hai, tùy thuộc vào độ phức tạp của truy vấn / giao dịch? không giống như họ là loại trừ lẫn nhau.
lưỡng cư

6
@WillSheppard có Sẽ. Tôi sử dụng Django ORM khá nhiều và nó hoạt động rất tốt. Tôi nghĩ rằng sự khác biệt có thể là bản chất năng động của python (và perl). Sử dụng ORM trong Java là một nỗi đau. Nhưng trong các ngôn ngữ năng động, nó có thể thực sự biểu cảm. Có một số dự án tuyệt vời để nhúng các hoạt động ORM như DSL trong Python và rất tuyệt.
santiagobasulto

97

Không, bởi vì có ORM sẽ mất quá nhiều quyền kiểm soát với những lợi ích nhỏ. Tiết kiệm thời gian thu được dễ dàng bị thổi bay khi bạn phải gỡ lỗi bất thường do sử dụng ORM. Hơn nữa, các ORM không khuyến khích các nhà phát triển học SQL và cách các cơ sở dữ liệu quan hệ hoạt động và sử dụng điều này vì lợi ích của họ.


4
Tôi đồng ý với câu nói này. Bao nhiêu từ tổng thời gian phát triển sẽ được tiêu thụ bằng cách viết mã kiên trì? Tôi nghĩ rằng ít hơn 10-15%
adrian.tarau

16
Nó phụ thuộc. Chắc chắn, nếu bạn đang sử dụng chỉ một loại cơ sở dữ liệu cụ thể, thật dễ dàng để không sử dụng ORM. Tuy nhiên, khi bạn cần hỗ trợ các loại cơ sở dữ liệu khác, nó có thể nhanh chóng trở nên ít quản lý hơn.
Jason Baker

3
"Tiết kiệm thời gian thu được dễ dàng bị thổi bay khi bạn phải gỡ lỗi những bất thường do sử dụng ORM" Điều này không đúng khi đường cong kỹ năng là một yếu tố hợp lý khi lựa chọn công nghệ.
elsadek

7
Đối số của bạn có thể được cung cấp chống lại việc sử dụng bất kỳ thư viện. Lợi ích lớn nhất của ORM là những thứ như đơn vị công việc, lập bản đồ đối tượng, theo dõi thay đổi, tải lười biếng, di chuyển và các mối quan hệ. Thật là một điều tuyệt vời khi có thể viết user.profile.givenName và không quan tâm đến cấu trúc nào đã được sử dụng để lưu trữ dữ liệu cho nó.
Alex

1
Nó có thể được sử dụng để chống lại bất kỳ thư viện, nhưng ở mức độ khác nhau. Nói chung tôi là một người ủng hộ tuyệt vời của việc sử dụng các thư viện - tại sao lại phát minh lại bánh xe? Tuy nhiên, trong trường hợp này tôi cảm thấy rằng Hibernate dành cho hầu hết các mục đích sử dụng trọng lượng quá nặng và một ORM nhẹ hơn sẽ được ưa chuộng hơn. Kinh nghiệm của tôi dựa trên nhiều năm kinh nghiệm phát triển với Hibernate và tìm hiểu kỹ về nó.
simon

92

Nhiều ORM rất tuyệt, bạn cần biết lý do tại sao bạn muốn thêm tính trừu tượng lên trên JDBC. Tôi có thể giới thiệu http://www.jooq.org cho bạn (từ chối trách nhiệm: Tôi là người tạo ra jOOQ, vì vậy câu trả lời này là sai lệch). JOOQ chấp nhận mô hình sau:

  • SQL là một điều tốt. Nhiều thứ có thể được thể hiện khá độc đáo trong SQL. Không cần trừu tượng hóa hoàn toàn SQL.
  • Mô hình dữ liệu quan hệ là một điều tốt. Nó đã chứng minh mô hình dữ liệu tốt nhất trong 40 năm qua. Không cần cơ sở dữ liệu XML hoặc các mô hình dữ liệu hướng đối tượng thực sự. Thay vào đó, công ty của bạn chạy một số phiên bản của Oracle, MySQL, MSSQL, DB2 hoặc bất kỳ RDBMS nào khác.
  • SQL có cấu trúc và cú pháp. Không nên biểu thị bằng cách sử dụng nối chuỗi "mức độ thấp" trong JDBC - hoặc nối chuỗi "mức cao" trong HQL - cả hai đều dễ bị lỗi cú pháp.
  • Liên kết biến có xu hướng rất phức tạp khi xử lý các truy vấn chính. THAT là một cái gì đó nên được trừu tượng hóa.
  • POJO là tuyệt vời khi viết mã Java thao tác dữ liệu cơ sở dữ liệu.
  • POJO là một nỗi đau để viết và duy trì bằng tay. Tạo mã là con đường để đi. Bạn sẽ có các truy vấn biên dịch an toàn bao gồm cả kiểu dữ liệu an toàn.
  • Cơ sở dữ liệu đến trước. Mặc dù ứng dụng trên cơ sở dữ liệu của bạn có thể thay đổi theo thời gian, nhưng cơ sở dữ liệu có thể sẽ tồn tại lâu hơn.
  • Có, bạn có các thủ tục được lưu trữ và các loại do người dùng xác định (UDT's) trong cơ sở dữ liệu cũ của bạn. Công cụ cơ sở dữ liệu của bạn sẽ hỗ trợ điều đó.

Có nhiều ORM tốt khác. Đặc biệt Hibernate hoặc iBATIS có một cộng đồng tuyệt vời. Nhưng nếu bạn đang tìm kiếm một thứ trực quan, đơn giản, tôi sẽ nói hãy thử jOOQ. Bạn sẽ yêu nó! :-)

Hãy xem ví dụ SQL này:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

Và làm thế nào nó có thể được thể hiện trong jOOQ:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

1
Các công cụ ORM tuyệt vời như bạn quản lý để sử dụng chúng đúng cách. Có những dự án mà các công cụ ORM hoạt động như một bùa mê, trong khi ở những dự án khác, chúng không phù hợp chút nào. Cuối cùng, trách nhiệm của nhóm phát triển là chọn công cụ phù hợp với yêu cầu dự án của họ. Các công cụ ORM rất phức tạp. Thật không may, chỉ một phần của tất cả các nhà phát triển sẽ dành thời gian để hiểu cách họ làm việc. Phần còn lại sẽ đổ lỗi cho công cụ và nói rằng nó xấu. Câu hỏi là: Câu trả lời được đánh giá cao nhất có đưa ra lời khuyên tốt nhất không? > Vì vậy, hãy xem xét chỉ sử dụng gói JDBC. Chúng ta có thực sự muốn sử dụng JDBC đơn giản không?
Vlad Mihalcea

Tôi cố gắng không để "Cơ sở dữ liệu đến trước.". Một ứng dụng chứa các quy tắc kinh doanh cho các tính năng mà khách hàng yêu cầu và họ hầu như không bao giờ yêu cầu tạo cơ sở dữ liệu. Đó là một chi tiết kỹ thuật được xác định trong quá trình thực hiện.
Kwebble

58

Hibernate, vì về cơ bản, nó là tiêu chuẩn defacto trong Java và là một trong những động lực trong việc tạo ra JPA. Nó có sự hỗ trợ tuyệt vời trong Spring và hầu như mọi khung công tác Java đều hỗ trợ nó. Cuối cùng, GORM là một trình bao bọc thực sự thú vị xung quanh nó đang thực hiện các công cụ tìm động và tiếp tục sử dụng Groovy.

Nó thậm chí còn được chuyển sang .NET (NHibernate) để bạn cũng có thể sử dụng nó ở đó.


4
Tôi bỏ phiếu Hib quá, nhưng với một sự bổ sung quan trọng: chúng ta nên sử dụng JPA API chỉ ngay cả khi thực hiện JPA là trong thực tế được cung cấp bởi Hib.
Vladimir Dyuzhev

52

Ngủ đông, bởi vì nó:

  • ổn định - tồn tại rất nhiều năm, nó không có vấn đề gì lớn
  • ra lệnh cho các tiêu chuẩn trong trường ORM
  • thực hiện tiêu chuẩn (JPA), ngoài việc ra lệnh.
  • có hàng tấn thông tin về nó trên Internet. Có nhiều hướng dẫn, giải pháp cho vấn đề chung, v.v.
  • là mạnh mẽ - bạn có thể dịch một mô hình đối tượng rất phức tạp thành một mô hình quan hệ.
  • nó có hỗ trợ cho bất kỳ RDBMS lớn và vừa
  • rất dễ làm việc, một khi bạn học tốt

Một vài điểm về lý do tại sao (và khi nào) sử dụng ORM:

  • bạn làm việc với các đối tượng trong hệ thống của bạn (nếu hệ thống của bạn đã được thiết kế tốt). Ngay cả khi sử dụng JDBC, cuối cùng bạn cũng sẽ tạo một số lớp dịch, để bạn chuyển dữ liệu của mình sang các đối tượng. Nhưng cá cược của tôi là ngủ đông tốt hơn dịch thuật hơn bất kỳ giải pháp tùy chỉnh nào.
  • nó không làm bạn mất kiểm soát. Bạn có thể kiểm soát mọi thứ với các chi tiết rất nhỏ và nếu API không có một số tính năng từ xa - thực hiện truy vấn gốc và bạn có nó.
  • bất kỳ hệ thống cỡ trung bình hoặc lớn hơn đều không thể có một tấn truy vấn (có thể ở một nơi hoặc nằm rải rác), nếu mục tiêu đó có thể duy trì được
  • nếu hiệu suất không quan trọng. Hibernate thêm chi phí hiệu suất, trong một số trường hợp không thể bỏ qua.

Khi tôi so sánh Hibernate và JPA, tôi chọn Hibernate và nếu so sánh JPA và JDO, tôi sẽ chọn JDO! Tôi rất thích JDO, nhưng tôi yêu hai tính năng của Hibernate (không có trong JDO), một là @Filters và hai là bạn có thể ánh xạ các trường phiên bản (để khóa tối ưu) vào các trường bình thường, điều này không thể có trong JDO .
Amir Pashazadeh

27

Tôi khuyên bạn nên sử dụng MyBatis . Nó là một lớp mỏng trên đầu JDBC, rất dễ dàng ánh xạ các đối tượng vào các bảng và vẫn sử dụng SQL đơn giản, mọi thứ đều nằm trong tầm kiểm soát của bạn.


10
Ibatis cho các lần đọc phức tạp và ngủ đông để tạo, cập nhật xóa và đọc đơn giản là sự lựa chọn hoàn hảo.
darpet

19

Tôi đã có trải nghiệm thực sự tốt với Avaje Ebean khi tôi đang viết một ứng dụng JavaSE cỡ trung bình.

Nó sử dụng các chú thích JPA tiêu chuẩn để xác định các thực thể, nhưng hiển thị API đơn giản hơn nhiều (Không có EntityManager hoặc bất kỳ thực thể nào được đính kèm / tách rời đó). Nó cũng cho phép bạn dễ dàng sử dụng các truy vấn SQL hoặc các cuộc gọi JDBC đơn giản khi cần thiết.

Nó cũng có API chất lỏng và loại an toàn rất tốt cho các truy vấn. Bạn có thể viết những thứ như:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

6
Tôi phải hơi kỳ lạ một chút ... chọn từ Người có giới tính = 'M' và tuổi <18 được đặt hàng bởi FirstName trông có vẻ tốt hơn nhiều đối với tôi :-)
Eelco

4
Đây là một trong những orms tốt hơn tôi từng thấy trong java. Quyết định sử dụng một singleton được làm mới và mang lại cho nó một lợi thế thực tế lớn so với những người khác.
opsb

Tôi nghĩ bạn có nghĩa là thông thạo không chất lỏng.
Montdidier

@opsb Tôi nghĩ về mặt kỹ thuật đó là một đơn vị, không phải là một đơn.
Montdidier

Làm thế nào để bắt đầu với Avaje Ebean ORM? Bất kỳ video hướng dẫn ??
Avinash

11

SimpleORM , bởi vì nó đơn giản và không có phép thuật. Nó định nghĩa tất cả các cấu trúc dữ liệu meta trong mã Java và rất linh hoạt.

SimpleORM cung cấp chức năng tương tự như Hibernate bằng cách ánh xạ dữ liệu trong cơ sở dữ liệu quan hệ đến các đối tượng Java trong bộ nhớ. Các truy vấn có thể được chỉ định theo các đối tượng Java, danh tính đối tượng được căn chỉnh với các khóa cơ sở dữ liệu, các mối quan hệ giữa các đối tượng được duy trì và các đối tượng được sửa đổi sẽ tự động được chuyển đến cơ sở dữ liệu với các khóa tối ưu.

Nhưng không giống như Hibernate, SimpleORM sử dụng cấu trúc và kiến ​​trúc đối tượng rất đơn giản, tránh sự cần thiết phải phân tích cú pháp phức tạp, xử lý mã byte, v.v. SimpleORM nhỏ và trong suốt, được đóng gói trong hai lọ có kích thước chỉ 79K và 52K, chỉ có một nhỏ và tùy chọn phụ thuộc (Slf4j). (Hibernate có hơn 2400K cộng với khoảng 2000K lọ phụ thuộc.) Điều này giúp SimpleORM dễ hiểu và do đó giảm đáng kể rủi ro kỹ thuật.


Không sử dụng nó, nhưng ActiveObjects mô tả chính nó như là một loại Hibernate-lite trên trang web của họ, vì vậy có lẽ có một số điểm tương đồng.
Abdullah Jibaly

10

Liên kết Eclipse , vì nhiều lý do, nhưng đáng chú ý là tôi cảm thấy như nó có ít sự phình to hơn các giải pháp luồng chính khác (ít nhất là ít phình ra trên khuôn mặt của bạn).

Liên kết Oh và Eclipse đã được chọn là triển khai tham chiếu cho JPA 2.0


5

Trong khi tôi chia sẻ các mối quan tâm về việc thay thế Java cho các truy vấn SQL dạng tự do, tôi thực sự nghĩ rằng mọi người chỉ trích ORM đang làm như vậy vì thiết kế ứng dụng thường kém.

True OOD được điều khiển bởi các lớp và các mối quan hệ và ORM cung cấp cho bạn ánh xạ nhất quán của các loại mối quan hệ và đối tượng khác nhau. Nếu bạn sử dụng công cụ ORM và kết thúc các biểu thức truy vấn mã hóa bằng bất kỳ ngôn ngữ truy vấn nào, khung ORM hỗ trợ (bao gồm, nhưng không giới hạn ở các cây biểu thức Java, phương thức truy vấn, OQL, v.v.), bạn chắc chắn đang làm gì đó sai, ví dụ như mô hình lớp của bạn rất có thể không hỗ trợ các yêu cầu của bạn theo cách nó nên. Một thiết kế ứng dụng sạch không thực sự cần truy vấn ở cấp ứng dụng. Tôi đã tái cấu trúc nhiều dự án, mọi người bắt đầu sử dụng khung ORM theo cách tương tự như chúng được sử dụng để nhúng các hằng chuỗi SQL trong mã của họ, và cuối cùng mọi người đều ngạc nhiên về việc toàn bộ ứng dụng có thể duy trì được như thế nào khi bạn khớp mô hình lớp học của bạn với mô hình sử dụng. Cấp, đối với những thứ như chức năng tìm kiếm, v.v. bạn cần một ngôn ngữ truy vấn, nhưng ngay cả khi đó các truy vấn bị hạn chế rất nhiều đến mức tạo ra một VIEW thậm chí phức tạp để duy trì và nhìn vào lớp bền vững chỉ đọc sẽ tốt hơn nhiều so với việc xây dựng các biểu thức trong một số ngôn ngữ truy vấn trong mã ứng dụng của bạn. Cách tiếp cận VIEW cũng tận dụng các khả năng của cơ sở dữ liệu và, thông qua việc cụ thể hóa, có thể hiệu quả hơn nhiều so với bất kỳ SQL viết tay nào trong nguồn Java của bạn. Vì vậy, tôi không thấy bất kỳ lý do nào cho một ứng dụng không tầm thường KHÔNG sử dụng ORM. nhưng ngay cả các truy vấn sau đó bị hạn chế rất nhiều đến mức tạo ra một VIEW thậm chí phức tạp đến mức một lớp liên tục chỉ đọc sẽ dễ duy trì và xem xét hơn so với việc xây dựng các biểu thức trong một số ngôn ngữ truy vấn trong mã ứng dụng của bạn. Cách tiếp cận VIEW cũng tận dụng các khả năng của cơ sở dữ liệu và, thông qua việc cụ thể hóa, có thể hiệu quả hơn nhiều so với bất kỳ SQL viết tay nào trong nguồn Java của bạn. Vì vậy, tôi không thấy bất kỳ lý do nào cho một ứng dụng không tầm thường KHÔNG sử dụng ORM. nhưng ngay cả các truy vấn sau đó bị hạn chế rất nhiều đến mức tạo ra một VIEW thậm chí phức tạp đến mức một lớp liên tục chỉ đọc sẽ dễ duy trì và xem xét hơn so với việc xây dựng các biểu thức trong một số ngôn ngữ truy vấn trong mã ứng dụng của bạn. Cách tiếp cận VIEW cũng tận dụng các khả năng của cơ sở dữ liệu và, thông qua việc cụ thể hóa, có thể hiệu quả hơn nhiều so với bất kỳ SQL viết tay nào trong nguồn Java của bạn. Vì vậy, tôi không thấy bất kỳ lý do nào cho một ứng dụng không tầm thường KHÔNG sử dụng ORM.


11
Nếu bạn đang xây dựng các ứng dụng trên một cửa hàng liên tục, giống như nhiều người trong chúng ta, cho dù đó là RDBMS hay một số hương vị NoQuery, thì cửa hàng đó sẽ có cách truy cập hiệu quả của riêng nó. Cố gắng trừu tượng từ đó quá nhiều chỉ là quá mức. Quá nhiệt tình về 'Căn hộ thực sự' khiến những kiến ​​trúc phi hành gia Java nổi tiếng là khét tiếng.
Eelco
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.