Чому мені не потрібна ОРМ на такій функціональній мові, як Scala?


30

Мені цікаво, чи зможу я перейти з Java на Scala у проекті Spring + Hiber, щоб скористатися деякими функціями Scala, такими як відповідність шаблонів, Варіант та те, що мені здається чистішим синтаксисом загалом. Я шукав ORM за замовчуванням в екосистемі Scala і знайшов такі думки, як Activate (але в основному я намагаюся знайти, чи може Hibernate використовуватися зі Scala). Шукаючи це, я прочитав це в документації Play про JPA + Scala.

Але найважливіший момент: чи справді вам потрібен картограф "Відносини до об'єктів", коли у вас є сила функціональної мови? Напевно, ні. JPA - це зручний спосіб абстрагувати відсутність потужності Java в трансформації даних, але вона справді відчуває себе неправильно, коли ви починаєте використовувати її від Scala.

У мене немає глибокого розуміння того, як використовувати функціональне програмування для створення повної програми (саме тому я маю намір використовувати Scala, щоб я міг зрозуміти це поступово, оскільки він поєднує OO + Functional), тому не можу зрозуміти чому мені не потрібна ОРМ з функціональною мовою та яким би був функціональний підхід для вирішення стійкості доменної моделі.

Підхід DDD до бізнес-логіки все ще має сенс у Scala, чи не так?


3
Це питання, засноване на думці. Scala не є суто функціональною, вона також є мовою ОО, тому це пояснить, чому ви все ще хочете використовувати інструмент ORM. Для відображення БД, дивись, наприклад: Slick , СОРМ , Anorm .
Jesper

Я не шукаю думки, я прошу щось із глибоким розумінням функціональної парадигми, яким є шлях досягнення наполегливості. Я знаю, що Scala - це гібрид, і я хочу використовувати його OO частину для DDD. Так ви кажете, що якщо я застосую DDD-підхід навіть із Scala, ORM - це шлях?
gabrielgiussi

У функціональних мовах ви в основному маєте справу зі значеннями, які не мають ідентичності як об'єкти. Тому вам не потрібно відстеження змін, яке є одним з основних завдань ORM.
Лі


5
Вам не потрібна ОРМ жодною основною мовою.
гросмайстерB

Відповіді:


30

Щось, що важливо робити, коли ми маємо дискусію, як це - чітко розмежувати між об'єктними реляційними картографами ("ORM") та шарами абстракції бази даних . ORM - це різновид шару абстрагування бази даних, але не всі шари абстракції бази даних є ОРМ. Хорошим інструментом для вивчення цього є популярна бібліотека SQLAlchemy Python, яка вважає себе "інструментарієм SQL та об'єктивним реляційним картографом" (мій жирний шрифт) з думкою, що це різні речі. Як вони розміщують це на своїй сторінці основних функцій :

Не потрібно ORM

SQLAlchemy складається з двох різних компонентів, відомих як Core і ORM . Core є самим повнофункціональним інструментарієм абстракції SQL, що забезпечує гладкий шар абстрагування для широкого спектру реалізацій та поведінки DBAPI, а також мову експресії SQL, яка дозволяє виражати мову SQL за допомогою генеративних виразів Python. Система подання схем, яка може випромінювати оператори DDL, а також самоаналіз існуючих схем, і система типів, яка дозволяє будь-яке відображення типів Python на типи баз даних, округляє систему. Обліковий реляційний Mapper - це необов'язковий пакет, який базується на ядрі.

На головній сторінці описано ОРМ так:

SQLAlchemy є найвідомішим своїм об'єктно-реляційним картографом (ORM), необов'язковим компонентом, який забезпечує схему відображення даних, де класи можуть бути перенесені в базу даних відкритим способом декількома способами - дозволяючи моделю об'єкта та схемі бази даних розвиватися в чисто розв'язаний шлях від початку.

