Tại sao tôi không cần ORM bằng ngôn ngữ chức năng như Scala?


30

Tôi tự hỏi liệu tôi có thể chuyển từ Java sang Scala trong dự án Spring + Hibernate để tận dụng một số tính năng của Scala như khớp mẫu, Tùy chọn và nói chung với tôi một cú pháp rõ ràng hơn. Tôi đã tìm kiếm ORM theo mặc định trong hệ sinh thái Scala và tôi thấy tôi nghĩ giống như Kích hoạt (nhưng chủ yếu tôi cố gắng tìm xem Hibernate có thể được sử dụng với Scala không). Tìm kiếm điều này Tôi đã đọc điều này trong tài liệu Play về JPA + Scala.

Nhưng điểm quan trọng nhất là: bạn có thực sự cần một người lập bản đồ Relationnal to Object khi bạn có sức mạnh của ngôn ngữ chức năng không? Chắc là không. JPA là một cách thuận tiện để trừu tượng hóa sự thiếu sức mạnh của Java trong chuyển đổi dữ liệu, nhưng nó thực sự cảm thấy sai khi bạn bắt đầu sử dụng nó từ Scala.

Tôi không hiểu sâu về cách sử dụng lập trình chức năng để tạo một ứng dụng hoàn chỉnh (đó là lý do tại sao tôi có ý định sử dụng Scala để tôi có thể hiểu điều này dần dần, vì nó kết hợp OO + Functional), vì vậy tôi không thể hiểu được tại sao tôi không cần ORM với ngôn ngữ chức năng và đâu là cách tiếp cận chức năng để giải quyết sự bền bỉ của mô hình miền.

Một cách tiếp cận DDD cho logic kinh doanh vẫn có ý nghĩa với Scala, phải không?


3
Đây là một câu hỏi dựa trên ý kiến. Scala không hoàn toàn là chức năng, nó cũng là ngôn ngữ OO, vì vậy điều đó sẽ giải thích lý do tại sao bạn vẫn muốn sử dụng công cụ ORM. Đối với ánh xạ DB, xem ví dụ: Slick , SORM , Anorm .
Jesper

Tôi không tìm kiếm một ý kiến, tôi đang hỏi một điều gì đó với sự hiểu biết sâu sắc về mô hình chức năng, cách thức để đạt được sự kiên trì là gì. Tôi biết rằng Scala là một hybrid và tôi muốn sử dụng phần OO của nó cho DDD. Vì vậy, bạn nói rằng nếu tôi thực hiện một cách tiếp cận DDD ngay cả với Scala, ORM là cách để đi?
gabrielgiussi

Trong các ngôn ngữ chức năng, bạn chủ yếu xử lý các giá trị không có danh tính như các đối tượng. Do đó, bạn không cần theo dõi thay đổi, một trong những công việc chính của ORM.
Lee


5
Bạn không cần ORM bằng bất kỳ ngôn ngữ chính nào .
GrandmasterB

Câu trả lời:


30

Chà, một điều quan trọng cần làm mỗi khi chúng ta có một cuộc thảo luận như thế này là phân biệt rõ ràng giữa các trình ánh xạ quan hệ đối tượng ("ORM") và các lớp trừu tượng hóa cơ sở dữ liệu . ORM là một loại lớp trừu tượng hóa cơ sở dữ liệu, nhưng không phải tất cả các lớp trừu tượng hóa cơ sở dữ liệu đều là ORM. Một công cụ tốt để nghiên cứu để nắm bắt điều này là thư viện SQLAlchemy nổi tiếng của Python , tự quảng cáo là "Bộ công cụ SQL và Bản đồ quan hệ đối tượng" (phần chữ đậm của tôi), với ý tưởng rằng đây là những thứ khác nhau. Khi họ đặt nó trong trang tính năng chính của họ :

Không cần ORM

SQLAlchemy bao gồm hai thành phần riêng biệt, được gọi là CoreORM . Core tự nó là một bộ công cụ trừu tượng SQL đầy đủ tính năng, cung cấp một lớp trừu tượng trơn tru trên nhiều cách thực hiện và hành vi DBAPI, cũng như Ngôn ngữ biểu thức SQL cho phép biểu hiện ngôn ngữ SQL thông qua các biểu thức Python tổng quát. Một hệ thống biểu diễn lược đồ vừa có thể phát ra các câu lệnh DDL cũng như xem xét các lược đồ hiện có và một hệ thống loại cho phép mọi ánh xạ các loại Python thành các loại cơ sở dữ liệu, làm tròn hệ thống. Object Mapper Mapper sau đó là một gói tùy chọn xây dựng trên Core.

Trang đầu mô tả ORM như thế này:

SQLAlchemy nổi tiếng nhất với trình ánh xạ quan hệ đối tượng (ORM), một thành phần tùy chọn cung cấp mẫu trình ánh xạ dữ liệu, trong đó các lớp có thể được ánh xạ tới cơ sở dữ liệu ở dạng kết thúc mở, nhiều cách - cho phép mô hình đối tượng và lược đồ cơ sở dữ liệu phát triển theo cách tách sạch ngay từ đầu.

Ý tưởng chính của ORM là thử và kết nối sự không phù hợp trở kháng quan hệ đối tượng nổi tiếng . Điều này có nghĩa là xác định mối quan hệ giữa các lớp do người dùng định nghĩa với các bảng trong lược đồ cơ sở dữ liệu và cung cấp các hoạt động "lưu" và "tải" tự động cho các lớp của ứng dụng của bạn.

