MyBatis. Когда использовать. Преимущества и недостатки
От: Aleksei_Lekomtsev  
Дата: 19.02.24 11:07
Оценка:
Добрый день. Попробовал Hibernate и MyBatis
MyBatis позволяет писать свои SQL запросы. В тоже время если использовать Spring Data and Query, то можно писать native queries или JPQL с Hibernate
springframework hibernate
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: Pavel Dvorkin Россия  
Дата: 19.02.24 11:47
Оценка: 2 (1)
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

A_L>Добрый день. Попробовал Hibernate и MyBatis

A_L>MyBatis позволяет писать свои SQL запросы. В тоже время если использовать Spring Data and Query, то можно писать native queries или JPQL с Hibernate

MyBatis почти ничего не дает в плане INSERT/UPDATE/DELETE. Все придется писать вручную. Только SELECT он умеет маппить на классы
Кроме того, в нем нет механизма отслеживания изменений в классе или в коллекции. Если сделал изменения — выполни сохранение/изменение сам.

Это его недостатки и в то же время достоинства. Ты будешь писать SQL сам и можешь сделать это эффективно.

В Hibernate обычно сами SQL не пишут, поручают фреймворку. Так что SQL не всегда будет наиболее эффективным. Можно, конечно, перейти на нативные запросы или JPQL, да, но это будет его использование "не как принято", и обычно без особых причин это не делают.
With best regards
Pavel Dvorkin
Re: MyBatis. Когда использовать.
От: GarryIV  
Дата: 19.02.24 21:52
Оценка:
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

Никогда
WBR, Igor Evgrafov
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 20.02.24 10:06
Оценка: 1 (1)
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

A_L>MyBatis позволяет писать свои SQL запросы.


Позволяет — это если бы была альтернатива. С MyBatis нужно писать свои SQL запросы.

A_L>В тоже время если использовать Spring Data and Query, то можно писать native queries или JPQL с Hibernate


Народ пишет, что Hibernate медленнее и нужно долго сложно настраивать и подкручивать, чтобы приблизиться по скорости.
MyBatis — это некие примочки над JDBC и особо ничего лишнего вроде не добавляет, т.е. по логике действительно должен быть достаточно быстрым.
Я не проверял и не так, чтобы усиленно в целом в Java мире находился.
Сверху спустили мне MyBatis и пришлось немного поработать.
Мне в нём удобно то, что SQL-запросы выносятся отдельно в xml файлики.
Spring Data вроде только атрибуты типа @Query умеет или в java-коде.
MyBatis тоже атрибуты умеет, но по-моему это неудобно.
Что мне относительно удобно было в MyBatis — это компоновка SQL-запроса.
В примерах везде константы иду типа:
@Query("update person set first_name = :firstName, last_name = :lastName where id = :id")
Мне было нужно апдейтить только то, что заполнено, т.е. не null.
В MyBatis это вылилось во что-то вроде:
<update id="updatePerson">
  update person
  <set>
    <if test="firstName">first_name = #{firstName}</if>
    <if test="lastName">last_name = #{lastName}</if>
  </set>
  where id = #{id}
</update>

Если я не ошибаюсь, то в Spring Data и Hibernate подобное решается не очень изящно и нужно городить какие-то новые классы и сбоку прикручивать.
Простым атрибутом там не отделаться.
Я не понимаю почему они нормальный синтаксис не сделали, банально массив для запроса с IN прибиндить нельзя и приходится цикл <foreach> писать в xml.
На голом JDBC больно сидеть, MyBatis всё же поудобнее.
Если устраивает то, что генерирует Hibernate и нет массы сложных запросов, которые выпадают из общего кода, то и не понятно зачем самому с MyBatis типовые CRUD писать.
Если нужно или хочется самому sql весь прописывать, то в принципе жить с MyBatis можно, но как-то всё криво и неудобно по-моему в итоге.
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: r0nd  
Дата: 20.02.24 11:50
Оценка: 3 (1)
On Feb 19, 2024, 2:07 PM, Aleksei_Lekomtsev <114506@users.rsdn.org> wrote:

AL>Добрый день. Попробовал Hibernate и MyBatis

AL>MyBatis позволяет писать свои SQL запросы. В тоже время если использовать Spring Data and Query, то можно писать native queries или JPQL с Hibernate

MyBatis имеет только два «преимущества»:
  1. Позволяет возвращать множественные ResultSet (Hibernate этого не может делать) — я в курсе что это плохая практика, но к сожалению она не искореняема;
  2. MyBatis позволяет делать модели вокруг ResultSet (то есть намного ниже уровень чем Hibernate/ORM), в hibernate придется описывать такие гибридные модели, иногда это не просто (например в случае с отсутствием ключей в них, либо с вычисляемыми ключами через SP). Таким образом если корпоративная логика приложения написана на основе множества SP (Stored Procedures), то написать код аналогичный «относительно простенькому» в MyBatis на Hibernate под силу скилловому программисту (обычно только ведущие инженеры).

Я предпочитаю Hibernate, только по одной причине — мне он больше нравится. Мне нравится комьюнити, зрелость библиотеки, поддержка его, (моя в том числе) база знаний, он лучше интегрируется с Spring/Java EE.

Когда использовать MyBatis?

IMHO, найти проблему в MyBatis гораздо сложнее, чем туже в Hibernate. Все эти не очевидные mappers, каждый слой в виде XML/моделей/секций трансформаций и биндинга — она иногда сводит с ума. И в больших продуктах (>100К CLOC) это ведет к большой неразберихи. Hibernate в этом плане проще.
...<< Dementor 1.6.1 ✪ Lets Play a Game ⚀⚀⚂⚃⚄>>
Re[2]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 20.02.24 13:09
Оценка:
Здравствуйте, r0nd, Вы писали:

