Los lenguajes no importan

Más allá del conocimiento de un lenguaje específico, la habilidad más valiosa para un programador es la capacidad de pensar de manera algorítmica y lógica. Este pensamiento incluye:

  1. Descomposición de problemas: Dividir un problema complejo en partes más manejables y solucionables.
  2. Reconocimiento de patrones: Identificar y utilizar patrones comunes en problemas diferentes para encontrar soluciones eficaces.
  3. Abstracción: Simplificar los detalles de implementación para centrarse en los aspectos esenciales de un problema.

https://www.genbeta.com/desarrollo/que-muchos-programadores-dicen-que-lenguajes-no-importan-secreto-esta-pseudocodigo-sintaxis?utm_source=pocket-newtab-es-es

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);
	}

}