Я разрабатываю новое веб-приложение 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.