R>IMHO, найти проблему в MyBatis гораздо сложнее, чем туже в Hibernate. Все эти не очевидные mappers, каждый слой в виде XML/моделей/секций трансформаций и биндинга — она иногда сводит с ума. И в больших продуктах (>100К CLOC) это ведет к большой неразберихи. Hibernate в этом плане проще.


По-моему наоборот. В MyBatis сам запросы пишешь, никаких отслеживания состояний объектов и т.п. Hibernate под капотом куда больше магии делает.
MyBatis же скажет какой xml упал на какой строке или откуда куда конвертация не сработала в каком запросе.
Некоторые вещи удивляют, костылями приходится что-то решать, но именно локализация проблемы в MyBatis достаточно просто делается.
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: scf  
Дата: 20.02.24 17:52
Оценка:
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

A_L>MyBatis позволяет писать свои SQL запросы. В тоже время если использовать Spring Data and Query, то можно писать native queries или JPQL с Hibernate


Я бы сказал, что MyBatis окончательно и бесповоротно устарел. Программирование в XML давно признано плохой практикой, а сделать селект с prepared statement с преобразованием в объект несложно через spring data или аналогичный самописный враппер:

List<MyModel> results = conn.query("select id, a, b, c from MyTable where id=:id and a=:a")
.set("id", id)
.set("a", a)
.list()
.map(this::toModel)
Re[2]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 20.02.24 19:41
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> <if test="firstName">first_name = #{firstName}</if>

Жуть, программирование на XML.
Я давно с базами не общался, но в своё время querydsl приглянулся больше всего. Смотрели?
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 20.02.24 19:48
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>В MyBatis это вылилось во что-то вроде:

K>
K><update id="updatePerson">
K>  update person
K>  <set>
K>    <if test="firstName">first_name = #{firstName}</if>
K>    <if test="lastName">last_name = #{lastName}</if>
K>  </set>
K>  where id = #{id}
K></update>
K>


где мои 20 лет
вы еще спринг через xml попробуйте
WBR, Igor Evgrafov
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 20.02.24 19:49
Оценка:
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

A_L>MyBatis позволяет писать свои SQL запросы.

Может jOOQ а?
WBR, Igor Evgrafov
Re[2]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 20.02.24 21:02
Оценка:
Здравствуйте, scf, Вы писали:

scf>List<MyModel> results = conn.query("select id, a, b, c from MyTable where id=:id and a=:a")

scf> .set("id", id)
scf> .set("a", a)
scf> .list()
scf> .map(this::toModel)

С MyBatis будет в интерфейсе маппера объявлен метод вида:
List<MyModel> getItems(long id, String a);

и сам запрос в xml:
<select id="getItems">
  select id, a, b, c from MyTable where id=#{id} and a=#{a}
</select>

Можно и без выноса в xml, в маппере аттрибут навесить:
@Select("select id, a, b, c from MyTable where id=#{id} and a=#{a}")
List<MyModel> getItems(long id, String a);

Не вижу тут никаких проблем с MyBatis в плане синтаксиса и xml
Re[3]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 20.02.24 21:15
Оценка:
Здравствуйте, ·, Вы писали:

·>Жуть, программирование на XML.

·>Я давно с базами не общался, но в своё время querydsl приглянулся больше всего. Смотрели?

Ну, MyBatis не был моим выбором и не скажу, что в восторге.
Удивило, что в Java среди популярных библиотек вот такие поделки со странными решениями и проблемами.
QueryDSL и подобное видел, но не могу сказать, что и такой подход нравится.
И SQL писать не люблю и при переименовании колонок везде лазить по запросам их переименовывать — сомнительное удовольствие.
С другой стороны можно спокойно SQL в соответствующих инструментах писать, отлаживать и потом вставить в этот XML,
поправив передачу параметров и добавив какие-то xml конструкции, если нужно какие-то проверки и обработки добавить.
Это всё же разные подходы и кому что нравится.
Re[3]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 20.02.24 21:21
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>где мои 20 лет

GIV>вы еще спринг через xml попробуйте

Я тут Helm с его Go template пробую.
Не сказал бы, что далеко от xml ушло, но конечно угловые скобки — это древний отстой, а фигурные скобки — стильно, модно, молодёжно.
Не знаю уж почему выстреливают какие-то сомнительные по удобству инструменты.
Re[4]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 25.02.24 22:57
Оценка:
Здравствуйте, karbofos42, Вы писали:

GIV>>вы еще спринг через xml попробуйте

K>Я тут Helm с его Go template пробую.

Хрен редьки не слаще. Я за Infrastructure as code (IaC) есличо в том виде как он сделан в AWS CDK например.
Но это епархия девопсов, там свои так сказать "наработки".
WBR, Igor Evgrafov
Re[3]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 25.02.24 23:12
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>@Select("select id, a, b, c from MyTable where id=#{id} and a=#{a}")

запросы в строчке (константной). Удобно, безопасно, современно.
Но да уже не 20 а 15 летней давности подход.

ЗЫЖ Есть же jOOQ, нормальный Java/Kotlin код, типобезопасно, компайл тайм проверки и тд. В апдейты умеет, в r2dbc.
WBR, Igor Evgrafov
Re[4]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 26.02.24 06:45
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>запросы в строчке (константной). Удобно, безопасно, современно.


Неудобно и не безопасно, а когда запросы сложные и объёмные, то и вовсе Mapper'ы превратятся в кашу.

GIV>ЗЫЖ Есть же jOOQ, нормальный Java/Kotlin код, типобезопасно, компайл тайм проверки и тд. В апдейты умеет, в r2dbc.


Jooq не пробовал, типобезопасность и проверки — это хорошо, но синтаксис у него сомнителен в плане удобства и в итоге пишешь тот же SQL не на языке SQL.
Если какой-то сложный запрос, то нужно сначала его писать на SQL, отлаживать, а потом транслировать его в jooq.
Те примеры, что я видел на jooq — не сказал бы, что было приятно читать запросы. Даже SQL приятнее как-то.
LINQ в .NET выглядит куда лучше.
Re[5]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 26.02.24 07:18
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Те примеры, что я видел на jooq — не сказал бы, что было приятно читать запросы. Даже SQL приятнее как-то.

Убераргумент, ну неприятно так неприятно.

K>LINQ в .NET выглядит куда лучше.

Linq то выглядит норм (не использовал) но у нас про жабу.
WBR, Igor Evgrafov
Re[4]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 26.02.24 12:23
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>·>Жуть, программирование на XML.

K>·>Я давно с базами не общался, но в своё время querydsl приглянулся больше всего. Смотрели?
K>Ну, MyBatis не был моим выбором и не скажу, что в восторге.
K>Удивило, что в Java среди популярных библиотек вот такие поделки со странными решениями и проблемами.
Ну это просто легаси из проектов ~прошлого века. В java много такого, старинные кодовые базы .

K>QueryDSL и подобное видел, но не могу сказать, что и такой подход нравится.

Пишешь код не на кривом SQL, а обычный java-код с компайл-тайм проверками, автодополнением и т.п.

K>И SQL писать не люблю и при переименовании колонок везде лазить по запросам их переименовывать — сомнительное удовольствие.

Так в этом и суть, что у тебя java-код, где работают авто-рефакторинги.

K>С другой стороны можно спокойно SQL в соответствующих инструментах писать, отлаживать и потом вставить в этот XML,

В топку "соответствующие инструменты" и отладка. Пишешь java-код с тестами, а не простыни XML.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 26.02.24 21:53
Оценка:
Здравствуйте, ·, Вы писали:

·>Пишешь код не на кривом SQL, а обычный java-код с компайл-тайм проверками, автодополнением и т.п.


Вместо кривого SQL пишешь на кривом Java, который старается повторять этот самый SQL.
В итоге пишешь на чём-то промежуточном. Знаешь как что-то сделать на Java, но нужно это как-то иначе записать, как принято в этой библиотеке, чтобы она смогла запись транслировать в SQL.
Либо наоборот знаешь как на SQL сделать, но нужно разбираться как сделать на этой обёртке.

·>В топку "соответствующие инструменты" и отладка. Пишешь java-код с тестами, а не простыни XML.


Так не получится. Всё равно нужно следить за генерируемыми запросами, анализировать как они исполняются в СУБД, какие индексы используются или нужны и т.д. и т.п.
Чисто на Java сидеть и делать вид, что нет СУБД со своим специфическим SQL не получится.
Рано или поздно придётся начать следить за всем этим добром и подкручивать.
Re[6]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 26.02.24 23:06
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> ·>Пишешь код не на кривом SQL, а обычный java-код с компайл-тайм проверками, автодополнением и т.п.

k> Вместо кривого SQL пишешь на кривом Java, который старается повторять этот самый SQL.
Цель — компилируемый высокоурвневый яп, со строгой типизацией, автодополнением, етс.
Ещё, SQL — очень плохо композится. Т.е. какой-то динамический запрос в sql собираемый из кусочков — жуть, нужен билдер запросов.

k> В итоге пишешь на чём-то промежуточном. Знаешь как что-то сделать на Java, но нужно это как-то иначе записать, как принято в этой библиотеке, чтобы она смогла запись транслировать в SQL.

k> Либо наоборот знаешь как на SQL сделать, но нужно разбираться как сделать на этой обёртке.
Пиши сразу на Java.

k> ·>В топку "соответствующие инструменты" и отладка. Пишешь java-код с тестами, а не простыни XML.

k> Так не получится. Всё равно нужно следить за генерируемыми запросами, анализировать как они исполняются в СУБД, какие индексы используются или нужны и т.д. и т.п.
k> Чисто на Java сидеть и делать вид, что нет СУБД со своим специфическим SQL не получится.
k> Рано или поздно придётся начать следить за всем этим добром и подкручивать.
Ну это уже отладка и оптимизация. Ровно так же приходится смотреть на байткод, машкоды, етс. Но это не повод писать с ассемблерными вставками.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[7]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 26.02.24 23:32
Оценка:
Здравствуйте, ·, Вы писали:

·>Цель — компилируемый высокоурвневый яп, со строгой типизацией, автодополнением, етс.


Это не цель, а вариант решения проблем.
Для SQL автодополнение вполне себе имеется в большинстве инструментов для БД.
Типизация там тоже имеется.
Собственно, все эти ORM решают задачу передачи данных между SQL и Java.

·>Ещё, SQL — очень плохо композится. Т.е. какой-то динамический запрос в sql собираемый из кусочков — жуть, нужен билдер запросов.


Он в целом по-моему дурацкий.

·>Пиши сразу на Java.


Ну, вот заходишь посмотреть что такое тот же QueryDSL, а там примеры типа:
List<Person> persons = queryFactory.selectFrom(person)
  .where(person.children.size().eq(
    JPAExpressions.select(parent.children.size().max())
                  .from(parent)))
  .fetch();

Вроде Java, а вроде как-то странный SQL.
Если бы person был List<Person>, а не сущность в БД, то код отбора элементов выглядел бы явно иначе.

·>Ну это уже отладка и оптимизация. Ровно так же приходится смотреть на байткод, машкоды, етс. Но это не повод писать с ассемблерными вставками.


