Я разрабатываю новое веб-приложение Java, и я изучаю новые способы (новые для меня!), чтобы сохранить данные. У меня в основном есть опыт работы с JPA и Hibernate, но, за исключением простых случаев, я думаю, что такой полный ORM может стать довольно сложным. Кроме того, мне не очень нравится работать с ними. Я ищу новое решение, возможно, ближе к SQL.
Решения, которые я сейчас изучаю:
- MyBatis
- JOOQ
- Обычный SQL/JDBC, возможно с DbUtils или некоторыми другими базовыми библиотеками утилиты.
Но есть два варианта использования, которые я беспокоюсь по этим решениям, по сравнению с Hibernate. Я хотел бы знать, какие рекомендуемые шаблоны для этих случаев использования.
Пример использования 1 - выборка объекта и доступ к некоторым связанным с ним дочерним объектам и внукам.
- Скажем, у меня есть объект
Person
.- Этот
Person
имеет связанный объектAddress
.- Этот
Address
имеет связанный объектCity
.- Объект
City
имеет свойствоname
.
- Объект
- Этот
- Этот
Полный путь доступа к имени города, начиная с лица, будет:
person.address.city.name
Теперь скажем, я загружаю объект Person из PersonService
с помощью этого метода:
public Person findPersonById(long id)
{
// ...
}
Используя Hibernate, сущности, связанные с Person
, могут быть лениво загружены по требованию, поэтому можно было бы получить доступ к person.address.city.name
и быть уверенным, что у меня есть доступ к этому свойству (если все объекты в этом цепочка не может быть нулевой).
Но с помощью любого из трех решений, которые я изучаю, это сложнее. С этими решениями, каковы рекомендуемые шаблоны для ухода за этим вариантом использования? Наверху я вижу 3 возможных шаблона:
-
Все необходимые дочерние объекты и внуки могут быть загружены с помощью используемого SQL-запроса.
Но проблема, которую я вижу в этом решении, заключается в том, что может быть какой-то другой код, который должен получить доступ к другим путям объектов/свойств из объекта
Person
. Например, возможно, какой-то код будет нуждаться в доступе кperson.job.salary.currency
. Если я хочу повторно использовать методfindPersonById()
, который у меня уже есть, тогда SQL-запрос должен будет загрузить дополнительную информацию! Не только связанный объектaddress->city
, но также связанный с ним объектjob->salary
.Теперь что, если есть 10 другие места, которым необходимо получить доступ к другой информации, начиная с лица? Должен ли я всегда загружать всю потенциально необходимую информацию? Или, может быть, у вас есть 12 различных методов обслуживания для загрузки лица?
findPersonById_simple(long id) findPersonById_withAdressCity(long id) findPersonById_withJob(long id) findPersonById_withAdressCityAndJob(long id) ...
Но тогда каждый раз, когда я буду использовать объект
Person
, я должен был бы знать, что было загружено с ним, а что нет... Это может быть довольно громоздко, правильно? -
В методе
getAddress()
getter объектаPerson
может быть проверка, чтобы проверить, был ли уже загружен адрес и, если нет, его лениво загружать? Это часто используется в реальных приложениях? -
Существуют ли другие шаблоны, которые можно использовать для обеспечения доступа к объектам/свойствам, которые мне нужны из загруженной модели?
Use Case 2 - Сохранение сущности и обеспечение того, чтобы ее связанные и измененные объекты также сохранялись.
Я хочу сохранить объект Person
, используя этот метод PersonService
:
public void savePerson(Person person)
{
// ...
}
Если у меня есть объект Person
и я меняю person.address.city.name
на что-то еще, как я могу убедиться, что модификации сущностей City
будут сохранены, когда я сохраню Person
? Использование Hibernate может быть легко каскадировать операцию сохранения связанным объектам. Как насчет решений, которые я изучаю?
-
Должен ли я использовать какой-то грязный флаг, чтобы узнать, какие связанные объекты также должны быть сохранены при сохранении человека?
-
Есть ли другие известные шаблоны, полезные для использования в этом случае?
Обновить: обсуждение об этом вопросе на форуме JOOQ.