Весна загрузки расширения 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, но после поиска немного, у меня сложилось впечатление, что вам не нужно покидать интерфейс для создания пользовательской логики-скорее вы создадите либо аннотированный метод интерфейса, метод интерфейса, который следует специальной схеме именования, либо метод интерфейса по умолчанию с пользовательской логикой:

enter image description here Скриншот из Baeldung: введение в Spring.

здесь ссылка на документация. Заметьте,"Таблица 4. Поддерживаемые ключевые слова внутри имен методов", который может использоваться для создания методов интерфейса, имя которого передает информацию генератору кода о том, какой запрос создать (см. часть таблицы ниже).

enter image description here


проблема тут 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> {

}