Ни разу не приходилось опускаться до байткодов и баловаться с ассемблерными вставками.
Вот со всякими библиотеками бывали истории, когда народ особо не задумывался над происходящим, писал на компилируемых типизированных языках что-то и оно даже работало.
Только потом оказывается, что на каждый чих выкачивается вся таблица или для каждой записи создаётся новый объект справочника, а не переиспользуются одни и те же объекты.
Как бы ни хотелось не иметь дела с SQL, а по-моему как-то лучше за ним следить и перепроверять во что там это всё объектное добро компилируется и что фактически запрашивается в БД.
Re[8]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 27.02.24 00:00
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> ·>Цель — компилируемый высокоурвневый яп, со строгой типизацией, автодополнением, етс.

k> Это не цель, а вариант решения проблем.
k> Для SQL автодополнение вполне себе имеется в большинстве инструментов для БД.
k> Типизация там тоже имеется.
k> Собственно, все эти ORM решают задачу передачи данных между SQL и Java.
ORM — это Object-Relation Mapping. Т.е. маппинг между объектной моделью и реляционной. querydsl — это query builder. Т.е. построитель запросов. Совершенно другой зверь.

k> ·>Ещё, SQL — очень плохо композится. Т.е. какой-то динамический запрос в sql собираемый из кусочков — жуть, нужен билдер запросов.

k> Он в целом по-моему дурацкий.
Кто он?

k> ·>Пиши сразу на Java.

k> Ну, вот заходишь посмотреть что такое тот же QueryDSL, а там примеры типа:
k>
k> List<Person> persons = queryFactory.selectFrom(person)
k>   .where(person.children.size().eq(
k>     JPAExpressions.select(parent.children.size().max())
k>                   .from(parent)))
k>   .fetch();
k>

k> Вроде Java, а вроде как-то странный SQL.
k> Если бы person был List<Person>, а не сущность в БД, то код отбора элементов выглядел бы явно иначе.
Это вроде для JDOQL, не?

k> ·>Ну это уже отладка и оптимизация. Ровно так же приходится смотреть на байткод, машкоды, етс. Но это не повод писать с ассемблерными вставками.

k> Ни разу не приходилось опускаться до байткодов и баловаться с ассемблерными вставками.
Повезло.

k> Вот со всякими библиотеками бывали истории, когда народ особо не задумывался над происходящим, писал на компилируемых типизированных языках что-то и оно даже работало.

k> Только потом оказывается, что на каждый чих выкачивается вся таблица или для каждой записи создаётся новый объект справочника, а не переиспользуются одни и те же объекты.
Ну так и с обычным кодом бывает.

k> Как бы ни хотелось не иметь дела с SQL, а по-моему как-то лучше за ним следить и перепроверять во что там это всё объектное добро компилируется и что фактически запрашивается в БД.

Ну насколько я помню, в querydsl видно генерируемый запрос.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: MyBatis. Когда использовать. Преимущества и недостатки
От: vsb Казахстан  
Дата: 27.02.24 00:42
Оценка: +1
Использовал в одном проекте, минусов не заметил. Думаю, что можно всегда использовать.

Из минусов — в SQL надо экранировать <, >, это раздражает.

В целом — мне пока больше всего по душе то, что в последнем helidon сделали. По сути человеческая обертка над JDBC. SQLException-ы убрали, вместо ResultSet-а — Stream. Но пока не применял это на практике, так что про минусы сказать ничего не могу, но впечатления хорошие.

ORM-ы типа Hibernate — индустриальный стандарт, но мне они не нравятся.
Отредактировано 27.02.2024 0:49 vsb . Предыдущая версия . Еще …
Отредактировано 27.02.2024 0:48 vsb . Предыдущая версия .
Отредактировано 27.02.2024 0:47 vsb . Предыдущая версия .
Отредактировано 27.02.2024 0:44 vsb . Предыдущая версия .
Re[9]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 27.02.24 08:12
Оценка:
Здравствуйте, ·, Вы писали:

·>ORM — это Object-Relation Mapping. Т.е. маппинг между объектной моделью и реляционной. querydsl — это query builder. Т.е. построитель запросов. Совершенно другой зверь.


Ну, маппинг реляционных данных на объекты там тоже есть. Официально себя называют ORM наверно только Hibernate.
Как по мне, так и MyBatis и JOOQ и всё остальное тоже можно записать в ORM.

·>Кто он?


SQL

·>Это вроде для JDOQL, не?


Это с главной страницы https://querydsl.com/

·>Ну насколько я помню, в querydsl видно генерируемый запрос.


Генерируемый запрос везде можно посмотреть. Вопрос в том, что проще уже отладить SQL-запрос в профильных инструментах и скопировать в проект на Java.
Чем метаться на сложных запросах туда-сюда и перегонять код из SQL в Java и наоборот.
Если в проекте много сложных запросов, то может быть сильно проще пихать SQL, а не эти компилируемые обёртки с типобезопасностью.
У обоих подходов свои плюсы и минусы, не считаю, что тот же MyBatis априори плох и не нужно его использовать.
Нужно просто взвешивать плюсы и минусы и выбирать что больше нравится и подходит.
Re[10]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 27.02.24 09:37
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> Ну, маппинг реляционных данных на объекты там тоже есть. Официально себя называют ORM наверно только Hibernate.

k> Как по мне, так и MyBatis и JOOQ и всё остальное тоже можно записать в ORM.
Если я не ошибаюсь, то собственно маппинг в querydsl опциональный. Его можно использовать именно как построитель запросов, а потом хоть голый jdbc используй.

k> ·>Кто он?

k> SQL
А куда деваться с подводной лодки...

k> ·>Это вроде для JDOQL, не?

