Loslegen
Javaneer
Zurück zur Stufe
Modul 3·Daten & Persistenz

Spring Data JPA & Repositories

Objekte mit JPA-Entities auf Tabellen abbilden und CRUD kostenlos aus einem Repository-Interface erhalten, das du nie implementierst.

18 Min. LesezeitFortgeschritten

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

BookVault's catalog has lived in a ConcurrentHashMap - it vanishes on restart. Time to give it a real database. Doing that with raw JDBC means writing connection code, SQL, and result-set mapping for every operation. Spring Data JPA removes almost all of it: you describe your data as objects, declare a repository interface, and get a full data-access layer you never implement.

Add the starter and a database

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>

H2 is an in-memory database - perfect for learning and tests. Swapping to PostgreSQL later is just a driver and a URL.

Map an object to a table: the entity

An entity is a class JPA maps to a database table. Annotations describe the mapping:

@Entity
class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;                 // primary key, auto-generated

    @Column(unique = true, nullable = false)
    private String isbn;

    private String title;
    private String author;
    private int copies;

    protected Book() {}              // JPA needs a no-arg constructor
    // constructor, getters…
}
An entity is a labeled shipping form

Think of an object's data as a parcel and the database table as a warehouse of numbered shelves. The entity annotations are the shipping form taped to the parcel: @Table says which warehouse, @Id is the shelf number, @Column labels each field's slot. JPA reads the form to file the object away and to fetch it back later - you never walk the warehouse aisles (write SQL) yourself.

The repository: CRUD you never write

Declare an interface extending one of Spring Data's repository types, and Spring generates the implementation at runtime:

interface BookRepository extends JpaRepository<Book, Long> {
    // that's it — save, findById, findAll, delete, count… all provided
}

JpaRepository<Book, Long> means "manage Book entities with a Long id." You immediately get save, findById, findAll, deleteById, count, and more - fully implemented, transactional, and typed.

@Service
class BookService {
    private final BookRepository repository;
    BookService(BookRepository repository) { this.repository = repository; }

    Book add(Book book) { return repository.save(book); }
    List<Book> all()   { return repository.findAll(); }
}

You wrote no SQL and no implementation

There is no BookRepositoryImpl anywhere. Spring Data creates a proxy that turns your interface methods into queries and executes them. In the next lesson you'll add custom finders just by naming methods.

From map to database

BookVault's BookService currently stores books in a Map<String, Book>. Describe the two things you add to move it to a real database with Spring Data JPA - one on the Book class, one new type - and note why you never write a class that implements the data-access methods.

How do you obtain CRUD operations for an entity in Spring Data JPA?

Key takeaways

  • Spring Data JPA maps objects to tables (@Entity, @Id, @Column) and generates data-access code for you.
  • spring-boot-starter-data-jpa + an H2 (or PostgreSQL) driver sets up JPA/Hibernate and a datasource automatically.
  • An entity is a class mapped to a table; it needs an @Id and a no-arg constructor.
  • Declaring a repository interface extending JpaRepository<Entity, Id> gives you save/findById/findAll/delete for free - you never write the implementation.
  • Switching databases later is mostly a driver and a connection URL change.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten