web-dev-qa-db-de.com

Spring Boot erweitert CrudRepository

Ich verwende Hibernate in einer Spring Boot-App. Ich erstelle ein neues CrudRepository für alle meine Model-Objekte, um grundlegende CRUD-Aufgaben auszuführen. Sie sehen so aus:

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

Aber dann muss ich immer noch einige zusätzliche Dinge tun, z. B. benutzerdefinierte Suchabfragen mit Ungleichheiten und dergleichen. Ich folge einem Muster wie folgt:

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

Meine Frage ist, kann ich diese beiden Konzepte in einer einzigen Klasse kombinieren? Ich habe versucht, daraus eine abstrakte Klasse zu machen:

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

}

Aber dann hat Spring keine Bohne dafür kreiert.

Wie kann ich das erreichen?

Vielen Dank!

6
James Watkins

Es gibt viele Möglichkeiten, dies zu erreichen. Wenn Sie wirklich absolute Kontrolle benötigen, versuchen Sie dies

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

Es gibt auch die Möglichkeit, eine einfachere Route zu wählen, und die Abfrage kann basierend auf dem Methodennamen automatisch für Sie generiert werden. In Ihrem Beispiel könnten Sie dies einfach zu Ihrem FoobarCrudRepo hinzufügen, und Spring sollte den Rest erledigen, vorausgesetzt, Foobar hat eine Eigenschaft mit dem Namen CreatedDate

List<Foobar> findByCreatedDateGreaterThan(Date date);

Informationen dazu, wie Spring Abfragen basierend auf dem Methodennamen generieren kann, finden Sie unter http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query- Schaffung

13
jst

Ganz neu bei Spring Data, aber nach einigem Suchen habe ich den Eindruck, dass Sie die Schnittstelle nicht verlassen müssen, um eine benutzerdefinierte Logik zu erstellen. Stattdessen erstellen Sie entweder eine kommentierte Schnittstellenmethode, eine Schnittstellenmethode, die einem speziellen Benennungsschema folgt, oder eine Standardschnittstellenmethode mit benutzerdefinierter Logik: 

 enter image description here Screenshot von Baeldung: Einführung in den Frühling .

Hier ist ein Link zur Dokumentation. Beachten Sie " table 4. Unterstützte Schlüsselwörter in Methodennamen ", die zum Erstellen von Schnittstellenmethoden verwendet werden können, deren Name dem Codegenerator Informationen über die zu erstellende Abfrage übermittelt (siehe unten in der Tabelle).

 enter image description here

1
Hervian

wir können das JPA EntityManager für direkte SQL-Aktionen verwenden:

public interface VerificationsRepository extends
    CrudRepository<Verification, Integer>,
    DAOAccess
{ }

interface DAOAccess {
   List findByEmail(String email);

}

class DAOAccessImpl implements DAOAccess {
   @PersistenceContext private EntityManager em;

    public List findByEmail(String email) {
        String sql =
            "select * from verifications where email = ?";
        Query query = em.createNativeQuery(sql, Verification.class)
            .setParameter(1, email);
        return query.getResultList();
    }
}
0
Bodhi Hu

Das Problem hier ist abstract Schlüsselwort.

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

Spring erstellt keine Bean für eine Klasse, es sei denn, es handelt sich um eine konkrete Klasse. Deshalb erhalten Sie eine Bean für diese Klasse.

0
pmverma

Das hat bei mir funktioniert ...

@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