k> Это с главной страницы https://querydsl.com/
Ну у querydsl есть несколько моделей, в т.ч. и JDO, и SQL и JPA и даже Mongo. Вот тут конкретно по sql: http://querydsl.com/static/querydsl/latest/reference/html/ch02s03.html
Тут тебе и CTE, и window, весь фарш.

k> ·>Ну насколько я помню, в querydsl видно генерируемый запрос.

k> Генерируемый запрос везде можно посмотреть. Вопрос в том, что проще уже отладить SQL-запрос в профильных инструментах и скопировать в проект на Java.
k> Чем метаться на сложных запросах туда-сюда и перегонять код из SQL в Java и наоборот.
Ну в этом и суть, что метаться не обязательно. И отлаживать в коде теста сразу.

k> Если в проекте много сложных запросов, то может быть сильно проще пихать SQL, а не эти компилируемые обёртки с типобезопасностью.

k> У обоих подходов свои плюсы и минусы, не считаю, что тот же MyBatis априори плох и не нужно его использовать.
Там XML. Это априори плохо.

Вот на этот код я сагрился:

<if test="firstName">first_name = #{firstName}</if>

И это тривиальнейший случай. А если тебе для условного добавления поля нужен ещё и join или подзапрос — вешайся.

k> Нужно просто взвешивать плюсы и минусы и выбирать что больше нравится и подходит.

А у тебя не будет кучи сложных запросов и метания. Запросы сложные можно собирать из простых частей. Опускаться до уровня грязного SQL придётся только при хардкорной оптимизации, как и с ассемблером.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[11]: MyBatis. Когда использовать. Преимущества и недостатки
От: Aleksei_Lekomtsev  
Дата: 27.02.24 10:32
Оценка:
·>Если я не ошибаюсь, то собственно маппинг в querydsl опциональный. Его можно использовать именно как построитель запросов, а потом хоть голый jdbc используй.

Можно использовать Spring Data and Query анотацию и писать native queries

·>И это тривиальнейший случай. А если тебе для условного добавления поля нужен ещё и join или подзапрос — вешайся.

Для join можно использовать association в resultMap
Re[12]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 27.02.24 10:53
Оценка:
Здравствуйте, Aleksei_Lekomtsev, Вы писали:

AL> ·>Если я не ошибаюсь, то собственно маппинг в querydsl опциональный. Его можно использовать именно как построитель запросов, а потом хоть голый jdbc используй.

AL> Можно использовать Spring Data and Query анотацию и писать native queries
Писать код аннотациями ничем не лучше, чем XML-ем.

AL> ·>И это тривиальнейший случай. А если тебе для условного добавления поля нужен ещё и join или подзапрос — вешайся.

AL> Для join можно использовать association в resultMap
Не очень понял. Вот такой пример. Нужно выбрать людей по разным критериям. Например, по имени, postcode и/или строчке адреса. Две таблички Person и Address
Нужно сгенерировать восемь разных запросов!
select p.* from Person p;

select p.* from Person p 
where p.name = :name;

select p.* from Person p join Address a on (a.id=p.addressId) 
where a.postcode = :postcode;

select p.* from Person p join Address a on (a.id=p.addressId) 
where a.line = :line;

select p.* from Person p join Address a on (a.id=p.addressId) 
where a.postcode = :postcode and a.line = :line;
... и т.д.

на java такое написать гораздо проще, чем на xml или аннотациях.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[13]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 29.02.24 07:07
Оценка:
Здравствуйте, ·, Вы писали:

·>на java такое написать гораздо проще, чем на xml или аннотациях.


В xml можно изобразить что-то вроде:
<select id="getPersons">
  select p.* from Person p
  <if test="addressId != null or line != null or postcode != null">
    join Address a on (a.id=p.addressId)
  </if>
  <where>
    <if test="name">p.name = #{name}</if>
    <if test="postcode">and a.postcode = #{postcode}</if>
    <if test="line">and a.line = #{line}</if>
  </where>
</select>

Можно пример на Java, где это будет сделано гораздо проще?
Re[14]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 29.02.24 07:46
Оценка: 2 (1)
K>В xml можно изобразить что-то вроде:
K>
K><select id="getPersons">
K>  select p.* from Person p
K>  <if test="addressId != null or line != null or postcode != null">
K>    join Address a on (a.id=p.addressId)
K>  </if>
K>  <where>
K>    <if test="name">p.name = #{name}</if>
K>    <if test="postcode">and a.postcode = #{postcode}</if>
K>    <if test="line">and a.line = #{line}</if>
K>  </where>
K></select>
K>

K>Можно пример на Java, где это будет сделано гораздо проще?

На котлине (что то jOOQ образное)
 selectFrom(Person) //address джойнится автоматом если надо
  .where(
    Person.name.eqIfNotNull(name),
    Person.address.postcode.eqIfNotNull(postcode),
    Person.address.line.eqIfNotNull(line),
  )
WBR, Igor Evgrafov
Re[14]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 29.02.24 13:18
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> ·>на java такое написать гораздо проще, чем на xml или аннотациях.

k> В xml можно изобразить что-то вроде:
k> <if test="name">p.name = #{name}</if>
k> <if test="postcode">and a.postcode = #{postcode}</if>
Вот ты и попался. У тебя тут бага — если name==null, то у тебя сгенерится лишний "and".
Попробуй-ка теперь багу исправить, посмеёмся, потом поплачем.

k> Можно пример на Java, где это будет сделано гораздо проще?

Давно я не брал в руку шашку... Вариант проще показали, но если тебе нужен чистый sql, то как-то так у меня получилось:
    private static SQLQuery<Person> makeQuery(SQLQueryFactory queryFactory, String name, String postcode, String line) {
        var person = new QPerson("p");
        var address = new QAddress("a");
        var q = queryFactory
                .select(person)
                .from(person);
        if (name != null) {
            q.where(person.username.eq(name));
        }
        if (line != null) {
            q.join(person.addressFk, address);
            q.where(address.line.eq(line));
        }
        if (postcode != null) {
            q.join(person.addressFk, address);// да, дупликат join проигнорируется
            q.where(address.postcode.eq(postcode));
        }
        return q;
    }

