Anpassade Spring Data-repositorier
Utöka Spring Data JPA-repositorier med anpassade metoder och frågedefinitioner för komplexa dataoperationer.
Anpassade Spring Data-repositorier är en gratis lektion i Spring Boot 4 – komplett guide på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Spring Boot 4 – komplett guide, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Introduktion till anpassade repositories
Spring Data JPA är fantastiskt för att minska mängden standardkod, men ibland behöver ni mycket specifika och komplexa dataoperationer som inte täcks av enkel härledning från metodnamn.
Det är här anpassade repositories kommer in i bilden! De låter er definiera och implementera er egen komplexa dataåtkomstlogik och utöka Spring Data JPA:s funktionalitet.
När ska ni använda anpassad logik
När behöver ni skriva anpassad repository-logik? Här är några vanliga scenarier:
- Komplexa join-uttryck och aggregeringar: När standardmetoder för frågor inte kan uttrycka era behov av join-uttryck eller aggregeringar.
- Batchåtgärder: Uppdatering eller borttagning av flera poster som kräver särskild logik.
- Lagrade procedurer: Interaktion med databasspecifika lagrade procedurer.
- Prestandajustering: Tillämpning av särskilda frågetips eller optimeringar.
- Verksamhetsspecifika åtgärder: Logik som kombinerar flera dataåtkomststeg till en sammanhållen metod.
Definiera ett anpassat interface
Det första steget är att definiera ett interface för era anpassade metoder. Interfacet deklarerar de metoder som inte följer Spring Data JPA:s konventioner.
Se det som en ritning för era unika dataoperationer.
package com.coddykit.repo;
public interface CustomUserRepository {
void activateUsersOlderThan(int age);
// Add more specific methods here
}Implementera anpassad logik
Skapa sedan en klass som implementerar ert anpassade interface. Här skriver ni den faktiska koden för era komplexa dataoperationer.
Vanligtvis använder ni EntityManager från JPA eller JdbcTemplate för mer direkt interaktion med SQL.
package com.coddykit.repo.impl;
import com.coddykit.repo.CustomUserRepository;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
public class CustomUserRepositoryImpl implements CustomUserRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void activateUsersOlderThan(int age) {
System.out.println("Executing custom logic...");
entityManager.createQuery(
"UPDATE User u SET u.active = true WHERE u.age > :age")
.setParameter("age", age)
.executeUpdate();
}
}Integrera med huvudrepositoryt
För att göra er anpassade implementation tillgänglig måste ert huvudsakliga Spring Data JPA-repositoryinterface utöka ert anpassade interface.
Spring Data JPA upptäcker och kopplar automatiskt samman implementationsklassen (den förväntar sig att implementationsklassens namn är [CustomInterfaceName]Impl).
package com.coddykit.repo;
import com.coddykit.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long>, CustomUserRepository {
// Standard methods from JpaRepository
// Plus custom methods from CustomUserRepository
}Fullständig demonstration av ett anpassat repository
Nu ska vi titta på ett komplett exempel som visar ett anpassat repository i praktiken. Vi definierar en User-entitet, ett UserRepository som kombinerar standardmetoder och anpassade metoder samt en Spring Boot-applikation som använder det.
Prova att köra exemplet:
package com.coddykit;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.transaction.Transactional;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
// 1. User Entity
@Entity
class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
private boolean active;
public User() {}
public User(String name, int age, boolean active) {
this.name = name;
this.age = age;
this.active = active;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public boolean isActive() { return active; }
public void setActive(boolean active) { this.active = active; }
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", active=" + active + '}';
}
}
// 2. Custom Interface
interface CustomUserRepository {
void activateUsersOlderThan(int age);
}
// 3. Custom Implementation
class CustomUserRepositoryImpl implements CustomUserRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void activateUsersOlderThan(int age) {
System.out.println("Activating users older than " + age + "...");
entityManager.createQuery(
"UPDATE User u SET u.active = true WHERE u.age > :age")
.setParameter("age", age)
.executeUpdate();
}
}
// 4. Main Repository extends JpaRepository and Custom Interface
@Repository
interface UserRepository extends JpaRepository<User, Long>, CustomUserRepository {
// Spring Data JPA methods
}
@SpringBootApplication
public class Main implements CommandLineRunner {
@Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Override
public void run(String... args) throws Exception {
// Save some users
userRepository.save(new User("Alice", 25, false));
userRepository.save(new User("Bob", 30, false));
userRepository.save(new User("Charlie", 35, false));
System.out.println("--- Initial Users ---");
userRepository.findAll().forEach(System.out::println);
// Use custom method
userRepository.activateUsersOlderThan(28);
System.out.println("--- Users After Custom Update ---");
userRepository.findAll().forEach(System.out::println);
}
}Använda @Query för JPQL/HQL
För specifika frågor som inte enkelt kan uttryckas med metodnamn kan ni använda annoteringen @Query. Den låter er skriva JPQL (Java Persistence Query Language) eller HQL (Hibernate Query Language) direkt på era repository-metoder.
Ni kan använda positionsparametrar (?1) eller namngivna parametrar (:paramName).
package com.coddykit.repo;
import com.coddykit.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.age > ?1 AND u.active = true")
List<User> findActiveUsersOlderThan(int age);
@Query("SELECT u FROM User u WHERE u.name LIKE %:namePart%")
List<User> findUsersWithNameContaining(@org.springframework.data.repository.query.Param("namePart") String namePart);
}Inbyggda SQL-frågor med @Query
Ibland räcker JPQL inte till, och då behöver ni använda inbyggda SQL-frågor som är specifika för er databas (till exempel för databasspecifika funktioner eller av prestandaskäl).
Det gör ni genom att ange nativeQuery = true i annoteringen @Query. Var försiktiga, eftersom inbyggda frågor är mindre portabla mellan olika databaser.
package com.coddykit.repo;
import com.coddykit.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM User WHERE age < ?1 ORDER BY name", nativeQuery = true)
List<User> findYoungerUsersNative(int age);
@Query(value = "SELECT COUNT(*) FROM User WHERE active = :status", nativeQuery = true)
long countUsersByActiveStatusNative(@org.springframework.data.repository.query.Param("status") boolean status);
}Dynamiska frågor med specifications
För mycket dynamiska frågor som baseras på varierande kriterier (till exempel komplexa sökfilter) erbjuder Spring Data JPA JpaSpecificationExecutor.
- Det låter er definiera återanvändbara frågepredikat med JPA Criteria API.
- Metoden är kraftfull när ni vill bygga frågor som ändras under körning utan att behöva skriva många statiska
@Query-metoder. - Det är en mer avancerad teknik för flexibla sökskärmar.
Kontroll av anpassade repositories
Vilka av följande är giltiga sätt att utöka Spring Data JPA-repositories med anpassad funktionalitet?
Sammanfattning: Anpassade repositories
I den här lektionen utforskade vi hur ni kan gå längre än grundläggande Spring Data JPA-metoder:
- Vi definierade anpassade interface och implementerade dem för att kapsla in komplex och unik dataåtkomstlogik.
- Vi integrerade dessa anpassade implementationer med våra huvudrepositories.
- Vi lärde oss att använda
@Query-annoteringen för både JPQL/HQL och inbyggda SQL-frågor när vi ville definiera specifik datahämtning. - Vi berörde kort
JpaSpecificationExecutorför att bygga dynamiska frågor baserade på varierande kriterier.
Dessa tekniker ger er möjlighet att hantera nästan alla dataåtkomstkrav i era Spring Boot-applikationer!
Lär dig Java med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 21
- Lektioner
- 84
Vanliga frågor
Är lektionen ”Anpassade Spring Data-repositorier” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Spring Boot 4 – komplett guide, inklusive ”Anpassade Spring Data-repositorier”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Spring Boot 4 – komplett guide innehåller totalt 4 lektioner.
Vad lär jag mig i ”Anpassade Spring Data-repositorier”?
Utöka Spring Data JPA-repositorier med anpassade metoder och frågedefinitioner för komplexa dataoperationer. Ni övar på Spring Boot 4 – komplett guide med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Spring Boot 4 – komplett guide?
Du behöver inga förkunskaper. Utbildningen i Spring Boot 4 – komplett guide på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Anpassade Spring Data-repositorier”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Spring Boot 4 – komplett guide-lektionen?
Ja. Varje Spring Boot 4 – komplett guide-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Anpassade Spring Data-repositorier
- Integrering av NoSQL-databaser
- Cachning med Spring Cache
- Databasmigreringar med Flyway