У меня есть сервисный слой, который автоматически связывает репозиторий, например:
@Service
public class OrderService {
@Autowired
private OrderRepository repository;
public List<Order> retrieveOrders(String storeId) {
try {
return repository.getOrders(storeId)
} catch(Exception e) {
...
}
}
}
У меня есть новое требование, что в зависимости от номера магазина логика запросов к репозиторию c должна меняться. Я думаю о том, чтобы абстрагировать свой репозиторий и использовать фабричный шаблон. Текущий репозиторий является интерфейсом и расширяет JpaRepository; более того, все его функции используют аннотацию @Query для определения JPQL. Это пример только с одной функцией, но в моем реальном репозитории есть несколько функций
public interface OrderRepository extends JpaRepository {
@Query("select o " +
" from Orders o " +
" where o.storeId = :storeId")
public List<Order> getOrders(@Param(value = "storeId") String storeId);
}
В новых требованиях говорится, что для определенного c storeId SQL необходимо изменить на что-то вроде this:
public interface OrderRepositoryStore886 extends JpaRepository {
@Query("select o " +
" from Order o " +
" where o.storeId = :storeId " +
" and o.status IN (1,3,10,15) " +
" and EXISTS (SELECT c from CollabOrder WHERE c.orderId = o.orderId)")
public List<Order> getOrders(@Param(value = "storeId") String storeId);
}
Однако все остальные хранилища должны использовать первый запрос SQL.
Я пытаюсь выяснить, как условно @Autowire хранилище на основе storeId. Я думал о создании фабрики, но я не знаю, как сделать фабрику, которая возвращает интерфейсные объекты (я все еще довольно новичок в java, это может быть тривиально, но я еще не выяснил это). И если я пытаюсь превратить интерфейс Repository в класс, это заставляет меня переопределить все абстрактные методы JpaRepository, что является ненужным дополнительным кодом.