Потом из SQLQuery можно извлечь готовый текст sql и массив байндингов.
Может можно упростить, но разбираться лень.
И заметь, это всё java-код — это можно рефакторить, разбивать на переиспользуемые функции, автодополнять, отлаживать и т.п.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[15]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 29.02.24 13:55
Оценка:
Здравствуйте, ·, Вы писали:

·>Вот ты и попался. У тебя тут бага — если name==null, то у тебя сгенерится лишний "and".

·>Попробуй-ка теперь багу исправить, посмеёмся, потом поплачем.

Бага была бы, если бы я написал where. У меня же он написан в виде xml элемента <where>.
MyBatis во всех этих <where>, <set> и т.п. отслеживает лишние запятые, and и удаляет из результирующего запроса.
Такие вот в нём костыли/фишки, так что исправлять ничего не нужно.

·>Давно я не брал в руку шашку... Вариант проще показали, но если тебе нужен чистый sql, то как-то так у меня получилось:


По-моему оно и пишется не очень удобно и понять результирующий запрос вот так по коду проблематично.

·>И заметь, это всё java-код — это можно рефакторить, разбивать на переиспользуемые функции, автодополнять, отлаживать и т.п.


java-код, в котором приходится писать: "q.where(address.line.eq(line))".
В C# я к подобному подходу лучше отношусь, т.к. там во всяких linq2db доступны обычные записи вида: "q.Where(a => a.Line == line)".
Синтаксически совершенно без разницы будет q — это таблица в БД или какой-то массив объектов.
В Java же сомнительные конструкции появляются, это всё усложняет и портит.
В целом такой подход мне не нравится следующим:
допустим я знаю SQL, знаю Java, а в итоге приходится отдельно разбираться как в этой библиотеке оформить cross join, как написать "where a and b or c" и т.д.
От SQL всё равно не уйдёшь и его читать придётся и следить за адекватностью генерируемых запросов.
Рефакторинг в итоге тоже не в 100% случаев защитит. В БД лишний раз не будешь колонки переименовывать или ещё какую мелочь делать, т.к. это относительно проблематично и лучше сидеть с кривым названием.
А вот если индексы поменяешь, добавишь колонку или какую-то колонку вынесешь в отдельную таблицу (например, раньше была монолитная строка адреса, а понадобилось брать его из КЛАДР и разбивать на составляющие), то тут и рефакторинг не так, чтобы сильно поможет.
Придётся ручками лезть в этот java код и переписывать запросы.
В MyBatis можно переиспользуемые блоки запросов тоже оформлять. Но тут я тоже не уверен, что стоит делать.
Отладка везде в итоге перейдёт к тому, что нужно смотреть какой запрос генерируется, какие в него параметры передаются и идти в СУБД этот запрос отлаживать.
В итоге сможешь разобраться какой SQL-запрос нужен, что в нём должно быть иначе, а дальше при помощи автодополнений и отладки будешь разбираться как его сгенерировать через удобную java-библиотеку.
Re[15]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 29.02.24 14:03
Оценка:
Здравствуйте, GarryIV, Вы писали:

GIV>На котлине (что то jOOQ образное)


джойны разных видов бывают, как и в where кроме and бывают or и вложенные запросы.
Если брать MyBatis, то там проще прикинуть какой SQL-запрос вызывается.
По этому коду на Java лично мне это сложнее понять, чем по кривому xml для MyBatis.
Суть происходящего конечно понятна и этот запрос в принципе простой, но и эти все конструкции с eqIfNotNull не могу назвать удобными для написания и чтения.
Re[16]: MyBatis. Когда использовать. Преимущества и недостатки
От: GarryIV  
Дата: 29.02.24 14:18
Оценка:
Здравствуйте, karbofos42, Вы писали:


GIV>>На котлине (что то jOOQ образное)


K>джойны разных видов бывают, как и в where кроме and бывают or и вложенные запросы.


если нравятся явные джойны — пишите, кто запрещает?
WBR, Igor Evgrafov
Re[16]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 29.02.24 21:52
Оценка:
Здравствуйте, karbofos42, Вы писали:

k> ·>Вот ты и попался. У тебя тут бага — если name==null, то у тебя сгенерится лишний "and".

k> ·>Попробуй-ка теперь багу исправить, посмеёмся, потом поплачем.
k> Бага была бы, если бы я написал where. У меня же он написан в виде xml элемента <where>.
k> MyBatis во всех этих <where>, <set> и т.п. отслеживает лишние запятые, and и удаляет из результирующего запроса.
k> Такие вот в нём костыли/фишки, так что исправлять ничего не нужно.
Мда уж, т.е. там всякие заковырки. Ещё один xml-based язык программирования.
Ещё недостаток, что условие добавления join и условие добавления в where — в разных частях. Легко забыть-перепутать. В java code это отдельный цельный блок кода.

k> ·>Давно я не брал в руку шашку... Вариант проще показали, но если тебе нужен чистый sql, то как-то так у меня получилось:

k> По-моему оно и пишется не очень удобно и понять результирующий запрос вот так по коду проблематично.
А оно действительно надо? Тебе не нужно видеть-понимать целый запрос, если ты его композируешь из небольших обозримых частей. Т.е.
if (line != null) {
  q.join(person.addressFk, address);
  q.where(address.line.eq(line));
}

ясно что делает. Зачем видеть что в результате это разместится в разные части результирующего запроса?
Вот это — неясно:
<if test="addressId != null or line != null or postcode != null">

