web-dev-qa-db-fra.com

Spring Boot qui étend CrudRepository

J'utilise Hibernate dans une application Spring Boot. Je crée un nouveau CrudRepository pour tous mes objets Model afin de réaliser des tâches CRUD de base. Ils ressemblent à ceci:

@Repository
public interface FoobarCrudRepo extends CrudRepository<Foobar, Long> {
}

Mais ensuite, je dois toujours faire des choses supplémentaires, comme des requêtes de recherche personnalisées avec des inégalités et autres. Je suis un modèle comme celui-ci:

@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();
    }
}

Ma question est la suivante: puis-je combiner ces deux concepts en une seule classe? J'ai essayé d'en faire une classe abstraite, comme ceci:

@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();
    }

}

Mais alors le printemps n'a pas créé un haricot pour cela.

Comment puis-je accomplir cela?

Merci!

6
James Watkins

Vous pouvez probablement y parvenir de nombreuses façons. Si vous avez vraiment besoin d'un contrôle absolu, essayez ceci.

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();
    }
}

Il existe également la possibilité de choisir un itinéraire plus simple et la requête peut être générée automatiquement pour vous en fonction du nom de la méthode. Dans votre exemple, vous pouvez simplement ajouter ceci à votre FoobarCrudRepo et Spring devrait faire le reste en supposant que Foobar a une propriété nommée CreatedDate.

List<Foobar> findByCreatedDateGreaterThan(Date date);

Pour savoir comment Spring peut générer des requêtes en fonction du nom de la méthode, voir ceci http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query -creation

13
jst

Complètement nouveau dans Spring Data, mais après avoir un peu fouillé, j’ai l’impression que vous n’avez pas à quitter l’interface pour créer une logique personnalisée. Vous devez plutôt créer une méthode d’interface annotée, une méthode d’interface qui suit un méthode d'interface par défaut avec logique personnalisée: 

 enter image description here Capture d'écran de Baeldung: Introduction au printemps .

Ici est un lien vers la documentation. Remarque " tableau 4. Mots clés pris en charge dans les noms de méthodes " qui peuvent être utilisés pour créer des méthodes d’interface, dont le nom transmet des informations au générateur de code sur la requête à créer (voir partie du tableau ci-dessous).

 enter image description here

1
Hervian

Le problème ici est abstract mot-clé.

@Repository
public abstract class FoobarCrudRepo extends CrudRepository<Foobar, Long>

Spring ne créera pas de haricot pour une classe sauf s'il s'agit d'une classe concrète.

0
pmverma

C'est ce qui a fonctionné pour moi...

@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> {

}
0
Rahul Wasnik