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 + '\'' + '}'; } }
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.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import com.trifulcas.SpringBootBiblioteca.model.Autor; import com.trifulcas.SpringBootBiblioteca.model.Genero; public interface AutorRepository extends JpaRepository<Autor, Integer> { List<Genero> findByLibrosGeneroNombreContaining(String cad); List<Autor> findByLibrosTituloContaining(String cad); }
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); }
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); List<Libro> findByAutoresIdautor(Integer id); List<Libro> findByTituloContaining(String cadena); }
package com.trifulcas.SpringBootBiblioteca.controller; import java.util.List; import java.util.Set; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.trifulcas.SpringBootBiblioteca.model.Genero; import com.trifulcas.SpringBootBiblioteca.model.Libro; import com.trifulcas.SpringBootBiblioteca.repository.GeneroRepository; @RestController @RequestMapping("/genero") public class GeneroController { @Autowired GeneroRepository generoRepository; @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; } } // 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; } } // 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; } } @PostMapping("/nuevo/{nombre}") public Genero addNuevo(@PathVariable String nombre) { try { System.out.println(nombre); Genero nuevo = new Genero(nombre); generoRepository.save(nuevo); return nuevo; } 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 java.util.Set; 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.model.Libro; 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 new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED); } } // 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; } } // Poner los valores en la URL, no parámetros nombrados @GetMapping("/titulo/{cadena}") public List<Autor> getAutoresByTitulo(@PathVariable String cadena) { System.out.println(cadena); try { return autorRepository.findByLibrosTituloContaining(cadena); } 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; } } }
package com.trifulcas.SpringBootBiblioteca.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.trifulcas.SpringBootBiblioteca.model.Autor; import com.trifulcas.SpringBootBiblioteca.model.Libro; import com.trifulcas.SpringBootBiblioteca.repository.AutorRepository; import com.trifulcas.SpringBootBiblioteca.repository.LibroRepository; @RestController @RequestMapping("/libro") public class LibroController { @Autowired LibroRepository libroRepository; @Autowired AutorRepository autorRepository; @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(Math.min(min, max),Math.max(min, max)); } }catch (Exception ex) { System.out.println(ex.getMessage()); return null; } } @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; } } @GetMapping("/titulo/{cadena}") public List<Libro> getByTitle(@PathVariable String cadena) { System.out.println(cadena); try { return libroRepository.findByTituloContaining(cadena); } 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; } } // 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; } } }