Будет десяток таких полей, разных джойнов и код превращается в макароны.

k> ·>И заметь, это всё java-код — это можно рефакторить, разбивать на переиспользуемые функции, автодополнять, отлаживать и т.п.

k> java-код, в котором приходится писать: "q.where(address.line.eq(line))".
k> В C# я к подобному подходу лучше отношусь, т.к. там во всяких linq2db доступны обычные записи вида: "q.Where(a => a.Line == line)".
Дело вкуса, зато автодополнение работает/етс. В каких-нибудь скала-котлин можно и операторы замутить при желании.

k> Синтаксически совершенно без разницы будет q — это таблица в БД или какой-то массив объектов.

Честно говоря, хоть и звучит круто, но реальное практическое применение ещё поискать надо. Всё же работа с объектами в памяти принципиально отличается от работы с субд.

k> В Java же сомнительные конструкции появляются, это всё усложняет и портит.

k> В целом такой подход мне не нравится следующим:
k> допустим я знаю SQL, знаю Java, а в итоге приходится отдельно разбираться как в этой библиотеке оформить cross join, как написать "where a and b or c" и т.д.
Ну так ставишь . и смотришь на autocomplete, там всё показывается.
Что такое cross join я что-то забыл, но это вроде просто запятая в sql, не?
select ... from t1, t2, t3 => select(...).from(t1, t2, t3) или select(...).from(t1).from(t2).from(t3). Т.е. это всё дело получаса почитать доку, да поглядеть в исходники.

k> От SQL всё равно не уйдёшь и его читать придётся и следить за адекватностью генерируемых запросов.

Ну как часто ты следишь за адекватностью генерируемого байткода?..

k> Рефакторинг в итоге тоже не в 100% случаев защитит. В БД лишний раз не будешь колонки переименовывать или ещё какую мелочь делать, т.к. это относительно проблематично и лучше сидеть с кривым названием.

А что такого? В этом и суть — shift-f6 и всё. Если что-то где-то не так, будет ошибка компиляции.

k> А вот если индексы поменяешь, добавишь колонку или какую-то колонку вынесешь в отдельную таблицу (например, раньше была монолитная строка адреса, а понадобилось брать его из КЛАДР и разбивать на составляющие), то тут и рефакторинг не так, чтобы сильно поможет.

k> Придётся ручками лезть в этот java код и переписывать запросы.
Поможет отыскать где как во всём коде поля используются.

k> В MyBatis можно переиспользуемые блоки запросов тоже оформлять. Но тут я тоже не уверен, что стоит делать.

Вообще говоря вижу что есть org.mybatis.dynamic.sql.SqlBuilder
Но не пользовался, не знаю.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[17]: MyBatis. Когда использовать. Преимущества и недостатки
От: karbofos42 Россия  
Дата: 01.03.24 11:57
Оценка:
Здравствуйте, ·, Вы писали:

·>Мда уж, т.е. там всякие заковырки. Ещё один xml-based язык программирования.


Ничем не отличаются от заковырок в Java, когда join оказывается можно дублировать и это нормально обработается.

·>Ещё недостаток, что условие добавления join и условие добавления в where — в разных частях. Легко забыть-перепутать. В java code это отдельный цельный блок кода.


Забыть и перепутать можно и там и там. Вопрос кому что удобнее и как на конкретном инструменте конкретный код организован.
У меня вот таких дублирований проверок нет.

·>А оно действительно надо? Тебе не нужно видеть-понимать целый запрос, если ты его композируешь из небольших обозримых частей. Т.е.


Звучит как: зачем тебе доступ ко всем исходникам, вот отдельные методы, проверяй сиди, ищи ошибки, оптимизируй. Не нужно в комплексе на это добро смотреть.

·>ясно что делает. Зачем видеть что в результате это разместится в разные части результирующего запроса?


Мне нужно видеть, что где-то лишний join затесался в результате неоднократного переписывания и запрос стал делать много лишнего.

·>Вот это — неясно:

·>
<if test="addressId != null or line != null or postcode != null">

·>Будет десяток таких полей, разных джойнов и код превращается в макароны.

Вряд ли я напишу метод, который будет принимать десяток аргументов.
Там появится какой-то AddressFilter и запись превратится в:
<if test="addressFilter">join ... </if>


·>Честно говоря, хоть и звучит круто, но реальное практическое применение ещё поискать надо. Всё же работа с объектами в памяти принципиально отличается от работы с субд.


Ну, там скорее в минус идёт, что половина методов обработки коллекции преобразуется в SQL и отработает на стороне СУБД, а где-то по незнанию можно выкачать на клиент всю таблицу и фильтрацию делать на клиенте.

·>Ну так ставишь . и смотришь на autocomplete, там всё показывается.

·>Что такое cross join я что-то забыл, но это вроде просто запятая в sql, не?

Лет 10 как уже наверно не модно писать запятую и используют cross join.

·>select ... from t1, t2, t3 => select(...).from(t1, t2, t3) или select(...).from(t1).from(t2).from(t3). Т.е. это всё дело получаса почитать доку, да поглядеть в исходники.


В итоге и SQL не знаешь и на Java не нормально пишешь, а повторяешь всратый синтаксис SQL и во всём этом нужно разбираться.
Ещё и SQL условно стандартизирован, а тут совсем каждая библиотека специфична.

·>Ну как часто ты следишь за адекватностью генерируемого байткода?..


Причём тут байткод? SQL — это такой же высокоуровневый язык по сути своей.
В профилировщике Java или C# периодически сижу. И пошаговой отладкой занимаюсь и анализирую кто память жрёт, кто ресурсы процессора расходует зря.
Эта Java библиотека внутри Java даст мне возможность отлаживать запросы?
Планы выполнения покажет и не нужно доставать откуда-то сгенерированный SQL, лезть в программу для работы с БД и там уже анализировать и оптимизировать?

