spring-boot
Spring boot + Spring Data JPA
Szukaj…
Wprowadzenie
Spring Boot ułatwia tworzenie aplikacji i usług zasilanych sprężyną, przy minimalnym wysiłku. Preferuje konwencję zamiast konfiguracji.
Spring Data JPA , część większej rodziny Spring Data , ułatwia wdrażanie repozytoriów opartych na JPA. Ułatwia tworzenie aplikacji korzystających z technologii dostępu do danych.
Uwagi
Adnotacje
@Repository
: Wskazuje, że klasa z adnotacjami jest „repozytorium”, mechanizmem enkapsulacji przechowywania, pobierania i wyszukiwania, który emuluje kolekcję obiektów. Zespoły wdrażające tradycyjne wzorce J2EE, takie jak „Obiekt dostępu do danych”, mogą również zastosować ten stereotyp do klas DAO, jednak należy dołożyć starań, aby zrozumieć różnicę między Obiektem dostępu do danych a repozytoriami w stylu DDD. Ta adnotacja jest stereotypem ogólnego zastosowania, a poszczególne zespoły mogą zawęzić swoją semantykę i stosować ją odpowiednio.
@RestController
: wygoda adnotacja, że sama jest opatrzone @Controller
i @ResponseBody.Types
które wykonują tę adnotację traktowane są jako kontrolery gdzie @RequestMapping
metody zakładają @ResponseBody
semantykę domyślnie.
@Service
: wskazuje, że klasa z adnotacjami jest „usługą” (np. Fasada usługi biznesowej). Ta adnotacja służy jako specjalizacja @Component
, umożliwiając automatyczne wykrywanie klas implementacji poprzez skanowanie ścieżki klas.
@SpringBootApplication
: Wielu programistom Spring Boot zawsze @Configuration
przypisanie do głównej klasy adnotacji @Configuration
, @EnableAutoConfiguration
i @ComponentScan
. Ponieważ te adnotacje są tak często używane razem (szczególnie jeśli postępujesz zgodnie z powyższymi najlepszymi praktykami), Spring Boot stanowi wygodną alternatywę @SpringBootApplication
.
@Entity
: określa, że klasa jest bytem. Ta adnotacja jest stosowana do klasy encji.
Oficjalna dokumentacja
Pivotal Software dostarczył dość obszerną dokumentację dotyczącą Spring Framework, którą można znaleźć na stronie
Podstawowy przykład integracji Spring Boot i Spring Data JPA
Zbudujemy aplikację przechowującą POJO w bazie danych. Aplikacja korzysta z JPA Spring Data do przechowywania i pobierania danych w relacyjnej bazie danych. Jego najbardziej atrakcyjną cechą jest możliwość automatycznego tworzenia implementacji repozytorium w czasie wykonywania z interfejsu repozytorium.
Główna klasa
package org.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
Metoda main()
używa metody SpringApplication.run()
Spring Boot do uruchomienia aplikacji. Zauważ, że nie ma jednej linii XML. Brak pliku web.xml. Ta aplikacja internetowa jest w 100% czystą Javą i nie musisz zajmować się konfigurowaniem instalacji wodno-kanalizacyjnej ani infrastruktury.
Klasa podmiotu
package org.springboot.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Greeting {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String text;
public Greeting() {
super();
}
public Greeting(String text) {
super();
this.text = text;
}
/* In this example, the typical getters and setters have been left out for brevity. */
}
Tutaj masz klasę Greeting
z dwoma atrybutami, id
i text
. Masz również dwóch konstruktorów. Domyślny konstruktor istnieje tylko ze względu na JPA. Nie będziesz używać go bezpośrednio, więc można go oznaczyć jako protected
. Drugi konstruktor służy do tworzenia wystąpień Greeting
które zostaną zapisane w bazie danych.
Klasa Greeting
jest opatrzona adnotacją @Entity
, co oznacza, że jest to jednostka JPA. W przypadku braku adnotacji @Table
zakłada się, że ten element zostanie zmapowany do tabeli o nazwie „Powitanie”.
Właściwość id
Powitania jest opatrzona adnotacją @Id
dzięki czemu JPA rozpozna ją jako identyfikator obiektu. Właściwość id
jest także opatrzona adnotacjami @GeneratedValue
aby wskazać, że identyfikator powinien zostać wygenerowany automatycznie.
Inną właściwością jest pozostawienie text
adnotacji. Zakłada się, że zostanie odwzorowany na kolumnę o tej samej nazwie co sama właściwość.
Właściwości przejściowe
W klasie encji podobnej do powyższej możemy mieć właściwości, których nie chcemy utrwalać w bazie danych lub tworzyć jako kolumny w naszej bazie danych, być może dlatego, że chcemy po prostu ustawić je w środowisku wykonawczym i używać ich w naszej aplikacji, stąd możemy mieć tę właściwość adnotację z adnotacją @Transient.
package org.springboot.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Transient;
@Entity
public class Greeting {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String text;
@Transient
private String textInSomeLanguage;
public Greeting() {
super();
}
public Greeting(String text) {
super();
this.text = text;
this.textInSomeLanguage = getTextTranslationInSpecifiedLanguage(text);
}
/* In this example, the typical getters and setters have been left out for brevity. */
}
Tutaj masz tę samą klasę Greeting, która ma teraz właściwość przejściową textInSomeLanguage
którą można zainicjować i używać w czasie wykonywania i nie będzie ona utrwalana w bazie danych.
Klasa DAO
package org.springboot.repository;
import org.springboot.model.Greeting;
import org.springframework.data.repository.CrudRepository;
public interface GreetingRepository extends CrudRepository<Greeting, Long> {
List<Greeting> findByText(String text);
}
GreetingRepository
rozszerza interfejs CrudRepository
. Typ encji i identyfikator, z którym współpracuje, Greeting
i Long
, są określone w ogólnych parametrach w CrudRepository
. Rozszerzając CrudRepository
, GreetingRepository
dziedziczy kilka metod pracy z trwałością Greeting
, w tym metody zapisywania, usuwania i wyszukiwania elementów Greeting
.
Zobacz tę dyskusję, aby porównać CrudRepository
, PagingAndSortingRepository
, JpaRepository
.
Spring Data JPA pozwala także definiować inne metody zapytań, po prostu deklarując ich podpis. W przypadku GreetingRepository
jest to pokazane za pomocą metody findByText()
.
W typowej aplikacji Java można oczekiwać napisania klasy, która implementuje GreetingRepository
. Ale to sprawia, że Spring Data JPA jest tak potężny: Nie musisz pisać implementacji interfejsu repozytorium. Spring Data JPA tworzy implementację w locie po uruchomieniu aplikacji.
Klasa serwisowa
package org.springboot.service;
import java.util.Collection
import org.springboot.model.Greeting;
public interface GreetingService {
Collection<Greeting> findAll();
Greeting findOne(Long id);
Greeting create(Greeting greeting);
Greeting update(Greeting greeting);
void delete(Long id);
}
Fasola Serwisowa
package org.springboot.service;
import java.util.Collection;
import org.springboot.model.Greeting;
import org.springboot.repository.GreetingRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GreetingServiceBean implements GreetingService {
@Autowired
private GreetingRepository greetingRepository;
@Override
public Collection<Greeting> findAll() {
Collection<Greeting> greetings = greetingRepository.findAll();
return greetings;
}
@Override
public Greeting findOne(Long id) {
Greeting greeting = greetingRepository.findOne(id);
return greeting;
}
@Override
public Greeting create(Greeting greeting) {
if (greeting.getId() != null) {
//cannot create Greeting with specified Id value
return null;
}
Greeting savedGreeting = greetingRepository.save(greeting);
return savedGreeting;
}
@Override
public Greeting update(Greeting greeting) {
Greeting greetingPersisted = findOne(greeting.getId());
if (greetingPersisted == null) {
//cannot find Greeting with specified Id value
return null;
}
Greeting updatedGreeting = greetingRepository.save(greeting);
return updatedGreeting;
}
@Override
public void delete(Long id) {
greetingRepository.delete(id);
}
}
Klasa kontrolera
package org.springboot.web.api;
import java.util.Collection;
import org.springboot.model.Greeting;
import org.springboot.service.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/api")
public class GreetingController {
@Autowired
private GreetingService greetingService;
// GET [method = RequestMethod.GET] is a default method for any request.
// So we do not need to mention explicitly
@RequestMapping(value = "/greetings", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Collection<Greeting>> getGreetings() {
Collection<Greeting> greetings = greetingService.findAll();
return new ResponseEntity<Collection<Greeting>>(greetings, HttpStatus.OK);
}
@RequestMapping(value = "/greetings/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> getGreeting(@PathVariable("id") Long id) {
Greeting greeting = greetingService.findOne(id);
if(greeting == null) {
return new ResponseEntity<Greeting>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Greeting>(greeting, HttpStatus.OK);
}
@RequestMapping(value = "/greetings", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> createGreeting(@RequestBody Greeting greeting) {
Greeting savedGreeting = greetingService.create(greeting);
return new ResponseEntity<Greeting>(savedGreeting, HttpStatus.CREATED);
}
@RequestMapping(value = "/greetings/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Greeting> updateGreeting(@PathVariable("id") Long id, @RequestBody Greeting greeting) {
Greeting updatedGreeting = null;
if (greeting != null && id == greeting.getId()) {
updatedGreeting = greetingService.update(greeting);
}
if(updatedGreeting == null) {
return new ResponseEntity<Greeting>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<Greeting>(updatedGreeting, HttpStatus.OK);
}
@RequestMapping(value = "/greetings/{id}", method = RequestMethod.DELETE)
public ResponseEntity<Greeting> deleteGreeting(@PathVariable("id") Long id) {
greetingService.delete(id);
return new ResponseEntity<Greeting>(HttpStatus.NO_CONTENT);
}
}
Plik właściwości aplikacji dla bazy danych MySQL
#mysql config
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=Welcome@123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy
#initialization
spring.datasource.schema=classpath:/data/schema.sql
Plik SQL
drop table if exists greeting;
create table greeting (
id bigint not null auto_increment,
text varchar(100) not null,
primary key(id)
);
plik pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Budowanie wykonywalnego pliku JAR
Możesz uruchomić aplikację z wiersza poleceń za pomocą Maven. Możesz też zbudować pojedynczy plik wykonywalny JAR, który zawiera wszystkie niezbędne zależności, klasy i zasoby, i uruchomić go. Ułatwia to wysyłkę, aktualizację i wdrożenie usługi jako aplikacji w całym cyklu rozwojowym, w różnych środowiskach i tak dalej.
Uruchom aplikację za pomocą ./mvnw spring-boot:run
. Lub możesz zbudować plik JAR za ./mvnw clean package
. Następnie możesz uruchomić plik JAR:
java -jar target/springboot-0.0.1-SNAPSHOT.jar