Ключова ідея ОРМ полягає в тому, щоб спробувати усунути відому невідповідність об'єктно-реляційного опору . Це означає визначення взаємозв'язку між визначеними користувачем класами до таблиць у схемі бази даних та надання автоматичних операцій "збереження" та "завантаження" для класів вашої програми.

На відміну від цього, шари абстракції баз даних, що не належать до ORM, як правило, більш прихильні до реляційної моделі даних та до SQL, а зовсім не до об'єктно-орієнтованої. Таким чином, замість того, щоб відображати "відображення" між таблицями та класами і ховати схему бази даних від програміста, вони, як правило, піддають базу даних програмісту, але з кращими API та абстракціями. Наприклад, конструктори запитів 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();

Тепер, начебто , система Play не відповідає 100% того, що я описав , але їх аргумент, здається, знаходиться в цьому загальному просторі: працюйте з реляційною моделлю безпосередньо замість того, щоб перекладати її на класи та назад від них.

Бібліотеку jOOQ варто вивчити як контрапункт ORM. У них також є відповідні записи в блозі, які варто прочитати:


19

Це важко пояснити, поки ви не зробили багато функціонального програмування. У об'єктно-орієнтованому програмуванні ваші дані начебто застрягли в одному об’єкті і залишаються там. Цей об'єкт трохи проходить і змінюється, але ви, як правило, працюєте з тією самою "ідентичністю" протягом життя цих даних.

ORM, як правило, розроблені навколо цієї парадигми. Ви отримуєте деякі дані з бази даних, з’єднуєте їх з об'єктом, потенційно виправляєте їх, і коли ви закінчите, у вас ще є той самий об'єкт, який ви можете записати назад у базу даних.

Функціональне програмування працює по-різному. Ваші дані не зберігають єдиної ідентичності протягом свого життя. Він розбивається, копіюється, ділиться та перетворюється. Він начебто протікає через купу функцій, а згодом знову збирається у потрібну форму виводу. Щоб будь-який API бази даних відчував себе природним у функціональній мові, він повинен це враховувати, а JPA - ні.


1
+1000 людей, які наполягають на використанні Scala, ніби Java ++, змушують мене боятися за майбутнє мови :(
Андрес Ф.

9

У масштабі все ще корисно зіставляти таблиці баз даних на об’єкти, і існує кілька способів це зробити.

Один з популярних рамок у світі Scala - це гладкий . Це не ОРМ, тому що вона робить менше (а саме, не виходить стосунків, не кажучи явно робити приєднання).

Таким чином, ви все ще відображаєте об'єкти у рядках баз даних, але ваші об'єкти незмінні (отже, немає розмивання стану), і ви явно виконуєте запити, використовуючи монадійний DSL. У результаті ви отримуєте багато "хороших" частин ОРМ без проблем навколо змінності та непередбачуваних N + 1 проблем.

Слід зазначити, що люди досягли великого успіху, використовуючи набагато тонші бібліотеки, як, наприклад, anorm або прямий JDBC, використовуючи функціональні методи для збереження красивого коду.

Одна фантастична бібліотека, яка застосовує функціональні методи на вершині JDBC, також doobie .

Таким чином, у вас є багато варіантів доступу до бази даних, але сплячий режим (який, здається, є фактичним ORM), не є одним з найкращих, через те, що він є упередженим щодо змінності.


0

ORM вам не потрібен навіть на об'єктно-орієнтованих мовах.

По-перше, хто сказав, що ваші дані мають бути фізично скопійовані з постійного сховища на ваш об’єкт? Алан Кей , людина, що стоїть за Smalltalk, хотів, щоб об’єкти позбулися даних . Він припустив, що об’єкт може мати лише посилання на деяку область, де зберігаються його дані.

По-друге - який найкращий спосіб досягти цього? Я рекомендую визначити ваші об'єкти за їх відповідальністю , а не думати про дані, якими вони володіють. Якщо ви чули про підхід до карт CRC, він використовується саме для цього.

І, нарешті, на всякий випадок, якщо ви коли-небудь повернетесь до OO-поля, ось спосіб його реалізації .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.