Весна загрузки расширения CrudRepository
Я использую Hibernate в приложении Spring Boot. Я делаю новый CrudRepository для всех моих объектов модели, чтобы выполнять основные задачи CRUD. Они выглядят так:
@Repository
public interface FoobarCrudRepo extends CrudRepository<Foobar, Long> {
}
но тогда мне всегда нужно делать некоторые дополнительные вещи, такие как пользовательские поисковые запросы с неравенствами и тому подобное. Я следую такой схеме:--4-->
@Repository
public class FoobarDao {
@PersistenceContext
EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
мой вопрос в том, Могу ли я объединить эти два понятия в один класс? Я попытался сделать его абстрактным классом, например:
@Repository
public abstract class FoobarCrudRepo extends CrudRepository<Foobar, Long> {
@PersistenceContext
EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
но тогда весна не создала для него Боба.
как я могу это сделать?
спасибо!
4 ответов
есть много способов, которыми вы могли бы это сделать. Если вам действительно нужен абсолютный контроль, попробуйте это
interface FoobarRepositoryCustom{
List<Foobar> findFoobarsByDate(Date date);
}
interface FoobarRepository extends CrudRepository<Foobar, Long>, FoobarRepositoryCustom
public class FoobarRespoitoryImpl implements FoobarRepositoryCustom{
@PersistenceContext private EntityManager em;
public List<Foobar> findFoobarsByDate(Date date) {
String sql = "select fb from Foobar fb where createdDate > :date";
...
return query.getResultList();
}
}
существует также возможность пройти более простой маршрут, и запрос может быть автоматически сгенерирован для вас на основе имени метода. В вашем примере вы можете просто добавить это в свой FoobarCrudRepo, а Spring должен сделать все остальное, предполагая, что Foobar имеет свойство с именем CreatedDate
List<Foobar> findByCreatedDateGreaterThan(Date date);
для справки о том, как Spring может генерировать запросы на основе имя метода см. Это http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation
совершенно новый для Spring Data, но после поиска немного, у меня сложилось впечатление, что вам не нужно покидать интерфейс для создания пользовательской логики-скорее вы создадите либо аннотированный метод интерфейса, метод интерфейса, который следует специальной схеме именования, либо метод интерфейса по умолчанию с пользовательской логикой:
Скриншот из Baeldung: введение в Spring.
здесь ссылка на документация. Заметьте,"Таблица 4. Поддерживаемые ключевые слова внутри имен методов", который может использоваться для создания методов интерфейса, имя которого передает информацию генератору кода о том, какой запрос создать (см. часть таблицы ниже).
проблема тут abstract
ключевое слово.
@Repository
public abstract class FoobarCrudRepo extends CrudRepository<Foobar, Long>
Spring не создаст боб для класса, если он не является конкретным классом. Вот почему вы получаете за это Боб.
Это то, что работал для меня...
@SpringBootApplication(scanBasePackages = { "com.myproject" })
@EnableJpaRepositories(basePackages="com.myproject.sprinbootapp.repository")
@EntityScan("com.myproject.sprinbootapp.model")
public class SpringbootAppWithDatabaseApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootAppWithDatabaseApplication.class, args);
}
}
@Service
public class TopicService {
@Autowired
private TopicRepository topicRepository;
private List<Topics> topics = new ArrayList<Topics>();
public List<Topics> getAllTopics(){
List<Topics> listOfTopics = new ArrayList<Topics>();
topicRepository.findAll().forEach(listOfTopics::add);;
return listOfTopics;
}
}
@Entity
public class Topics {
@Id
private String id;
private String name;
public Topics(){
}
getters and setters...
}
public interface TopicRepository extends CrudRepository<Topics, String> {
}