Ejercicio Colección de funkos

Mi hija quiere hacer una base de datos para guardar su colección de funkos. Los funkos están organizados en colecciones, que tienen un nombre de la colección y el nombre del diseñador. Un funko solo pertenece a una colección. De cada funko queremos guardar el Nombre, Precio, Número,Estilo, Fecha de lanzamiento y Tamaño.

La mayoría de los funkos son de productos audiovisuales (series, películas…). Nos interesa conocer el título de ese producto, la fecha de emisión, la nacionalidad y el número de temporadas.

colecciones  1—N funko  N—1 audiovisuales
Modelo lógico

coleccion
———-
idcoleccion int
nombre varchar(150)
disenyador varchar(150)

funko
—–
idfunko int
idcoleccion int
idaudiovisual int
nombre varchar(150)
precio decimal
numero smallint
estilo varchar(150)
lanzamiento date
tamanyo varchar

audiovisual
———–
idaudiovisual int
titulo varchar(150)
emision date
nacionalidad varchar(150)
temporadas smallint

CREATE TABLE `coleccion` (
  `idcoleccion` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `nombre` varchar(150) DEFAULT NULL,
  `disenyador` varchar(150) DEFAULT NULL,
  PRIMARY KEY (`idcoleccion`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `audiovisual` (
  `idaudiovisual` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `titulo` varchar(150) DEFAULT NULL,
  `emision` date DEFAULT NULL,
  `nacionalidad` varchar(150) DEFAULT NULL,
  `temporadas` smallint(6) DEFAULT NULL,
  PRIMARY KEY (`idaudiovisual`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `funko` (
  `idfunko` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `idcoleccion` int(11) unsigned DEFAULT NULL,
  `idaudiovisual` int(11) unsigned DEFAULT NULL,
  `nombre` varchar(150) DEFAULT NULL,
  `precio` decimal(8,2) DEFAULT NULL,
  `numero` smallint(6) DEFAULT NULL,
  `estilo` varchar(150) DEFAULT NULL,
  `lanzamiento` date DEFAULT NULL,
  `tamanyo` varchar(150) DEFAULT NULL,
  PRIMARY KEY (`idfunko`),
  KEY `fk_coleccion_idx` (`idcoleccion`),
  KEY `fk_audiovisual_idx` (`idaudiovisual`),
  CONSTRAINT `fk_audiovisual` FOREIGN KEY (`idaudiovisual`) REFERENCES `audiovisual` (`idaudiovisual`) ON UPDATE NO ACTION,
  CONSTRAINT `fk_coleccion` FOREIGN KEY (`idcoleccion`) REFERENCES `coleccion` (`idcoleccion`) ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

Datos de prueba:

INSERT INTO `coleccion` (`nombre`, `disenyador`) VALUES
('Star Wars: Original Trilogy', 'John Doe'),
('Marvel Avengers', 'Jane Smith'),
('Harry Potter', 'Robert Brown'),
('Game of Thrones', 'Emily White'),
('The Walking Dead', 'Michael Green'),
('Disney Classics', 'Sarah Black'),
('DC Comics Superheroes', 'Thomas Blue'),
('Stranger Things', 'Olivia Purple'),
('Rick and Morty', 'Daniel Red'),
('The Simpsons', 'Jessica Pink'),
('Dragon Ball Z', 'Matthew Yellow'),
('Naruto Shippuden', 'Sophia Orange'),
('One Piece', 'James Violet'),
('Pokemon', 'Emma Indigo'),
('Lord of the Rings', 'Christopher Teal'),
('The Office', 'Isabella Grey'),
('Friends', 'Benjamin Azure'),
('My Hero Academia', 'Mia Lime'),
('Overwatch', 'Elijah Olive'),
('Fortnite', 'Charlotte Cyan');

INSERT INTO `audiovisual` (`titulo`, `emision`, `nacionalidad`, `temporadas`) VALUES
('Breaking Bad', '2008-01-20', 'USA', 5),
('Stranger Things', '2016-07-15', 'USA', 4),
('Game of Thrones', '2011-04-17', 'USA', 8),
('Narcos', '2015-08-28', 'USA', 3),
('The Crown', '2016-11-04', 'UK', 4),
('La Casa de Papel', '2017-05-02', 'Spain', 5),
('Dark', '2017-12-01', 'Germany', 3),
('Money Heist', '2017-05-02', 'Spain', 5),
('The Mandalorian', '2019-11-12', 'USA', 2),
('The Witcher', '2019-12-20', 'USA', 2),
('Friends', '1994-09-22', 'USA', 10),
('The Office', '2005-03-24', 'USA', 9),
('Sherlock', '2010-07-25', 'UK', 4),
('Black Mirror', '2011-12-04', 'UK', 5),
('The Simpsons', '1989-12-17', 'USA', 32),
('Rick and Morty', '2013-12-02', 'USA', 5),
('Naruto Shippuden', '2007-02-15', 'Japan', 21),
('One Piece', '1999-10-20', 'Japan', 20),
('Dragon Ball Z', '1989-04-26', 'Japan', 9),
('Attack on Titan', '2013-04-07', 'Japan', 4);

INSERT INTO `funko` (`idcoleccion`, `idaudiovisual`, `nombre`, `precio`, `numero`, `estilo`, `lanzamiento`, `tamanyo`) VALUES
(1, 3, 'Darth Vader', 12.99, 1, 'Vinyl', '2018-05-04', 'Standard'),
(1, 3, 'Luke Skywalker', 12.99, 2, 'Vinyl', '2018-05-04', 'Standard'),
(2, 10, 'Iron Man', 14.99, 3, 'Vinyl', '2019-04-26', 'Standard'),
(2, 10, 'Captain America', 14.99, 4, 'Vinyl', '2019-04-26', 'Standard'),
(3, 7, 'Harry Potter', 11.99, 5, 'Vinyl', '2017-07-31', 'Standard'),
(3, 7, 'Hermione Granger', 11.99, 6, 'Vinyl', '2017-07-31', 'Standard'),
(4, 2, 'Jon Snow', 13.99, 7, 'Vinyl', '2019-04-14', 'Standard'),
(4, 2, 'Daenerys Targaryen', 13.99, 8, 'Vinyl', '2019-04-14', 'Standard'),
(5, 1, 'Rick Grimes', 10.99, 9, 'Vinyl', '2018-10-07', 'Standard'),
(5, 1, 'Daryl Dixon', 10.99, 10, 'Vinyl', '2018-10-07', 'Standard'),
(6, 19, 'Mickey Mouse', 9.99, 11, 'Vinyl', '2019-11-18', 'Standard'),
(6, 19, 'Donald Duck', 9.99, 12, 'Vinyl', '2019-11-18', 'Standard'),
(7, 11, 'Batman', 12.99, 13, 'Vinyl', '2019-03-01', 'Standard'),
(7, 11, 'Superman', 12.99, 14, 'Vinyl', '2019-03-01', 'Standard'),
(8, 2, 'Eleven', 14.99, 15, 'Vinyl', '2019-07-04', 'Standard'),
(8, 2, 'Jim Hopper', 14.99, 16, 'Vinyl', '2019-07-04', 'Standard'),
(9, 17, 'Rick', 13.49, 17, 'Vinyl', '2020-09-20', 'Standard'),
(9, 17, 'Morty', 13.49, 18, 'Vinyl', '2020-09-20', 'Standard'),
(10, 12, 'Homer Simpson', 11.49, 19, 'Vinyl', '2019-09-29', 'Standard'),
(10, 12, 'Bart Simpson', 11.49, 20, 'Vinyl', '2019-09-29', 'Standard'),
(11, 14, 'Goku', 12.49, 21, 'Vinyl', '2018-11-18', 'Standard'),
(11, 14, 'Vegeta', 12.49, 22, 'Vinyl', '2018-11-18', 'Standard'),
(12, 16, 'Naruto Uzumaki', 13.99, 23, 'Vinyl', '2019-02-15', 'Standard'),
(12, 16, 'Sasuke Uchiha', 13.99, 24, 'Vinyl', '2019-02-15', 'Standard'),
(13, 18, 'Monkey D. Luffy', 14.49, 25, 'Vinyl', '2020-05-20', 'Standard'),
(13, 18, 'Roronoa Zoro', 14.49, 26, 'Vinyl', '2020-05-20', 'Standard'),
(14, 15, 'Pikachu', 9.99, 27, 'Vinyl', '2019-07-06', 'Standard'),
(14, 15, 'Charmander', 9.99, 28, 'Vinyl', '2019-07-06', 'Standard'),
(15, 5, 'Frodo Baggins', 11.99, 29, 'Vinyl', '2018-12-19', 'Standard'),
(15, 5, 'Gandalf', 11.99, 30, 'Vinyl', '2018-12-19', 'Standard'),
(16, 8, 'Michael Scott', 10.99, 31, 'Vinyl', '2019-10-07', 'Standard'),
(16, 8, 'Dwight Schrute', 10.99, 32, 'Vinyl', '2019-10-07', 'Standard'),
(17, 9, 'Rachel Green', 11.99, 33, 'Vinyl', '2019-05-01', 'Standard'),
(17, 9, 'Ross Geller', 11.99, 34, 'Vinyl', '2019-05-01', 'Standard'),
(18, 4, 'Izuku Midoriya', 14.99, 35, 'Vinyl', '2020-03-15', 'Standard'),
(18, 4, 'Katsuki Bakugo', 14.99, 36, 'Vinyl', '2020-03-15', 'Standard'),
(19, 13, 'Tracer', 12.99, 37, 'Vinyl', '2019-10-10', 'Standard'),
(19, 13, 'Reaper', 12.99, 38, 'Vinyl', '2019-10-10', 'Standard'),
(20, 6, 'Jonesy', 11.49, 39, 'Vinyl', '2019-06-05', 'Standard'),
(20, 6, 'Raven', 11.49, 40, 'Vinyl', '2019-06-05', 'Standard'),
(1, 3, 'Boba Fett', 14.99, 41, 'Vinyl', '2019-12-05', 'Standard'),
(1, 3, 'Princess Leia', 14.99, 42, 'Vinyl', '2019-12-05', 'Standard'),
(2, 10, 'Thor', 15.99, 43, 'Vinyl', '2020-02-20', 'Standard'),
(2, 10, 'Hulk', 15.99, 44, 'Vinyl', '2020-02-20', 'Standard'),
(3, 7, 'Ron Weasley', 11.99, 45, 'Vinyl', '2018-08-31', 'Standard'),
(3, 7, 'Albus Dumbledore', 11.99, 46, 'Vinyl', '2018-08-31', 'Standard'),
(4, 2, 'Tyrion Lannister', 13.99, 47, 'Vinyl', '2018-03-25', 'Standard'),
(4, 2, 'Arya Stark', 13.99, 48, 'Vinyl', '2018-03-25', 'Standard'),
(5, 1, 'Michonne', 10.99, 49, 'Vinyl', '2017-04-06', 'Standard'),
(5, 1, 'Negan', 10.99, 50, 'Vinyl', '2017-04-06', 'Standard');

Ejemplo modificar datos:

UPDATE `funko` SET `estilo` = 'Metallic' WHERE `idfunko` = 1;
UPDATE `funko` SET `estilo` = 'Glow in the Dark' WHERE `idfunko` = 2;
UPDATE `funko` SET `estilo` = 'Flocked' WHERE `idfunko` = 3;
UPDATE `funko` SET `estilo` = 'Diamond' WHERE `idfunko` = 4;
UPDATE `funko` SET `estilo` = 'Chrome' WHERE `idfunko` = 5;
UPDATE `funko` SET `estilo` = 'Pearlescent' WHERE `idfunko` = 6;
UPDATE `funko` SET `estilo` = 'Translucent' WHERE `idfunko` = 7;
UPDATE `funko` SET `estilo` = 'Glitter' WHERE `idfunko` = 8;
UPDATE `funko` SET `estilo` = 'Wooden' WHERE `idfunko` = 9;
UPDATE `funko` SET `estilo` = '8-Bit' WHERE `idfunko` = 10;
UPDATE `funko` SET `estilo` = 'Retro' WHERE `idfunko` = 11;
UPDATE `funko` SET `estilo` = 'Vintage' WHERE `idfunko` = 12;
UPDATE `funko` SET `estilo` = 'Chibi' WHERE `idfunko` = 13;
UPDATE `funko` SET `estilo` = 'Pixel' WHERE `idfunko` = 14;
UPDATE `funko` SET `estilo` = 'Steampunk' WHERE `idfunko` = 15;
UPDATE `funko` SET `estilo` = 'Graffiti' WHERE `idfunko` = 16;
UPDATE `funko` SET `estilo` = 'Art Series' WHERE `idfunko` = 17;
UPDATE `funko` SET `estilo` = 'Metallic Gold' WHERE `idfunko` = 18;
UPDATE `funko` SET `estilo` = 'Bronze' WHERE `idfunko` = 19;
UPDATE `funko` SET `estilo` = 'Silver' WHERE `idfunko` = 20;

UPDATE `funko` SET `tamanyo` = 'Large' WHERE `idfunko` = 1;
UPDATE `funko` SET `tamanyo` = 'Small' WHERE `idfunko` = 2;
UPDATE `funko` SET `tamanyo` = 'Mini' WHERE `idfunko` = 3;
UPDATE `funko` SET `tamanyo` = 'Jumbo' WHERE `idfunko` = 4;
UPDATE `funko` SET `tamanyo` = 'Super Sized' WHERE `idfunko` = 5;
UPDATE `funko` SET `tamanyo` = 'Pocket' WHERE `idfunko` = 6;
UPDATE `funko` SET `tamanyo` = 'Mega' WHERE `idfunko` = 7;
UPDATE `funko` SET `tamanyo` = 'Giant' WHERE `idfunko` = 8;
UPDATE `funko` SET `tamanyo` = 'Titan' WHERE `idfunko` = 9;
UPDATE `funko` SET `tamanyo` = 'Colossal' WHERE `idfunko` = 10;
UPDATE `funko` SET `tamanyo` = 'Compact' WHERE `idfunko` = 11;
UPDATE `funko` SET `tamanyo` = 'Petite' WHERE `idfunko` = 12;
UPDATE `funko` SET `tamanyo` = 'Grand' WHERE `idfunko` = 13;
UPDATE `funko` SET `tamanyo` = 'Tiny' WHERE `idfunko` = 14;
UPDATE `funko` SET `tamanyo` = 'Massive' WHERE `idfunko` = 15;
UPDATE `funko` SET `tamanyo` = 'Huge' WHERE `idfunko` = 16;
UPDATE `funko` SET `tamanyo` = 'Enormous' WHERE `idfunko` = 17;
UPDATE `funko` SET `tamanyo` = 'Oversized' WHERE `idfunko` = 18;
UPDATE `funko` SET `tamanyo` = 'Immense' WHERE `idfunko` = 19;
UPDATE `funko` SET `tamanyo` = 'Gargantuan' WHERE `idfunko` = 20;

UPDATE `funko` SET `estilo` = 'Diamond' WHERE `idfunko` between 20 and 25;
UPDATE `funko` SET `estilo` = 'Glitter' WHERE `idfunko` between 25 and 30;
UPDATE `funko` SET `estilo` = 'Steampunk' WHERE `idfunko` between 30 and 40;
UPDATE `funko` SET `estilo` = 'Metallic' WHERE `idfunko` >40;

UPDATE `funko` SET `tamanyo` = 'Small' WHERE `idfunko` between 20 and 25;
UPDATE `funko` SET `tamanyo` = 'Compact' WHERE `idfunko` between 25 and 30;
UPDATE `funko` SET `tamanyo` = 'Large' WHERE `idfunko` between 30 and 40;
UPDATE `funko` SET `tamanyo` = 'Oversized' WHERE `idfunko`>40;

Consultas

-- Consultas con condiciones simples
-- audiovisuales con más de 5 temporadas
select * from audiovisual where temporadas>5;
-- funkos que tengan una 'h' en el nombre
select * from funko where nombre like '%h%';
-- colecciones de diseñadores cuyo nombre empiece por 'M'
select * from coleccion where disenyador like 'm%';

-- Consultas con joins
-- Todos los funkos de la colección 'friends'
select funko.* from coleccion join funko on coleccion.idcoleccion=funko.idcoleccion
where coleccion.nombre='friends';
-- Todos los funkos del audiovisual 'one piece'
select funko.* from audiovisual join funko on audiovisual.idaudiovisual=funko.idaudiovisual
where titulo='one piece';
-- Todos los funkos de la colección o el audiovisual 'friends'
select f.* from funko f join coleccion c on f.idcoleccion=c.idcoleccion
join audiovisual a on f.idaudiovisual=a.idaudiovisual
where c.nombre='friends' or a.titulo='friends';

-- Consultas agrupadas
-- Total de funkos por colección
select coleccion.*, count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion;

-- Total de funkos por audiovisual
select audiovisual.*, count(idfunko) total
from audiovisual join funko using(idaudiovisual)
group by idaudiovisual;
-- Total de funkos por estilos ordenados de mayor a  menor
select estilo,count(idfunko) total
from funko
group by estilo
order by total desc, estilo desc;

-- Media de precio de todos los funkos
select avg(precio) from funko;

-- Total de precios (suma) por tamaño
select tamanyo,sum(precio) total
from funko
group by tamanyo;
-- Colecciones con más de 10 funkos (no sé si hay)
select coleccion.*, count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion
having total>=4;

-- Subconsultas y división
-- Coleccion (o colecciones) con mayor número de funkos

select coleccion.*, count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion
having total=(maximo);


select max(total) total from (
select count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion) foo;

select count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion
order by total desc
limit 1 ;

-- Junto la primera con alguna de las segundas y voila
select coleccion.*, count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion
having total=(select count(idfunko) total
from coleccion left join funko using(idcoleccion)
group by idcoleccion
order by total desc
limit 1);
-- Lo mismo para audiovisual

select audiovisual.*, count(idfunko) total
from audiovisual left join funko using(idaudiovisual)
group by idaudiovisual
having total=(select count(idfunko) total
from audiovisual left join funko using(idaudiovisual)
group by idaudiovisual
order by total desc
limit 1);


-- Funkos cuyo precio esté por encima de la media

-- calculo la media

select avg(precio) from funko;

select * from funko
where precio>(select avg(precio) from funko);

-- Consultas con funciones
-- Todos los funkos lanzados en febrero
select * from funko
where month(lanzamiento)=2;
-- Total de funkos por año
select year(lanzamiento) anyo,count(idfunko) total
from funko
group by year(lanzamiento);
-- Funkos cuyo nombre tenga una longitud mayor de 12 letras
select * from funko
where length(nombre)>12;
-- Funkos lanzados en 2020 o cuyo audiovisual se emitió en 2020
select * from funko join 
audiovisual on funko.idaudiovisual=audiovisual.idaudiovisual
where year(lanzamiento)=2020 or year(emision)=2020;

Consultas agregadas

Aquí tienes algunos ejemplos de consultas de agregación en MongoDB utilizando la colección de libros que has proporcionado:

1. Buscar libros por género y ordenar por fecha de publicación

db.libros.aggregate([
    { $match: { genero: "Novela" } },
    { $sort: { fecha_publicacion: 1 } }
])

2. Contar el número de libros por cada género

db.libros.aggregate([
    { $group: { _id: "$genero", total: { $sum: 1 } } },
    { $sort: { total: -1 } }
])

3. Encontrar el libro más antiguo y el más reciente

db.libros.aggregate([
    { $group: {
        _id: null,
        mas_antiguo: { $min: "$fecha_publicacion" },
        mas_reciente: { $max: "$fecha_publicacion" }
    } }
])

4. Calcular el número promedio de años desde la publicación de los libros hasta la fecha actual

db.libros.aggregate([
    { $project: {
        titulo: 1,
        años_desde_publicacion: { $subtract: [new Date(), "$fecha_publicacion"] }
    } },
    { $group: {
        _id: null,
        promedio_años: { $avg: { $divide: ["$años_desde_publicacion", 1000 * 60 * 60 * 24 * 365] } }
    } }
])

5. Encontrar libros publicados por una editorial específica y contar cuántos hay

db.libros.aggregate([
    { $match: { editorial: "Viking Press" } },
    { $count: "total_libros" }
])

6. Listar los libros publicados después de 1950 y ordenarlos por fecha de publicación en orden descendente

db.libros.aggregate([
    { $match: { fecha_publicacion: { $gt: new Date("1950-01-01") } } },
    { $sort: { fecha_publicacion: -1 } }
])

7. Agrupar los libros por autor y listar los títulos de los libros que han escrito

db.libros.aggregate([
    { $group: {
        _id: "$autor",
        libros: { $push: "$titulo" }
    } }
])

8. Calcular la cantidad de libros publicados por década

db.libros.aggregate([
    { $project: {
        decada: { $substr: [ { $year: "$fecha_publicacion" }, 0, 3 ] }
    } },
    { $group: {
        _id: { $concat: ["$_id", "0s"] },
        total: { $sum: 1 }
    } }
])

9. Filtrar libros que tienen la palabra “El” en el título

db.libros.aggregate([
    { $match: { titulo: { $regex: /El/, $options: "i" } } }
])

10. Contar libros por autor y ordenar los autores por el número de libros en orden descendente

db.libros.aggregate([
    { $group: {
        _id: "$autor",
        total_libros: { $sum: 1 }
    } },
    { $sort: { total_libros: -1 } }
])

Estos ejemplos muestran cómo utilizar las funcionalidades de agregación de MongoDB para realizar consultas complejas y obtener información específica de la colección de libros.

Proyecciones

Por supuesto, las proyecciones en MongoDB se utilizan para incluir o excluir campos específicos en los documentos devueltos por una consulta. Aquí tienes varios ejemplos de consultas con proyecciones utilizando la colección libros:

1. Incluir solo el campo titulo

db.libros.find({}, { titulo: 1, _id: 0 }).pretty()

2. Incluir solo los campos titulo y autor

db.libros.find({}, { titulo: 1, autor: 1, _id: 0 }).pretty()

3. Excluir el campo editorial

db.libros.find({}, { editorial: 0 }).pretty()

4. Incluir solo los campos tituloautor y fecha_publicacion

db.libros.find({}, { titulo: 1, autor: 1, fecha_publicacion: 1, _id: 0 }).pretty()

5. Incluir solo el campo genero

db.libros.find({}, { genero: 1, _id: 0 }).pretty()

6. Incluir solo el campo titulo y obtener los libros ordenados por fecha_publicacion (ascendente)

db.libros.find({}, { titulo: 1, _id: 0 }).sort({ fecha_publicacion: 1 }).pretty()

7. Excluir el campo _id

db.libros.find({}, { _id: 0 }).pretty()

8. Incluir solo los campos titulo y fecha_publicacion para libros de un autor específico

db.libros.find({ autor: "George Orwell" }, { titulo: 1, fecha_publicacion: 1, _id: 0 }).pretty()

9. Incluir solo los campos titulo y genero para libros publicados después de 1950

db.libros.find({ fecha_publicacion: { $gt: new Date("1950-01-01") } }, { titulo: 1, genero: 1, _id: 0 }).pretty()

10. Incluir solo el campo autor y contar cuántos libros tiene cada autor (proyección con agregación)

db.libros.aggregate([
    { $group: { _id: "$autor", total: { $sum: 1 } } },
    { $project: { autor: "$_id", total: 1, _id: 0 } }
])

11. Incluir solo los campos titulo y editorial para libros de un género específico

db.libros.find({ genero: "Realismo Mágico" }, { titulo: 1, editorial: 1, _id: 0 }).pretty()

12. Incluir solo los campos titulo y fecha_publicacion y excluir libros publicados antes de 1950

db.libros.find({ fecha_publicacion: { $gte: new Date("1950-01-01") } }, { titulo: 1, fecha_publicacion: 1, _id: 0 }).pretty()

13. Incluir solo el campo titulo y mostrar los libros en orden descendente de fecha_publicacion

db.libros.find({}, { titulo: 1, _id: 0 }).sort({ fecha_publicacion: -1 }).pretty()

14. Incluir solo los campos tituloautor y genero para libros de una editorial específica

db.libros.find({ editorial: "Viking Press" }, { titulo: 1, autor: 1, genero: 1, _id: 0 }).pretty()

15. Incluir solo el campo genero y contar cuántos libros hay en cada género (proyección con agregación)

db.libros.aggregate([
    { $group: { _id: "$genero", total: { $sum: 1 } } },
    { $project: { genero: "$_id", total: 1, _id: 0 } }
])

Estas proyecciones te permiten controlar qué campos se devuelven en los resultados de tus consultas, lo cual es útil para optimizar el rendimiento y la claridad de los datos que necesitas.

Ejemplos consultas MOngoDB

Claro, aquí tienes varios ejemplos de consultas que puedes realizar sobre la base de datos biblioteca y la colección libros:

1. Obtener todos los libros

db.libros.find().pretty()

2. Obtener un libro específico por su título

db.libros.findOne({ titulo: "1984" })

3. Obtener todos los libros de un autor específico

db.libros.find({ autor: "Gabriel García Márquez" }).pretty()

4. Obtener todos los libros publicados antes de un año específico

db.libros.find({ fecha_publicacion: { $lt: new Date("1950-01-01") } }).pretty()

5. Obtener todos los libros de un género específico

db.libros.find({ genero: "Fantasía" }).pretty()

6. Contar el número de libros en la colección

db.libros.countDocuments()

7. Obtener todos los libros ordenados por fecha de publicación (ascendente)

db.libros.find().sort({ fecha_publicacion: 1 }).pretty()

8. Obtener todos los libros ordenados por fecha de publicación (descendente)

db.libros.find().sort({ fecha_publicacion: -1 }).pretty()

9. Obtener todos los libros de un autor específico y ordenarlos por fecha de publicación

db.libros.find({ autor: "Gabriel García Márquez" }).sort({ fecha_publicacion: 1 }).pretty()

10. Obtener libros con un rango específico de fechas de publicación

db.libros.find({ 
    fecha_publicacion: { 
        $gte: new Date("1930-01-01"), 
        $lte: new Date("1950-12-31") 
    } 
}).pretty()

11. Actualizar el género de un libro específico

db.libros.updateOne(
    { titulo: "El Gran Gatsby" },
    { $set: { genero: "Novela Trágica" } }
)

12. Actualizar el autor de varios libros

db.libros.updateMany(
    { autor: "Gabriel García Márquez" },
    { $set: { autor: "G. García Márquez" } }
)

13. Eliminar un libro por su título

db.libros.deleteOne({ titulo: "La Metamorfosis" })

14. Eliminar todos los libros de un autor específico

db.libros.deleteMany({ autor: "G. García Márquez" })

15. Obtener libros con títulos que contengan una palabra específica (búsqueda por patrón)

db.libros.find({ titulo: /Cien/ }).pretty()

16. Obtener todos los libros publicados en un año específico

db.libros.find({ fecha_publicacion: { $gte: new Date("1967-01-01"), $lt: new Date("1968-01-01") } }).pretty()

17. Obtener todos los libros de una editorial específica

db.libros.find({ editorial: "Viking Press" }).pretty()

18. Agrupar libros por género y contar cuántos hay en cada grupo

db.libros.aggregate([
    { $group: { _id: "$genero", total: { $sum: 1 } } }
])

19. Encontrar libros cuyo título comienza con una letra específica

db.libros.find({ titulo: /^E/ }).pretty()

20. Obtener libros que no pertenezcan a un género específico

db.libros.find({ genero: { $ne: "Fantasía" } }).pretty()

Estas consultas te permiten explorar y manipular la colección libros de diversas maneras, proporcionando una base sólida para trabajar con tus datos en MongoDB.

Ejemplos básicos mongodb

Comandos para crear la base de datos y la colección

Crea la base de datos y la colección:

use biblioteca

db.createCollection("libros")

Comandos para insertar 10 documentos de prueba

A continuación, insertarás 10 documentos con los campos tituloautorfecha_publicaciongenero, y editorial.

db.libros.insertMany([
    { titulo: "Cien Años de Soledad", autor: "Gabriel García Márquez", fecha_publicacion: new Date("1967-05-30"), genero: "Realismo Mágico", editorial: "Sudamericana" },
    { titulo: "Don Quijote de la Mancha", autor: "Miguel de Cervantes", fecha_publicacion: new Date("1605-01-16"), genero: "Novela", editorial: "Francisco de Robles" },
    { titulo: "1984", autor: "George Orwell", fecha_publicacion: new Date("1949-06-08"), genero: "Distopía", editorial: "Secker & Warburg" },
    { titulo: "Matar a un ruiseñor", autor: "Harper Lee", fecha_publicacion: new Date("1960-07-11"), genero: "Drama", editorial: "J.B. Lippincott & Co." },
    { titulo: "El Gran Gatsby", autor: "F. Scott Fitzgerald", fecha_publicacion: new Date("1925-04-10"), genero: "Tragedia", editorial: "Charles Scribner's Sons" },
    { titulo: "Orgullo y Prejuicio", autor: "Jane Austen", fecha_publicacion: new Date("1813-01-28"), genero: "Romance", editorial: "T. Egerton" },
    { titulo: "En el camino", autor: "Jack Kerouac", fecha_publicacion: new Date("1957-09-05"), genero: "Novela", editorial: "Viking Press" },
    { titulo: "El Hobbit", autor: "J.R.R. Tolkien", fecha_publicacion: new Date("1937-09-21"), genero: "Fantasía", editorial: "George Allen & Unwin" },
    { titulo: "Fahrenheit 451", autor: "Ray Bradbury", fecha_publicacion: new Date("1953-10-19"), genero: "Ciencia ficción", editorial: "Ballantine Books" },
    { titulo: "La Metamorfosis", autor: "Franz Kafka", fecha_publicacion: new Date("1915-01-01"), genero: "Ficción", editorial: "Kurt Wolff Verlag" }
])

Comandos para verificar la inserción

Para asegurarte de que los documentos se han insertado correctamente, puedes usar el siguiente comando para mostrar todos los documentos en la colección:

db.libros.find().pretty()

Este comando mostrará todos los documentos de la colección libros en un formato legible.

Comandos para realizar operaciones básicas

Leer (Read)

Mostrar todos los documentos de la colección:

db.libros.find().pretty()

Mostrar un libro específico por su título:

db.libros.findOne({ titulo: "1984" })

Actualizar (Update)

Actualizar la editorial de un libro específico:

db.libros.updateOne(
    { titulo: "El Hobbit" },
    { $set: { editorial: "Houghton Mifflin" } }
)

Eliminar (Delete)

Eliminar un libro específico por su título:

db.libros.deleteOne({ titulo: "La Metamorfosis" })

Estos comandos te permitirán gestionar una colección de libros en MongoDB desde la consola, realizando operaciones CRUD básicas y verificando los resultados.

MongoDB

https://www.mongodb.com/es

Probarlo sin instalar:

https://docs.mongodb.com/manual/tutorial/getting-started/

Instalar en windows:

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/

https://www.genbeta.com/desarrollo/mongodb-que-es-como-funciona-y-cuando-podemos-usarlo-o-no

Tutorial básico:

https://www.diegocalvo.es/tutorial-de-mongodb-con-ejemplos/

https://geekflare.com/es/mongodb-queries-examples/

https://www.codigofuente.org/series/mongodb/

Solución Actor

package com.trifulcas.DAO;

public class Actor {
	private int actor_id;
	private String first_name;
	private String last_name;
	public Actor(int actor_id, String first_name, String last_name) {
		super();
		this.actor_id = actor_id;
		this.first_name = first_name;
		this.last_name = last_name;
	}
	public int getActor_id() {
		return actor_id;
	}
	public void setActor_id(int actor_id) {
		this.actor_id = actor_id;
	}
	public String getFirst_name() {
		return first_name;
	}
	public void setFirst_name(String first_name) {
		this.first_name = first_name;
	}
	public String getLast_name() {
		return last_name;
	}
	public void setLast_name(String last_name) {
		this.last_name = last_name;
	}
	@Override
	public String toString() {
		return "Actor [actor_id=" + actor_id + ", first_name=" + first_name + ", last_name=" + last_name + "]";
	}
	
	
	
}

package com.trifulcas.DAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ActorDAO {
	private Connection con;
	private PreparedStatement st;
	private ResultSet rs;

	public ActorDAO() {
		try {
			// Nos conectamos en el constructor, la variable con estará disponible
			// para todas las funciones de la clase DAO
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/sakila", "root", "");

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public void close() {
		try {
			con.close();
			st.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public Actor getActor(int id) {
		try {
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from actor where actor_id=?";
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			if (rs.next()) {
				return new Actor(rs.getInt("actor_id"), rs.getString("first_name"), rs.getString("last_name"));
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}
	public List<Actor> getActors(String texto){
		try {
			List<Actor> actores = new ArrayList<>();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from actor where first_name like ? or last_name like ?";
			st = con.prepareStatement(sql);
			st.setString(1, "%" + texto + "%");
			st.setString(2, "%" + texto + "%");
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				actores.add(new Actor(rs.getInt("actor_id"), rs.getString("first_name"), rs.getString("last_name")));
			}
			return actores;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}
	public List<Actor> getActors(){
		try {
			
			return getActors("");
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}
	
	public int addActor(String first, String last) {
		try {
			// Creo el sql
			String sql = "insert into actor(first_name, last_name) values (?,?)";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, first);
			st.setString(2, last);
			// Ejecuto
			return st.executeUpdate();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
	public int addActor(Actor actor) {
		try {
			
			// Ejecuto
			return addActor(actor.getFirst_name(),actor.getLast_name());
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
	public int updateActor(Actor actor) {
		try {
			String sql = "update actor set first_name=?,last_name=? where actor_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, actor.getFirst_name());
			st.setString(2, actor.getLast_name());
			st.setInt(3, actor.getActor_id());
			// Ejeceuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
	public int deleteActor(int id) {
		try {
			String sql = "delete from actor  where actor_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setInt(1, id);
			// Ejecuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
}

package com.trifulcas.DAO;

public class TestActorDao {

	public static void main(String[] args) {
		ActorDAO actorDAO = new ActorDAO();
		System.out.println(actorDAO.getActor(1));
		System.out.println(actorDAO.getActors());
		actorDAO.addActor("aa", "bb");
		Actor actor=new Actor(0,"aa","bb");
		actorDAO.addActor(actor);
		
		Actor penelope=actorDAO.getActor(1);
		penelope.setFirst_name("Paquita");
		penelope.setLast_name("Salas");
		actorDAO.updateActor(penelope);
		System.out.println(actorDAO.getActor(1));
		actorDAO.deleteActor(56982);
	}

}

DAO con relaciones

Los POJOs

package com.trifulcas.DAO;

import java.util.List;

// Esta clase nos representa a un registro de la tabla country
// Contiene toda la información necesaria
// Se llaman POJOs (Plain Java Object)
public class Country {
	private int country_id;
	private String country;
	private List<City> cities;
	
	public List<City> getCities() {
		return cities;
	}
	public void setCities(List<City> cities) {
		this.cities = cities;
	}
	public Country(int country_id, String country) {
		super();
		this.country_id = country_id;
		this.country = country;
	}
	public int getCountry_id() {
		return country_id;
	}
	public void setCountry_id(int country_id) {
		this.country_id = country_id;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	@Override
	public String toString() {
		return "Country [country_id=" + country_id + ", country=" + country + ", cities=" + cities + "]";
	}

	
}

package com.trifulcas.DAO;

public class City {
	private int city_id;
	private int country_id;
	private Country country;
	private String city;
	
	public City(int city_id, int country_id, String city) {
		super();
		this.city_id = city_id;
		this.country_id = country_id;
		this.city = city;
	}
	public int getCity_id() {
		return city_id;
	}
	public void setCity_id(int city_id) {
		this.city_id = city_id;
	}
	public int getCountry_id() {
		return country_id;
	}
	public void setCountry_id(int country_id) {
		this.country_id = country_id;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public Country getCountry() {
		return country;
	}
	public void setCountry(Country country) {
		this.country = country;
	}
	@Override
	public String toString() {
		return "City [city_id=" + city_id + ", country_id=" + country_id + ", country=" + country + ", city=" + city
				+ "]";
	}
	
	
	
}

Los DAOs

package com.trifulcas.DAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

// En esta clase vamos a implementar la lógica del CRUD
// Desde aquí accederemos a la base de datos
public class CountryDAO {
	// Tenemos una variable para almacenar la conexión
	private Connection con;
	private PreparedStatement st;
	private ResultSet rs;
	private static CityDAO cityDAO;

	public CountryDAO() {
		this("sakila");
	}

	public CountryDAO(String bd) {
		try {
			// Nos conectamos en el constructor, la variable con estará disponible
			// para todas las funciones de la clase DAO
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + bd, "root", "");

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public void close() {
		try {
			con.close();
			st.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private void loadDAO() {
		if (cityDAO == null) {
			cityDAO = new CityDAO();
		}
	}

	// cRud
	// Obtengo un pais por el ID
	public Country getCountry(int id) {
		try {
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country where country_id=?";
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			if (rs.next()) {
				return new Country(rs.getInt("country_id"), rs.getString("country"));
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	public Country fillCity(Country pais) {
		try {
			loadDAO();
			pais.setCities(cityDAO.getCityByCountry(pais.getCountry_id()));
			return pais;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	// cRud
	// Obtengo todos los paises que tengan un texto
	public List<Country> getCountries(String texto) {
		try {
			List<Country> paises = new ArrayList<>();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country where country like ?";
			st = con.prepareStatement(sql);
			st.setString(1, "%" + texto + "%");
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				paises.add(new Country(rs.getInt("country_id"), rs.getString("country")));
			}
			return paises;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	// cRud
	// Obtengo todos los paises
	public List<Country> getCountries() {
		try {
			List<Country> paises = new ArrayList<>();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country";
			st = con.prepareStatement(sql);

			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				paises.add(new Country(rs.getInt("country_id"), rs.getString("country")));
			}
			return paises;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	// Crud
	// Para añadir hago lo mismo, le paso un pais
	public int addCountry(Country pais) {
		try {
			return addCountry(pais.getCountry());
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// Crud
	public int addCountry(String pais) {
		try {
			// Creo el sql
			String sql = "insert into country(country) values (?)";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, pais);
			// Ejecuto
			return st.executeUpdate();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// crUd
	// Para modificar
	public int updateCountry(Country pais) {
		try {
			String sql = "update country set country=? where country_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, pais.getCountry());
			st.setInt(2, pais.getCountry_id());
			// Ejeceuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// Cread un método deleteCountry al que le pasamos un id y nos borra el país con
	// ese id
	// cruD
	public int deleteCountry(int id) {
		try {
			String sql = "delete from country  where country_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setInt(1, id);
			// Ejecuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// cruD
	public int deleteCountry(Country pais) {
		try {

			return deleteCountry(pais.getCountry_id());

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
}

package com.trifulcas.DAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

// En esta clase vamos a implementar la lógica del CRUD
// Desde aquí accederemos a la base de datos
public class CityDAO {
	// Tenemos una variable para almacenar la conexión
	private Connection con;
	private PreparedStatement st;
	private ResultSet rs;
	private static CountryDAO countryDAO;

	public CityDAO() {
		this("sakila");
	}

	public CityDAO(String bd) {
		try {
			// Nos conectamos en el constructor, la variable con estará disponible
			// para todas las funciones de la clase DAO
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + bd, "root", "");
			
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}
	private void loadDAO() {
		if (countryDAO == null) {
			countryDAO = new CountryDAO();
		}
	}
	public void close() {
		try {
			con.close();
			st.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// cRud
	// Obtengo un pais por el ID
	public City getCity(int id) {
		try {
			loadDAO();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from city where city_id=?";
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			if (rs.next()) {
				City ciudad = new City(rs.getInt("city_id"), rs.getInt("country_id"), rs.getString("city"));
				Country pais = countryDAO.getCountry(ciudad.getCountry_id());
				ciudad.setCountry(pais);
				return ciudad;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	public List<City> getCityByCountry(int id) {
		try {
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from city where country_id=?";
			List<City> cities = new ArrayList<>();
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				cities.add(getCity(rs.getInt("city_id")));
			}
			return cities;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

}

Los tests

package com.trifulcas.DAO;

import java.util.List;

public class Test {

	public static void main(String[] args) {
		// Usar la capa de DAO para crear un país llamado 'Utopía'
		CountryDAO countryDAO=new CountryDAO();
		
		// Lo añado usando el método por cadena
		countryDAO.addCountry("Utopía");
		
		// Lo añado usando un objeto de tipo Country
		Country utopia=new Country(0,"Utopía");
		countryDAO.addCountry(utopia);
		
		// Usar la capa de DAO para modificar el nombre 
		// del país de id 27 a 'República Dominicana'
		
		// Recupero el país
		Country repdom=countryDAO.getCountry(27);
		// Le cambio el nombre
		repdom.setCountry("República Dominicana");
		// Actualizo
		countryDAO.updateCountry(repdom);
		
		// Creo el país
		repdom=new Country(27,"República Dominicana");
		// Actualizo
		countryDAO.updateCountry(repdom);
		
		if (countryDAO.deleteCountry(12)==0) {
			System.out.println("No se ha podido eliminar");
		};
		
		List<Country> paises=countryDAO.getCountries("pa");
		System.out.println(paises);
		
		countryDAO.close();
	}

}

package com.trifulcas.DAO;

public class TestCiy {

	public static void main(String[] args) {
		CityDAO cityDAO=new CityDAO();
		
		City ciudad=cityDAO.getCity(1);
		
		System.out.println(ciudad);
		
		CountryDAO countryDAO=new CountryDAO();
		Country spain=countryDAO.getCountry(87);
		System.out.println(spain);
		spain=countryDAO.fillCity(spain);
		System.out.println(spain);
	}

}

DAO de city

package com.trifulcas.DAO;

public class City {
	private int city_id;
	private int country_id;
	private Country country;
	private String city;
	
	public City(int city_id, int country_id, String city) {
		super();
		this.city_id = city_id;
		this.country_id = country_id;
		this.city = city;
	}
	public int getCity_id() {
		return city_id;
	}
	public void setCity_id(int city_id) {
		this.city_id = city_id;
	}
	public int getCountry_id() {
		return country_id;
	}
	public void setCountry_id(int country_id) {
		this.country_id = country_id;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public Country getCountry() {
		return country;
	}
	public void setCountry(Country country) {
		this.country = country;
	}
	@Override
	public String toString() {
		return "City [city_id=" + city_id + ", country_id=" + country_id + ", country=" + country + ", city=" + city
				+ "]";
	}
	
	
	
}
package com.trifulcas.DAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// En esta clase vamos a implementar la lógica del CRUD
// Desde aquí accederemos a la base de datos
public class CityDAO {
	// Tenemos una variable para almacenar la conexión
	private Connection con;
	private PreparedStatement st;
	private ResultSet rs;
	private CountryDAO countryDAO;
	
	public CityDAO() {
		this("sakila");
	}

	public CityDAO(String bd) {
		try {
			// Nos conectamos en el constructor, la variable con estará disponible
			// para todas las funciones de la clase DAO
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + bd, "root", "");
			countryDAO=new CountryDAO();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public void close() {
		try {
			con.close();
			st.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// cRud
	// Obtengo un pais por el ID
	public City getCity(int id) {
		try {
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from city where city_id=?";
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			if (rs.next()) {
				City ciudad= new City(rs.getInt("city_id"),rs.getInt("country_id"), rs.getString("city"));
				Country pais=countryDAO.getCountry(ciudad.getCountry_id());
				ciudad.setCountry(pais);
				return ciudad;
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	
}
package com.trifulcas.DAO;

public class TestCiy {

	public static void main(String[] args) {
		CityDAO cityDAO=new CityDAO();
		
		City ciudad=cityDAO.getCity(1);
		
		System.out.println(ciudad);

	}

}

Soluciones DAO

package com.trifulcas.DAO;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

// En esta clase vamos a implementar la lógica del CRUD
// Desde aquí accederemos a la base de datos
public class CountryDAO {
	// Tenemos una variable para almacenar la conexión
	private Connection con;
	PreparedStatement st;
	ResultSet rs;

	public CountryDAO() {
		this("sakila");
	}

	public CountryDAO(String bd) {
		try {
			// Nos conectamos en el constructor, la variable con estará disponible
			// para todas las funciones de la clase DAO
			Class.forName("com.mysql.cj.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + bd, "root", "");
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public void close() {
		try {
			con.close();
			st.close();
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	// cRud
	// Obtengo un pais por el ID
	public Country getCountry(int id) {
		try {
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country where country_id=?";
			st = con.prepareStatement(sql);
			st.setInt(1, id);
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			if (rs.next()) {
				return new Country(rs.getInt("country_id"), rs.getString("country"));
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	// cRud
	// Obtengo todos los paises que tengan un texto
	public List<Country> getCountries(String texto) {
		try {
			List<Country> paises = new ArrayList<>();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country where country like ?";
			st = con.prepareStatement(sql);
			st.setString(1, "%"+texto+"%");
			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				paises.add(new Country(rs.getInt("country_id"), rs.getString("country")));
			}
			return paises;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}
	// cRud
	// Obtengo todos los paises
	public List<Country> getCountries() {
		try {
			List<Country> paises = new ArrayList<>();
			// Lo hago igual que hasta ahora, SQL, STATEMENT, RESULTSET
			String sql = "select * from country";
			st = con.prepareStatement(sql);

			rs = st.executeQuery();
			// Si hay resultado construyo un país con los datos que me devuelve la consulta
			while (rs.next()) {
				paises.add(new Country(rs.getInt("country_id"), rs.getString("country")));
			}
			return paises;
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return null;
	}

	// Crud
	// Para añadir hago lo mismo, le paso un pais
	public int addCountry(Country pais) {
		try {
			return addCountry(pais.getCountry());
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// Crud
	public int addCountry(String pais) {
		try {
			// Creo el sql
			String sql = "insert into country(country) values (?)";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, pais);
			// Ejecuto
			return st.executeUpdate();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// crUd
	// Para modificar
	public int updateCountry(Country pais) {
		try {
			String sql = "update country set country=? where country_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setString(1, pais.getCountry());
			st.setInt(2, pais.getCountry_id());
			// Ejeceuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	// Cread un método deleteCountry al que le pasamos un id y nos borra el país con
	// ese id
	// cruD
	public int deleteCountry(int id) {
		try {
			String sql = "delete from country  where country_id=?";
			st = con.prepareStatement(sql);
			// Añado el parámetro
			st.setInt(1, id);
			// Ejecuto
			return st.executeUpdate();

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}
	// cruD
		public int deleteCountry(Country pais) {
			try {
				
				return deleteCountry(pais.getCountry_id());

			} catch (Exception ex) {
				System.out.println(ex.getMessage());
			}
			return 0;
		}
}

package com.trifulcas.DAO;

import java.util.List;

public class Test {

	public static void main(String[] args) {
		// Usar la capa de DAO para crear un país llamado 'Utopía'
		CountryDAO countryDAO=new CountryDAO();
		
		// Lo añado usando el método por cadena
		countryDAO.addCountry("Utopía");
		
		// Lo añado usando un objeto de tipo Country
		Country utopia=new Country(0,"Utopía");
		countryDAO.addCountry(utopia);
		
		// Usar la capa de DAO para modificar el nombre 
		// del país de id 27 a 'República Dominicana'
		
		// Recupero el país
		Country repdom=countryDAO.getCountry(27);
		// Le cambio el nombre
		repdom.setCountry("República Dominicana");
		// Actualizo
		countryDAO.updateCountry(repdom);
		
		// Creo el país
		repdom=new Country(27,"República Dominicana");
		// Actualizo
		countryDAO.updateCountry(repdom);
		
		if (countryDAO.deleteCountry(12)==0) {
			System.out.println("No se ha podido eliminar");
		};
		
		List<Country> paises=countryDAO.getCountries("pa");
		System.out.println(paises);
	}

}