Ngược lại, các lớp trừu tượng hóa cơ sở dữ liệu không phải ORM có xu hướng cam kết nhiều hơn với mô hình dữ liệu quan hệ và SQL, và hoàn toàn không hướng đến đối tượng. Vì vậy, thay vì làm nổi bật "ánh xạ" giữa các bảng và các lớp và ẩn lược đồ cơ sở dữ liệu khỏi lập trình viên, họ có xu hướng hiển thị cơ sở dữ liệu cho lập trình viên nhưng với các API và trừu tượng tốt hơn. Ví dụ: các trình tạo truy vấn SQL cho phép bạn tạo các truy vấn SQL phức tạp theo chương trình, không cần thao tác chuỗi, như thế này ( một ví dụ từ thư viện jOOQ cho 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();

Bây giờ, khung Play dường như không liên kết 100% với những gì tôi vừa mô tả , nhưng đối số của chúng dường như nằm trong không gian chung này: làm việc trực tiếp với mô hình quan hệ thay vì dịch nó sang các lớp và quay lại từ chúng.

Các thư viện jOOQ là giá trị nghiên cứu như một đối trọng ORMs. Họ cũng có một số mục blog có liên quan đáng để đọc:


19

Thật khó để giải thích cho đến khi bạn thực hiện nhiều chương trình chức năng. Trong lập trình hướng đối tượng, dữ liệu của bạn bị kẹt trong một đối tượng và ở đó. Đối tượng đó được truyền qua một chút và sửa đổi khá nhiều, nhưng về cơ bản, bạn thường làm việc với cùng một "danh tính" trong suốt thời gian tồn tại của dữ liệu đó.

Các ORM thường được thiết kế xung quanh mô hình đó. Bạn lấy một số dữ liệu từ cơ sở dữ liệu, chuyển dữ liệu vào một đối tượng, có khả năng sửa đổi nó thành một bó và khi bạn hoàn thành, bạn vẫn có cùng một đối tượng bạn có thể ghi lại vào cơ sở dữ liệu.

Lập trình chức năng hoạt động khác nhau. Dữ liệu của bạn không duy trì một danh tính duy nhất trong suốt cuộc đời của nó. Nó được chia ra, sao chép, chia sẻ và chuyển đổi. Nó sắp xếp các luồng thông qua một loạt các hàm, sau đó cuối cùng được ghép lại thành dạng đầu ra mà bạn cần. Để bất kỳ API cơ sở dữ liệu nào cảm thấy tự nhiên trong ngôn ngữ chức năng, nó phải tính đến điều đó và JPA thì không.


1
+1000 Những người khăng khăng sử dụng Scala như thể là Java ++ khiến tôi lo sợ cho tương lai của ngôn ngữ :(
Andres F.

9

Trong scala, vẫn hữu ích khi ánh xạ các bảng cơ sở dữ liệu tới các đối tượng và có một số cách để thực hiện nó.

Một khuôn khổ phổ biến trong thế giới của Scala là lắt léo . Nó không phải là ORM, vì nó ít hơn (cụ thể là, nó không tìm nạp các mối quan hệ mà không được yêu cầu tham gia một cách rõ ràng).

Vì vậy, bạn vẫn ánh xạ các đối tượng vào các hàng cơ sở dữ liệu, nhưng các đối tượng của bạn là bất biến, (do đó không có trạng thái lộn xộn) và bạn thực hiện rõ ràng các truy vấn bằng cách sử dụng DSL đơn sắc. Kết quả là bạn nhận được rất nhiều phần "tốt" của ORM mà không gặp phải các vấn đề xoay quanh khả năng biến đổi và các vấn đề N + 1 không thể đoán trước.

Mọi người nên lưu ý rằng mọi người đã đạt được thành công lớn khi sử dụng các thư viện mỏng hơn nhiều, như anorm hoặc JDBC thẳng, sử dụng các kỹ thuật chức năng để giữ cho mã đẹp.

Một thư viện tuyệt vời áp dụng các kỹ thuật chức năng trên JDBC cũng là doobie .

Vì vậy, bạn có rất nhiều sự lựa chọn để truy cập cơ sở dữ liệu, nhưng Hibernate (dường như là ORM trên thực tế) không phải là một trong những lựa chọn tốt nhất, do thiên về khả năng biến đổi.


0

Bạn không cần ORM ngay cả trong các ngôn ngữ hướng đối tượng.

Đầu tiên, ai nói rằng dữ liệu của bạn nên được sao chép từ bộ lưu trữ liên tục vào đối tượng của bạn? Alan Kay , một người đàn ông đằng sau Smalltalk, muốn các đối tượng thoát khỏi dữ liệu . Ông cho rằng một đối tượng chỉ có thể có một tham chiếu đến một khu vực nơi dữ liệu của nó được lưu trữ.

Thứ hai - cách tốt nhất để đạt được điều đó là gì? Tôi khuyên bạn nên xác định đối tượng của mình bằng trách nhiệm của họ và không nghĩ về dữ liệu họ sở hữu. Nếu bạn đã nghe về cách tiếp cận thẻ CRC, nó được sử dụng chính xác cho điều đó.

Và cuối cùng, chỉ trong trường hợp bạn sẽ quay lại trường OO, đây là một cách để thực hiện nó .

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.