·>А что такого? В этом и суть — shift-f6 и всё. Если что-то где-то не так, будет ошибка компиляции.


Что такое shift-f6? Что всё?
Нажму кнопку и с БД колонка переименуется?
Или если я колонку в БД переименую, а в Java-коде — нет, то получу ошибку компиляции?

·>Поможет отыскать где как во всём коде поля используются.


Это немного жизнь упростит, но всё равно придётся многое перепроверять отдельно.

·>Вообще говоря вижу что есть org.mybatis.dynamic.sql.SqlBuilder

·>Но не пользовался, не знаю.

Видел. Какая-то бессмысленная фигня.
Re[18]: MyBatis. Когда использовать. Преимущества и недостатки
От: · Великобритания  
Дата: 01.03.24 14:27
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>·>Мда уж, т.е. там всякие заковырки. Ещё один xml-based язык программирования.

K>Ничем не отличаются от заковырок в Java, когда join оказывается можно дублировать и это нормально обработается.
Ну join можно и в sql дублировать с тем же эффектом практически.

K>·>Ещё недостаток, что условие добавления join и условие добавления в where — в разных частях. Легко забыть-перепутать. В java code это отдельный цельный блок кода.

K>Забыть и перепутать можно и там и там. Вопрос кому что удобнее и как на конкретном инструменте конкретный код организован.
K>У меня вот таких дублирований проверок нет.
В твоём xml условие "добавить join" логически оторвано от условия "добавить в where". В java-коде это одна и та же строчка кода, перепутать банально нечего.

K>·>А оно действительно надо? Тебе не нужно видеть-понимать целый запрос, если ты его композируешь из небольших обозримых частей. Т.е.

K>Звучит как: зачем тебе доступ ко всем исходникам, вот отдельные методы, проверяй сиди, ищи ошибки, оптимизируй. Не нужно в комплексе на это добро смотреть.
Не нужно, но ведь можно, если очень надо.

K>·>ясно что делает. Зачем видеть что в результате это разместится в разные части результирующего запроса?

K>Мне нужно видеть, что где-то лишний join затесался в результате неоднократного переписывания и запрос стал делать много лишнего.
Мелочи жизни.

K>·>Вот это — неясно:

K>·>
<if test="addressId != null or line != null or postcode != null">

K>·>Будет десяток таких полей, разных джойнов и код превращается в макароны.
K>Вряд ли я напишу метод, который будет принимать десяток аргументов.
K>Там появится какой-то AddressFilter и запись превратится в:
K>
K><if test="addressFilter">join ... </if>
K>

Да, можно наверное. Но это значит твои типы фильтров должны в точности повторять структуру таблиц и джойнов. Что далеко не всегда случается. Врочем, можно наверное завести ещё один промежуточный слой маппинга... брр.

K>·>Честно говоря, хоть и звучит круто, но реальное практическое применение ещё поискать надо. Всё же работа с объектами в памяти принципиально отличается от работы с субд.

K>Ну, там скорее в минус идёт, что половина методов обработки коллекции преобразуется в SQL и отработает на стороне СУБД, а где-то по незнанию можно выкачать на клиент всю таблицу и фильтрацию делать на клиенте.
Ну да... как в хибернейте, непредсказуемо.

K>·>Ну так ставишь . и смотришь на autocomplete, там всё показывается.

K>·>Что такое cross join я что-то забыл, но это вроде просто запятая в sql, не?
K>Лет 10 как уже наверно не модно писать запятую и используют cross join.
Хз, мелочи жизни имхо.

K>·>select ... from t1, t2, t3 => select(...).from(t1, t2, t3) или select(...).from(t1).from(t2).from(t3). Т.е. это всё дело получаса почитать доку, да поглядеть в исходники.

K>В итоге и SQL не знаешь и на Java не нормально пишешь, а повторяешь всратый синтаксис SQL и во всём этом нужно разбираться.
Ну как бы java довольно близко следует sql. Разница лишь в том, что вместо линейного текста sql строишь древовидную модель запроса.

K>·>Ну как часто ты следишь за адекватностью генерируемого байткода?..

K>Причём тут байткод? SQL — это такой же высокоуровневый язык по сути своей.
K>В профилировщике Java или C# периодически сижу. И пошаговой отладкой занимаюсь и анализирую кто память жрёт, кто ресурсы процессора расходует зря.
K>Эта Java библиотека внутри Java даст мне возможность отлаживать запросы?
Что значит "отлаживать"? Выполнить и заасертить результат в тесте — конечно.

K>Планы выполнения покажет и не нужно доставать откуда-то сгенерированный SQL, лезть в программу для работы с БД и там уже анализировать и оптимизировать?

Для плана да. Придётся извлечь текст. Но не вижу в этом серьёзной проблемы.

K>·>А что такого? В этом и суть — shift-f6 и всё. Если что-то где-то не так, будет ошибка компиляции.

K>Что такое shift-f6? Что всё?
Рефакторинг переименования.

K>Нажму кнопку и с БД колонка переименуется?

K>Или если я колонку в БД переименую, а в Java-коде — нет, то получу ошибку компиляции?
Ну да.

K>·>Поможет отыскать где как во всём коде поля используются.

K>Это немного жизнь упростит, но всё равно придётся многое перепроверять отдельно.
Имхо "немного" — это мягко сказано.

K>·>Вообще говоря вижу что есть org.mybatis.dynamic.sql.SqlBuilder

K>·>Но не пользовался, не знаю.
K>Видел. Какая-то бессмысленная фигня.
Поглядел внимательнее, похоже ты прав.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.