spring-boot
Spring boot + Spring Data JPA
Zoeken…
Invoering
Spring Boot maakt het gemakkelijk om Spring-powered, productiekwaliteit applicaties en services te maken met absoluut minimum gedoe. Het geeft de voorkeur aan conventie boven configuratie.
Spring Data JPA , onderdeel van de grotere Spring Data- familie, maakt het eenvoudig om op JPA gebaseerde repositories te implementeren. Het maakt het eenvoudiger om apps te bouwen die technologieën voor gegevenstoegang gebruiken.
Opmerkingen
aantekeningen
@Repository
: geeft aan dat een geannoteerde klasse een "Repository" is, een mechanisme voor het inkapselen van opslag-, ophaal- en zoekgedrag dat een verzameling objecten emuleert. Teams die traditionele J2EE-patronen implementeren, zoals "Data Access Object", kunnen dit stereotype ook toepassen op DAO-klassen, hoewel voorzichtigheid geboden is om het onderscheid tussen Data Access Object en DDD-achtige repositories te begrijpen. Deze annotatie is een stereotype voor algemene doeleinden en individuele teams kunnen hun semantiek beperken en waar nodig gebruiken.
@RestController
: Een gemak annotatie die zelf is geannoteerd met @Controller
en @ResponseBody.Types
dat deze annotatie dragen, worden behandeld als controllers, waar @RequestMapping
methoden aannemen @ResponseBody
semantiek standaard.
@Service
: geeft aan dat een geannoteerde klasse een "Service" is (bijv. Een gevel van een zakelijke service). Deze annotatie dient als een specialisatie van @Component
, waardoor implementatieklassen automatisch kunnen worden gedetecteerd via classpath scanning.
@SpringBootApplication
: Veel Spring Boot-ontwikkelaars hebben altijd hun hoofdklasse geannoteerd met @Configuration
, @EnableAutoConfiguration
en @ComponentScan
. Omdat deze annotaties zo vaak samen worden gebruikt (vooral als u de bovenstaande praktische @SpringBootApplication
volgt), biedt Spring Boot een handig alternatief voor @SpringBootApplication
.
@Entity
: geeft aan dat de klasse een entiteit is. Deze annotatie wordt toegepast op de entiteitsklasse.
Officiële documentatie
Pivotal Software heeft een behoorlijk uitgebreide documentatie over Spring Framework geleverd en is te vinden op
Spring Boot en Spring Data JPA integratie basisvoorbeeld
We gaan een applicatie bouwen die POJO's in een database opslaat. De applicatie maakt gebruik van Spring Data JPA om gegevens op te slaan en op te halen in een relationele database. De meest aantrekkelijke functie is de mogelijkheid om repository-implementaties automatisch te maken, tijdens runtime, vanuit een repository-interface.
Hoofdklasse
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);
}
}
De methode main()
gebruikt de methode SpringApplication.run()
Spring Boot om een toepassing te starten. Merk op dat er geen enkele XML-regel is. Ook geen web.xml-bestand. Deze webtoepassing is 100% puur Java en u hoeft geen rekening te houden met het configureren van sanitair of infrastructuur.
Entiteitsklasse
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. */
}
Hier hebt u een Greeting
met twee attributen, de id
en de text
. Je hebt ook twee constructeurs. De standaardconstructor bestaat alleen omwille van JPA. U zult het niet direct gebruiken, dus het kan als protected
worden aangemerkt. De andere constructor is degene die u gebruikt om instanties van Greeting
te maken die in de database worden opgeslagen.
De klasse Greeting
is geannoteerd met @Entity
, wat aangeeft dat het een JPA-entiteit is. Bij gebrek aan een @Table
annotatie wordt ervan uitgegaan dat deze entiteit wordt toegewezen aan een tabel met de naam 'Begroeting'.
De eigenschap id
de groet is geannoteerd met @Id
zodat JPA deze herkent als de ID van het object. De eigenschap id
is ook geannoteerd met @GeneratedValue
om aan te geven dat de ID automatisch moet worden gegenereerd.
De andere eigenschap, text
is niet geannoteerd. Er wordt aangenomen dat het wordt toegewezen aan een kolom met dezelfde naam als de eigenschap zelf.
Voorbijgaande eigenschappen
In een entiteitsklasse vergelijkbaar met die hierboven, kunnen we eigenschappen hebben waarvan we niet willen dat ze in de database blijven staan of als kolommen in onze database worden gemaakt, misschien omdat we ze gewoon in runtime willen instellen en ze in onze applicatie willen gebruiken, daarom kunnen we die eigenschap laten annoteren met de @Transient annotatie.
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. */
}
Hier hebt u dezelfde begroetingsklasse die nu een tijdelijke eigenschap textInSomeLanguage
die tijdens runtime kan worden geïnitialiseerd en gebruikt en niet in de database blijft bestaan.
DAO-klasse
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
breidt de CrudRepository
interface uit. Het type entiteit en ID waarmee het werkt, Greeting
en Long
, worden gespecificeerd in de generieke parameters op CrudRepository
. Door CrudRepository
breiden, neemt GreetingRepository
verschillende methoden over voor het werken met Greeting
, waaronder methoden voor het opslaan, verwijderen en vinden van Greeting
.
Zie deze discussie voor vergelijking van CrudRepository
, PagingAndSortingRepository
, JpaRepository
.
Met Spring Data JPA kunt u ook andere querymethoden definiëren door eenvoudig hun methode-handtekening te declareren. In het geval van GreetingRepository
wordt dit getoond met de methode findByText()
.
In een typische Java-toepassing zou je verwachten een klasse te schrijven die GreetingRepository
implementeert. Maar dat is wat Spring Data JPA zo krachtig maakt: u hoeft geen implementatie van de repository-interface te schrijven. Spring Data JPA maakt een implementatie on the fly wanneer u de applicatie uitvoert.
Serviceklasse
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);
}
Serviceboon
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);
}
}
Controller Klasse
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);
}
}
Bestand met toepassingseigenschappen voor MySQL-database
#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
SQL bestand
drop table if exists greeting;
create table greeting (
id bigint not null auto_increment,
text varchar(100) not null,
primary key(id)
);
pom.xml-bestand
<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>
Een uitvoerbare JAR bouwen
U kunt de toepassing uitvoeren vanaf de opdrachtregel met Maven. Of u kunt een enkel uitvoerbaar JAR-bestand maken dat alle benodigde afhankelijkheden, klassen en bronnen bevat en dat uitvoeren. Dit maakt het gemakkelijk om de service te verzenden, te versie en te implementeren als een applicatie gedurende de ontwikkelingslevenscyclus, in verschillende omgevingen, enzovoort.
Voer de toepassing uit met ./mvnw spring-boot:run
. Of u kunt het JAR-bestand ./mvnw clean package
. Vervolgens kunt u het JAR-bestand uitvoeren:
java -jar target/springboot-0.0.1-SNAPSHOT.jar