#java #spring #jdbc #spring-data-jpa #spring-data
#java #spring #jdbc #spring-data-jpa #spring-данные
Вопрос:
Я довольно хорошо знаком с JdbcTemplate
объектом Spring (и с spring-jdbc в целом), и мне действительно нравится писать SQL и самому разбираться с отображением объектов.
Однако недавно я играл с CrudRepository
интерфейсом, и он мне действительно понравился.
Тем не менее, я по-прежнему предпочитаю писать свои собственные запросы SQLs, когда дело доходит до сложного запроса (объединения и так далее).
Я хотел бы иметь возможность использовать CrudRepository
методы в классе, у которого также есть JdbcTemplate
экземпляр, таким образом, я мог бы иметь готовые методы CrudRepository
, имея при этом возможность писать свои собственные сложные SQLL и использовать их с JdbcTemplate
.
Проблема, конечно, в том, что CrudRepository
это просто интерфейс, а JdbcTemplate
это обычный класс. Итак, вопрос в том
- Имеет ли смысл что-либо из того, что я упоминаю, на самом деле?
- Предполагая, что ответ на (1) положительный, как бы я мог иметь класс с экземпляром a,
JdbcTemplate
который также предоставляет реализациюCrudRepository
, без необходимости слишком много обходить его?
Ответ №1:
Смешивание JPA и JDBC вполне возможно в любом приложении. JdbcTemplate
Может использоваться для написания сложных запросов или выполнения более сложного пользовательского сопоставления. Другой вариант — использовать RowCallbackHandler
(вместо RowMapper
для прямой потоковой передачи чего-либо в файл или другой ресурс, чтобы сохранить память).
При использовании Spring Data вы можете использовать @Query
аннотацию для написания пользовательских запросов в репозитории. Это может быть собственный запрос или JPQL.
Однако в Spring нет ничего, что мешало бы вам использовать оба в одном классе. Вы могли бы напрямую внедрить свой репозиторий как в сервис, так и в JdbcTemplate
(или вы могли бы поместить это за другим фасадом, если хотите).
@Service
@Transactional
public class YourService {
private final YourCrudRepository repo;
private final JdbcTemplate jdbc;
public YourService(YourCrudRepository repo, JdbcTemplate jdbc) {
this.repo=repo;
this.jdbc=jdbc;
}
// Your methods go down here
}
Теперь вы можете использовать оба. Приятная особенность Spring в том, что независимо от использования CrudRepository
или JdbcTemplate
DataAccessException
он будет выдавать одни и те же исключения, the, the. Если они работают на одном и том же, DataSource
одного JpaTransactionManager
достаточно для управления подключением и транзакцией.
Комментарии:
1. Известно ли JdbcTemplate о кэшировании 1-го уровня entity Manager и стратегии очистки? Я бы сомневался в этом. Таким образом, это открывает возможности для непоследовательного и неожиданного поведения. У вас есть больше опыта в этом?
2. Конечно, это не так, поэтому разумно сделать
flush
перед использованием шаблона jdbc (или вы могли бы использовать какой-нибудь AOP для автоматизации этого). Если вы не уверены, что все уже было сброшено.
Ответ №2:
Почему бы просто не использовать их в качестве членов?
public class MyDao {
private JdbcTemplate template;
private CrudRepository repository;
}
Конечно, вам нужно было бы пройти через все методы, которые являются своего рода шумными. Dao
это был бы стереотипный Data объект ccess O.
Комментарии:
1. Я думал об этом, но тогда мне нужно будет предоставить все методы
CrudRepository
вMyDao
классе, и это стало бы запутанным : (