Подтвердить что ты не робот

Ближайший эквивалент SQLAlchemy для Java/Scala

Как кто-то, незнакомый с Python, я часто слышал много отзывов за SQLAlchemy. Поэтому я хотел бы понять:

  • Что он предлагает по сравнению с "конструкторами SQL типа", такими как jOOQ или QueryDSL?

  • Есть ли близкие эквиваленты к нему в Java (или Scala) мире? Я видел Apache Empire-DB, упомянутый в этом отношении...

4b9b3361

Ответ 1

Одна из примечательных особенностей SQLAlchemy заключается в том, что она делает таблицы объектами первого класса. Таким образом, базовый API действительно написан вокруг объектов таблицы, и поэтому API по существу носит реляционный характер. Таким образом, на этом уровне, даже если API является OO, он по существу отражает объекты или функции RDBMS, такие как таблицы, столбцы, отношения, соединения, псевдонимы и т.д. На этом уровне SQLAlchemy дает вам по существу OOSQL, где SQL и реляционные базы данных не предоставляются второй класс лечения. Кроме того, при этом SQLAlchemy действительно сияет, поскольку этот уровень абстракции дает вам возможность свести к минимуму "сырой" реляционный уровень и, таким образом, получить огромную гибкость, и я действительно не видел никакого другого предложения ORM. Интересно, что некоторые из базовых возможностей, которые необходимы для моделирования наследования классов в ORM, реализованы на этом уровне, например. Наследование наследуемых таблиц http://docs.sqlalchemy.org/en/rel_0_7/orm/inheritance.html#joined-table-inheritance

API, который чаще всего используется (по крайней мере в последнее время), - это декларативный API, который на самом деле намного больше OO и сопоставляет объекты в бизнес-домене с объектами, о которых я упоминал выше (в большинстве случаев прозрачно). Здесь, где реализована функциональность ORM, и API немного больше похож на другие API ORM, где один работает с объектами домена, и эти действия напрямую преобразуются в основные действия таблицы.

Насколько я знаю, ORM в Scala все еще играют в догоняющую способность к тому, что легко доступно в Java (например, наследование), даже если они предлагают другие возможности (например, безопасность типов, LINQ-подобные конструкции) даже когда они борются с некоторыми серьезными проблемами, такими как 22 ограничения столбцов. (Я читал комментарии, где мало кто задавался вопросом, почему кому-то понадобится больше 22 столбцов, и, по крайней мере, в моем опыте есть ситуации, которые я бы не назвал редкостью, где нужно многократно).

ORM в Scala (даже если они используют другой вкус от Java), я думаю, все еще догоняют то, что требуется. Что касается SQLAlchemy, есть ли достаточно близкий эквивалент, который я видел на Java или Scala? Я не видел.

EDIT: Я забыл добавить, что даже если вы используете декларативный API, SQLAlchemy по-прежнему дает вам прямой доступ к базовым объектам. Поэтому, если "класс Foo" отображается декларативно, Foo.__ table__ - это объект таблицы, который вы можете использовать напрямую, если хотите.

Ответ 2

Squeryl обеспечивает композицию, подобную той, о которой они говорят в "SQLALCHEMY PHILOSOPHY" на домашней странице библиотек. Вы можете запросить запрос.

val query = from(table)(t => where(t.a === 1) select(t))
val composed = from(query)(q => where(q.b === 2) select(q))

Он также разделяет значительную часть философии дизайна, прежде всего потому, что когда все усложняется, библиотека должна "уйти с дороги" и позволить разработчику самостоятельно настраивать вещи. Хотя Squeryl делает сопоставление объектов, я рассматриваю его скорее как DSL, чем ORM.

Некоторые функции, от которых он не делится, быстро просматривают список функций SQLAlchemy:

  • Возможность использования raw SQL - трудно найти что-либо в стандартном ANSI SQL, который не может быть выражен.
  • Наследование - это личное мнение здесь, но я думаю, что когда библиотека делает это, это часто нарушает принцип "уйти с пути".

Конечно, Squeryl также предлагает то, что я считаю основной особенностью, которую не может использовать библиотека Python, которая проверяет компилятор типа безопасности ваших запросов.

Ответ 3

ScalaQuery (см. примечание о "пятне" внизу) может сделать простую:

for{
  a <- Article
  if a.dateCreated between(start, end)
  _ <- Query groupBy a.reporterID orderBy a.dateCreated.desc
} yield(a)

или сколь угодно сложным по составу:

val team = for{
  t <- Team
  s <- School if t.schoolID is s.id 
} yield (t,s)

val player = for{
  r <- Roster
  p <- Player if r.playerID is p.id
} yield (r, p)

val playerDetail = for{
  (r, p) <- player
} yield (p.id, p.firstName, p.lastName, r.jerseyID, r.position, r.gamesPlayed)

val scoring = for{
  (r, p) <- player
  s <- Scoring if p.id is s.playerID
  detail <- playerDetail 
} yield (r, p, s, detail)

val scoringDetail = for{
  (r, p, s, detail) <- scoring
  val (total, goals, assists) = 
    (s.playerID.count, s.goal.sum, (s.assist1.sum + s.assist2.sum))
  val ppg = (s.playerID.count / r.gamesPlayed)
} yield (goals, assists, total, ppg)

Здесь, как получить статистику команды (можно изменить для просмотра в лиге или в одиночном режиме):

val forScoring = for{
  start ~ end ~ teamID <- Parameters[JodaTime,JodaTime,Int]
  (r,p,s,player) <- scoring if r.teamID is teamID
  comp <- bindDate(start, end) if s.gameID is comp.id
  (goals, assists, total, ppg) <- scoringDetail
  _ <- Query groupBy p.id orderBy ( ppg.desc, total.asc, goals.desc )
} yield (player, goals, assists, total, ppg)

def getScoring(start: JodaTime, end: JodaTime, id: Int): List[TeamScoring] = {
  forScoring(start, end, id).list
}

Я не думал, что можно было бы генерировать строго типизированные сложные запросы в Scala, и смирился с тем, чтобы просто портировать проверенный и правильный ручной SQL; то есть до тех пор, пока я не наткнулся на ScalaQuery, который был откровением, очень похожим на язык Scala.

Во всяком случае, у вас есть опции, Squeryl может быть в большей степени совместим с SQL Alchemy, не знаю, немного изучите, вы, вероятно, не будете разочарованы, есть так много предложений Scala, это сложно не чувствовать головокружение здесь, сейчас и после; -)

p.s. отличный разговор Zeiger и Vogt в Scala Days Skills Вопросы по SLICK, следующая эволюция ScalaQuery

Ответ 4

Вы также можете использовать Slick, который недавно был добавлен в стек типов.

Ответ 5

ActiveJDBC

Это реализация Java шаблона проектирования "Active Record". Он был вдохновлен ActiveRecord ORM от Ruby on Rails. Это может соответствовать вашим потребностям.

https://code.google.com/p/activejdbc/

или

JDBI

Библиотека удобства SQL для Java. Он пытается выявить доступ к реляционным базам данных в идиоматической Java, используя коллекции, beans и т.д., Сохраняя тот же уровень детализации, что и JDBC.

http://jdbi.org