1. Fichero de configuración application.properties
En este fichero podemos guardar las siguientes propiedades:1. Las que afectan a las de documentación JSONDoc que hemos visto en una entrada anterior.
2. Para inidicar donde se guardan los archivos de BD. Por ejemplo para h2 se puede hacer
spring.datasource.url=jdbc:h2:file:./bookings.db
3. El puerto donde correrá nuestra aplicación
server.port = 8080
4. Variables que vamos a utilizar para configurar nuestra aplicación
app-mode = development (para distinguir entre development o production)
Para el caso de las variables a utilizar en la aplicación se puede hacer referencia a ella mediante 2 métodos que hablaremos mas tarde.
2. Recuperar variables de aplication.properties
Para ello podemos actuar de 2 maneres distintasMÉTODO 1: Inyección de propiedad
@Value("${app-mode}") private String appMode;
MÉTODO 2: Inyección de constructor
private String appMode2; public DemoController (Environment env) { appMode2=env.getProperty("app-mode"); }
Siendo DemoController el nombre de la clase sobre la que creamos el constructor.
3. El Model de Spring
Spring proporciona un lugar donde guardar ciertas variables que nos serán útiles para dar un comportamiento concreto al programa. Estas variables se guardan en el "Model".Para guardar las variables en el Model hay un método que se llama addAttribute. Podemos por ejemplo, añadir al modelo, entre otras, las variables recuperadas de application.properties. Veamos un pequeño ejemplo
package com.ximodante; import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.ui.Model; @Controller public class ViewController { @Value("${app-mode}") private String appMode; @RequestMapping("/") public String index(Model model){ model.addAttribute("datetime", new Date()); model.addAttribute("username", "Informatica Dantesca"); model.addAttribute("mode", appMode); return "index"; } }Aquí estamos adelantando lo que veremos mas adelante, que es mostrar una plantilla Thymeleaf llamada "index.html" cuando llamamos a nuestra aplicación con la ruta "http://localhost:8080"
4. JPA muy simple
PASO 1:
Cuando creamos el proyecto en la entrada anterior le hemos dicho utilizar JPA y h2
PASO 2:
Crearemos una entidad (POJO) y le indicaremos entre otras las siguientes anotaciones:
@Entity:
Anotación a nivel de clase para que JPA sepa que es una entidad a persistir
@Id:
Anotación sobre un atributo numérico para que sea clave única
@GeneratedValue(strategy = GenerationType.SEQUENCE)
Para que sea autogerado e incremental
Veamos la clase en concreto a la cual hemos quitado verbosidad con Lombok
package com.ximodante; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import lombok.Getter; import lombok.Setter; @Entity public class HotelBooking { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @Getter private long id; @Getter @Setter private String hotelName; @Getter @Setter private double pricePerNight; @Getter @Setter private int nbOfNights; public HotelBooking() { super(); } public HotelBooking(String hotelName, double pricePerNight, int nbOfNights){ this.hotelName = hotelName; this.pricePerNight = pricePerNight; this.nbOfNights = nbOfNights; } public double getTotalPrice(){ return pricePerNight * nbOfNights; } }
5. JpaRepository
En Spring podemos heredar de la interfaz JpaRepository y adapatarla a nuestra clase. pero con la "ventaja" que Spring nos da de tener métodos por "convención". Notar el uso de la anotación @Repository Veamos interfaz adaptada:
package com.ximodante; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BookingRepository extends JpaRepository < HotelBooking,Long >{ List < HotelBooking > findByPricePerNightLessThan(double price); }
6. Generador de datos en la BD con CommandLineRunner
Spring proporciona generadores de datos en las BD de prueba. Hay que tener cuidado ya que tal como tenenos nuestro proyecto, está pensado en el desarrollo y no en la producción ya que se borran todos los datos de la BD y se crean solo los que se indican en el generador.
En cualquier caso Spring te permite esta alimentación de la BD mediante la implementación de la intefaz CommandLineRunner y haciendo uso del JpaRepository. Notar las notaciones @Component y @Autowired.
Veamos como guardamos llenamos la BD con información de la entidad mostrada arriba
En cualquier caso Spring te permite esta alimentación de la BD mediante la implementación de la intefaz CommandLineRunner y haciendo uso del JpaRepository. Notar las notaciones @Component y @Autowired.
Veamos como guardamos llenamos la BD con información de la entidad mostrada arriba
package com.ximodante; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class DatabaseSeeder implements CommandLineRunner { private BookingRepository bookingRepository; @Autowired public DatabaseSeeder(BookingRepository bookingRepository){ this.bookingRepository = bookingRepository; } @Override public void run(String... arg0) throws Exception { List <HotelBooking > bookings=new ArrayList<>(); bookings.add(new HotelBooking("Palas",14.5,3)); bookings.add(new HotelBooking("Ibis",24.5,2)); bookings.add(new HotelBooking("Atenea",20,5)); bookings.add(new HotelBooking("Palasiet",200,1)); this.bookingRepository.save(bookings); } }
7. REST con JPA
Nuestro querido amigo, en su tutorial, nos enseña a como integrar todas estas tecnologías. Aquí listo la clase que ofrece las funciones de persistencia a traves de servicios REST. Como los hemos documentado don JSONDoc, podemos verlos tal como lo hicimos en le punto anterior
package com.ximodante; import java.util.List; import org.jsondoc.core.annotation.Api; import org.jsondoc.core.annotation.ApiMethod; import org.jsondoc.core.annotation.ApiPathParam; import org.jsondoc.core.pojo.ApiStage; import org.springframework.beans.factory.annotation.Autowired; 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 = "/bookings") @Api( name = "Hotel Booking API", description = "Provides a list of methods that manage hotel bookings", stage = ApiStage.RC) public class BookingController { private BookingRepository bookingRepository; @Autowired public BookingController(BookingRepository bookingRepository){ this.bookingRepository=bookingRepository; } @RequestMapping(value="/all" ,method = RequestMethod.GET) @ApiMethod(description = "Get all hotel bookings from database") public ListgetAll(){ return this.bookingRepository.findAll(); } @RequestMapping(value = "/affordable/{price}", method = RequestMethod.GET) @ApiMethod(description = "Get all hotel bookings from database whose price is under the provided value") public List getAffordable(@ApiPathParam(name = "price") @PathVariable double price){ return this.bookingRepository.findByPricePerNightLessThan(price); } @RequestMapping(value = "/create", method = RequestMethod.POST) @ApiMethod(description = "Create a hotel booking and save it to the database") public List create(@RequestBody HotelBooking hotelBooking){ this.bookingRepository.save(hotelBooking); return this.bookingRepository.findAll(); } @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST) @ApiMethod(description = "Deleta a hotel booking whose id is the provided value") public List remove(@ApiPathParam(name = "id") @PathVariable long id) { bookingRepository.delete(id); return this.bookingRepository.findAll(); } }
No hay comentarios :
Publicar un comentario