Una aplicación para instalar los diferentes LLM del mercado.
Autor: Juan Pablo Fuentes
Ejemplos JPA
package com.trifulcas.SpringBootBiblioteca.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Libro;
public interface LibroRepository extends JpaRepository<Libro, Integer> {
List<Libro> findByPaginasBetweenOrderByPaginasAsc(Integer a, Integer b);
}
package com.trifulcas.SpringBootBiblioteca.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Genero;
public interface GeneroRepository extends JpaRepository<Genero, Integer> {
// Dentro del repositorio podemos crear consultas de una manera 'mágica'
List<Genero> findByNombreContaining(String nombre);
}
En el controlador:
@GetMapping("")
public List<Genero> getAll(@RequestParam(required=false) String nombre) {
try {
if (nombre==null) {
return generoRepository.findAll();
}else {
return generoRepository.findByNombreContaining(nombre);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
Url:
http://localhost:8080/libro?nombre=fi
@GetMapping("")
public List<Libro> getAll(@RequestParam(required=false) Integer min,@RequestParam(required=false) Integer max) {
try {
if (min==null || max==null) {
return libroRepository.findAll();
}else {
return libroRepository.findByPaginasBetweenOrderByPaginasAsc(min, max);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
Otro ejemplo, buscar los libros de un autor determinado
En el repository:
List<Libro> findByAutoresIdautor(Integer id);
En el controlador, creo un endpoint nuevo
@GetMapping("/autor/{id}")
public List<Libro> getByIdAutor(@PathVariable int id) {
System.out.println(id);
try {
return libroRepository.findByAutoresIdautor(id);
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
Nuevos endpoints para cosas extra
Normalmente queremos hacer más cosas aparte del crud estandard, para eso definimos nuevos endpoints, por ejemplo:
// Si yo quiero obtener los libros de un género, algo que he perdido
// con el JSON ignore pues me lo monto yo
@GetMapping("/{id}/libros")
public Set<Libro> getLibrosByIdGenero(@PathVariable int id) {
System.out.println(id);
try {
Genero cat = generoRepository.findById(id).orElse(null);
if (cat != null) {
return cat.getLibros();
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}/libros")
public Set<Libro> getLibrosByIdAutor(@PathVariable int id) {
System.out.println(id);
try {
Autor cat = autorRepository.findById(id).orElse(null);
if (cat != null) {
return cat.getLibros();
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
Endpoints en libros para manejar la relación con autores:
// Gestión de libros y autores
@PostMapping("{idlibro}/autor/{idautor}")
public Libro addLibroAutor(@PathVariable int idlibro, @PathVariable int idautor) {
System.out.println(idlibro);
System.out.println(idautor);
try {
Libro libro = libroRepository.findById(idlibro).orElse(null);
Autor autor = autorRepository.findById(idautor).orElse(null);
if (libro != null && autor != null) {
libro.getAutores().add(autor);
return libroRepository.save(libro);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Gestión de libros y autores
@DeleteMapping("{idlibro}/autor/{idautor}")
public Libro deleteLibroAutor(@PathVariable int idlibro, @PathVariable int idautor) {
System.out.println(idlibro);
System.out.println(idautor);
try {
Libro libro = libroRepository.findById(idlibro).orElse(null);
Autor autor = autorRepository.findById(idautor).orElse(null);
if (libro != null && autor != null) {
libro.getAutores().remove(autor);
return libroRepository.save(libro);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
API Biblioteca completo (3) Controladores
Los controladores son el núcleo de la aplicación. Toda la lógica de negocio está aquí. Recordemos que tenemos puntos de entrada ‘endpoint’ y cuando el usuario accede a uno de estos puntos se ejecuta lo que tengamos ahí.
Nosotros nos estamos basando en la arquitectura REST: Si yo lo que suelo hacer es CRUD y yo en HTTP tengo los verbos GET, POST, PUT y DELETE, me monto una manera de trabajar en la que el formato de datos es JSON y hago el match GET-Read POST-Create PUT-Update DELETE-Delete.
El Spring boot me proporciona la capacidad de definir urls de entrada con el mapping. Y de definir el verbo con el prefijo del mapping. Así PostMapping(‘/autor’) me está diciendo que si yo hago una petición POST a la url /autor entrará en ese punto del controlador.
Recordemos que tenemos dos tipos de controladores RestController y Controller. En el primer caso que es el que estamos viendo el propio Spring serializa (convierte a JSON) los valores que devolvemos.
También ‘mágicamente’ podemos utilizar los repositorios con la anotación @Autowired que se encarga de crear una instancia del objeto e inyectarlo.
Como los controladores que hemos definido aquí realizan el CRUD de las tres entidades tenemos una API completamente funcional.
package com.trifulcas.SpringBootBiblioteca.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.trifulcas.SpringBootBiblioteca.model.Genero;
import com.trifulcas.SpringBootBiblioteca.repository.GeneroRepository;
@RestController
@RequestMapping("/genero")
public class GeneroController {
@Autowired
GeneroRepository generoRepository;
@GetMapping("")
public List<Genero> getAll() {
try {
return generoRepository.findAll();
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}")
public ResponseEntity<Genero> getById(@PathVariable int id) {
System.out.println(id);
try {
Genero cat= generoRepository.findById(id).orElse(null);
if (cat!=null) {
return new ResponseEntity<>(cat, HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PostMapping("")
public Genero add(@RequestBody Genero cat) {
System.out.println(cat);
try {
if (cat.getIdgenero() == 0 && cat.getNombre() != null) {
return generoRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PutMapping("/{id}")
public Genero put(@RequestBody Genero cat, @PathVariable int id) {
System.out.println(cat);
System.out.println(id);
try {
if (cat.getIdgenero() == id) {
return generoRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@DeleteMapping("/{id}")
public int delete(@PathVariable int id) {
try {
System.out.println(id);
generoRepository.deleteById(id);
return id;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0;
}
}
}
package com.trifulcas.SpringBootBiblioteca.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.trifulcas.SpringBootBiblioteca.model.Libro;
import com.trifulcas.SpringBootBiblioteca.repository.LibroRepository;
@RestController
@RequestMapping("/libro")
public class LibroController {
@Autowired
LibroRepository libroRepository;
@GetMapping("")
public List<Libro> getAll() {
try {
return libroRepository.findAll();
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}")
public ResponseEntity<Libro> getById(@PathVariable int id) {
System.out.println(id);
try {
Libro cat= libroRepository.findById(id).orElse(null);
if (cat!=null) {
return new ResponseEntity<>(cat, HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PostMapping("")
public Libro add(@RequestBody Libro cat) {
System.out.println(cat);
try {
if (cat.getIdlibro() == 0 && cat.getTitulo() != null) {
return libroRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PutMapping("/{id}")
public Libro put(@RequestBody Libro cat, @PathVariable int id) {
System.out.println(cat);
System.out.println(id);
try {
if (cat.getIdlibro() == id) {
return libroRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@DeleteMapping("/{id}")
public int delete(@PathVariable int id) {
try {
System.out.println(id);
libroRepository.deleteById(id);
return id;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0;
}
}
}
package com.trifulcas.SpringBootBiblioteca.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.trifulcas.SpringBootBiblioteca.model.Autor;
import com.trifulcas.SpringBootBiblioteca.repository.AutorRepository;
@RestController
@RequestMapping("/autor")
public class AutorController {
@Autowired
AutorRepository autorRepository;
@GetMapping("")
public List<Autor> getAll() {
try {
return autorRepository.findAll();
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}")
public ResponseEntity<Autor> getById(@PathVariable int id) {
System.out.println(id);
try {
Autor cat= autorRepository.findById(id).orElse(null);
if (cat!=null) {
return new ResponseEntity<>(cat, HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PostMapping("")
public Autor add(@RequestBody Autor cat) {
System.out.println(cat);
try {
if (cat.getIdautor() == 0 && cat.getNombre() != null) {
return autorRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PutMapping("/{id}")
public Autor put(@RequestBody Autor cat, @PathVariable int id) {
System.out.println(cat);
System.out.println(id);
try {
if (cat.getIdautor() == id) {
return autorRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@DeleteMapping("/{id}")
public int delete(@PathVariable int id) {
try {
System.out.println(id);
autorRepository.deleteById(id);
return id;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0;
}
}
}
API Biblioteca completo (2) Repositorios
Los repositorios son nuestra capa de DAO, que nos la proporciona Spring Boot automáticamente y de manera ‘mágica’
Tenemos dos tipoos de repository, Crud y JPA. Crud solo proporciona comandos básicos de altas, bajas, modificaciones y consultas. JPA permite eso y mucho más.
package com.trifulcas.SpringBootBiblioteca.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Genero;
public interface GeneroRepository extends JpaRepository<Genero, Integer> {
}
package com.trifulcas.SpringBootBiblioteca.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Libro;
public interface LibroRepository extends JpaRepository<Libro, Integer> {
}
package com.trifulcas.SpringBootBiblioteca.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Autor;
public interface AutorRepository extends JpaRepository<Autor, Integer> {
}
API Biblioteca completo (1) Entidades
Las entidades, que son las mismas que en hibernate:
package com.trifulcas.SpringBootBiblioteca.model;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
@Entity
@Table(name = "genero")
public class Genero {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idgenero;
private String nombre;
// Carga perezosa, pero al serializar siempre carga
// Mapeamos por 'genero', que es el campo en la entidad relacionada
@OneToMany(mappedBy = "genero")
@JsonIgnore // Quitar este campo NO de la entidad SI de la srialización
private Set<Libro> libros;
// Constructor vacío
public Genero() {
}
// Constructor con parámetros
public Genero(String nombre) {
this.nombre = nombre;
}
// Getters y Setters
public int getIdgenero() {
return idgenero;
}
public void setIdgenero(int idgenero) {
this.idgenero = idgenero;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Set<Libro> getLibros() {
return libros;
}
public void setLibros(Set<Libro> libros) {
this.libros = libros;
}
// Método toString (opcional)
@Override
public String toString() {
return "Genero{" +
"idgenero=" + idgenero +
", nombre='" + nombre + '\'' +
'}';
}
}
package com.trifulcas.SpringBootBiblioteca.model;
import java.util.Set;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
@Entity
@Table(name = "libro")
public class Libro {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idlibro;
// Carga ansiosa. El nombre del campo es el mapping en genero
@ManyToOne
@JoinColumn(name = "idgenero")
private Genero genero;
private String titulo;
private int paginas;
// Cuando tenemos many to many tenemos que elegir donde montamos
// toda la relación con la especificación de la tabla intermedia
// Y los campos relacionados. Yo lo he hecho aquí pero podría ser
// en autor, es lo mismo
@ManyToMany
@JoinTable(
name = "libro_autor",
joinColumns = @JoinColumn(name = "idlibro"),
inverseJoinColumns = @JoinColumn(name = "idautor")
)
// Utilizamos set porque son valores únicos pero podría ser List
private Set<Autor> autores;
// Constructor vacío
public Libro() {
}
// Constructor con parámetros
public Libro(Genero genero, String titulo, int paginas) {
this.genero = genero;
this.titulo = titulo;
this.paginas = paginas;
}
// Getters y Setters
public int getIdlibro() {
return idlibro;
}
public void setIdlibro(int idlibro) {
this.idlibro = idlibro;
}
public Genero getGenero() {
return genero;
}
public void setGenero(Genero genero) {
this.genero = genero;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public int getPaginas() {
return paginas;
}
public void setPaginas(int paginas) {
this.paginas = paginas;
}
public Set<Autor> getAutores() {
return autores;
}
public void setAutores(Set<Autor> autores) {
this.autores = autores;
}
// Método toString (opcional)
@Override
public String toString() {
return "Libro{" +
"idlibro=" + idlibro +
", genero=" + genero +
", titulo='" + titulo + '\'' +
", paginas=" + paginas +
'}';
}
}
package com.trifulcas.SpringBootBiblioteca.model;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
@Entity
@Table(name = "autor")
public class Autor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idautor;
private String nombre;
// Como todas las indicaciones de tablas intermedias y foreign keys
// Las hemos puesto en libro aquí podemos usar solo autores
@ManyToMany(mappedBy = "autores")
@JsonIgnore // Para evitar bucles infinitos
private Set<Libro> libros;
// Constructor vacío
public Autor() {
}
// Constructor con parámetros
public Autor(String nombre) {
this.nombre = nombre;
}
// Getters y Setters
public int getIdautor() {
return idautor;
}
public void setIdautor(int idautor) {
this.idautor = idautor;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Set<Libro> getLibros() {
return libros;
}
public void setLibros(Set<Libro> libros) {
this.libros = libros;
}
// Método toString (opcional)
@Override
public String toString() {
return "Autor{" +
"idautor=" + idautor +
", nombre='" + nombre + '\'' +
'}';
}
}
Entidades Biblioteca
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.OneToMany;
import java.util.Set;
@Entity
@Table(name = "genero")
public class Genero {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idgenero;
private String nombre;
@OneToMany(mappedBy = "genero")
private Set<Libro> libros;
// Constructor vacío
public Genero() {
}
// Constructor con parámetros
public Genero(String nombre) {
this.nombre = nombre;
}
// Getters y Setters
public int getIdgenero() {
return idgenero;
}
public void setIdgenero(int idgenero) {
this.idgenero = idgenero;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Set<Libro> getLibros() {
return libros;
}
public void setLibros(Set<Libro> libros) {
this.libros = libros;
}
// Método toString (opcional)
@Override
public String toString() {
return "Genero{" +
"idgenero=" + idgenero +
", nombre='" + nombre + '\'' +
'}';
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;
import javax.persistence.Column;
import java.util.Set;
@Entity
@Table(name = "libro")
public class Libro {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idlibro;
@ManyToOne
@JoinColumn(name = "idgenero")
private Genero genero;
private String titulo;
private int paginas;
@ManyToMany
@JoinTable(
name = "libro_autor",
joinColumns = @JoinColumn(name = "idlibro"),
inverseJoinColumns = @JoinColumn(name = "idautor")
)
private Set<Autor> autores;
// Constructor vacío
public Libro() {
}
// Constructor con parámetros
public Libro(Genero genero, String titulo, int paginas) {
this.genero = genero;
this.titulo = titulo;
this.paginas = paginas;
}
// Getters y Setters
public int getIdlibro() {
return idlibro;
}
public void setIdlibro(int idlibro) {
this.idlibro = idlibro;
}
public Genero getGenero() {
return genero;
}
public void setGenero(Genero genero) {
this.genero = genero;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public int getPaginas() {
return paginas;
}
public void setPaginas(int paginas) {
this.paginas = paginas;
}
public Set<Autor> getAutores() {
return autores;
}
public void setAutores(Set<Autor> autores) {
this.autores = autores;
}
// Método toString (opcional)
@Override
public String toString() {
return "Libro{" +
"idlibro=" + idlibro +
", genero=" + genero +
", titulo='" + titulo + '\'' +
", paginas=" + paginas +
'}';
}
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import java.util.Set;
@Entity
@Table(name = "autor")
public class Autor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idautor;
private String nombre;
@ManyToMany(mappedBy = "autores")
private Set<Libro> libros;
// Constructor vacío
public Autor() {
}
// Constructor con parámetros
public Autor(String nombre) {
this.nombre = nombre;
}
// Getters y Setters
public int getIdautor() {
return idautor;
}
public void setIdautor(int idautor) {
this.idautor = idautor;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public Set<Libro> getLibros() {
return libros;
}
public void setLibros(Set<Libro> libros) {
this.libros = libros;
}
// Método toString (opcional)
@Override
public String toString() {
return "Autor{" +
"idautor=" + idautor +
", nombre='" + nombre + '\'' +
'}';
}
}
Biblioteca Genero
package com.trifulcas.SpringBootBiblioteca.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "genero")
public class Genero {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int idgenero;
private String nombre;
// Constructor vacío
public Genero() {
}
// Constructor con parámetros
public Genero(String nombre) {
this.nombre = nombre;
}
// Getters y Setters
public int getIdgenero() {
return idgenero;
}
public void setIdgenero(int idgenero) {
this.idgenero = idgenero;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
// Método toString (opcional)
@Override
public String toString() {
return "Genero{" +
"idgenero=" + idgenero +
", nombre='" + nombre + '\'' +
'}';
}
}
package com.trifulcas.SpringBootBiblioteca.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.trifulcas.SpringBootBiblioteca.model.Genero;
public interface GeneroRepository extends JpaRepository<Genero, Integer> {
}
package com.trifulcas.SpringBootBiblioteca.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.trifulcas.SpringBootBiblioteca.model.Genero;
import com.trifulcas.SpringBootBiblioteca.repository.GeneroRepository;
@RestController
@RequestMapping("/genero")
public class GeneroController {
@Autowired
GeneroRepository generoRepository;
@GetMapping("")
public List<Genero> getAll() {
try {
return generoRepository.findAll();
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}")
public ResponseEntity<Genero> getById(@PathVariable int id) {
System.out.println(id);
try {
Genero cat= generoRepository.findById(id).orElse(null);
if (cat!=null) {
return new ResponseEntity<>(cat, HttpStatus.OK);
}
else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PostMapping("")
public Genero add(@RequestBody Genero cat) {
System.out.println(cat);
try {
if (cat.getIdgenero() == 0 && cat.getNombre() != null) {
return generoRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PutMapping("/{id}")
public Genero put(@RequestBody Genero cat, @PathVariable int id) {
System.out.println(cat);
System.out.println(id);
try {
if (cat.getIdgenero() == id) {
return generoRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@DeleteMapping("/{id}")
public int delete(@PathVariable int id) {
try {
System.out.println(id);
generoRepository.deleteById(id);
return id;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0;
}
}
}
Swagger
Añadimos la siguiente dependencia:
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.3.0</version> </dependency>
Y vamos a la siguiente url:
http://localhost:8080/swagger-ui/index.html
API Rest completa
package com.trifulcas.SpringBootAPI.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.trifulcas.SpringBootAPI.model.Category;
import com.trifulcas.SpringBootAPI.repository.CategoryRepository;
@RestController
@RequestMapping("/category")
public class CategoryController {
@Autowired
CategoryRepository categoryRepository;
@GetMapping("")
public List<Category> getAll() {
try {
return categoryRepository.findAll();
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
// Poner los valores en la URL, no parámetros nombrados
@GetMapping("/{id}")
public Category getById(@PathVariable int id) {
System.out.println(id);
try {
return categoryRepository.findById(id).orElse(null);
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PostMapping("")
public Category add(@RequestBody Category cat) {
System.out.println(cat);
try {
if (cat.getCategoryId() == 0 && cat.getName() != null) {
return categoryRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@PutMapping("/{id}")
public Category put(@RequestBody Category cat, @PathVariable int id) {
System.out.println(cat);
System.out.println(id);
try {
if (cat.getCategoryId() == id) {
return categoryRepository.save(cat);
} else {
return null;
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
return null;
}
}
@DeleteMapping("/{id}")
public int delete(@PathVariable int id) {
try {
System.out.println(id);
categoryRepository.deleteById(id);
return id;
} catch (Exception ex) {
System.out.println(ex.getMessage());
return 0;
}
}
}