domingo, 6 de noviembre de 2011

Ejercicio "Efemérides" (base de datos)

Crear una aplicación que permita gestionar una base de datos de efemérides. Todas las operaciones se realizarán mediante consola, ya que el tema de formularios lo hemos empezado a ver después del de acceso a bases de datos.

Para empezar creamos en Access la base de datos "efemerides", que contendrá una única entidad: "efemeride", con los siguientes atributos:
  • id. De tipo entero.
  • texto. De tipo texto.
  • fecha. De tipo fecha.
Una vez creada la base de datos, implementamos el puente JDBC-ODBC y empezamos a trabajar.

Dentro de nuestro proyecto, crearemos la clase "BaseDatos" y el fichero de configuración, que como vimos en la entrada anterior nos facilitan todas las gestiones que realicemos con respecto al acceso a bases de datos.

Además, para que todo sea más realista y más sencillo de entender para el programador, crearemos la clase "Efemeride", que tendrá los atributos propios de una efeméride y, como métodos, los correspondientes "getters" y "setters".

CLASE EFEMERIDE

public class Efemeride {
 private Integer id;
 private String texto;
 private Date fecha;

 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getTexto() {
  return texto;
 }

 public void setTexto(String texto) {
  this.texto = texto;
 }

 public Date getFecha() {
  return fecha;
 }

 public void setFecha(Date fecha) {
  this.fecha = fecha;
 }
}

TRUCO: una vez que has especificado todos los atributos de una clase, en Eclipse es muy sencillo generar los métodos getAtributo() y setAtributo(Dato dato). Sólo tienes que hacer clic con el botón derecho y en "Source" elegir "Generate Getters and Setters". En el cuadro de diálogo que se abre eliges los atributos de los que quieres generar estos métodos, haces clic en "OK" y ¡listo!

Para controlar las excepciones de nuestra aplicación, crearemos nuestra propia excepción. En nuestro caso esta clase fue facilitada por el profesor, así como una interfaz ("IEfemerides") que debe implementar la clase "Efemerides". Esta clase es la encargada de realizar todas las gestiones con la base de datos (insertar datos, actualizar, recuperar, etc.).

CLASE EFEMERIDEEXCEPTION

public class EfemerideException extends Exception {
 private static final long serialVersionUID = 1L;

 public EfemerideException(String mensaje) {
  super(mensaje);
 }
 
}

CLASE EFEMERIDES

public class Efemerides implements IEfemerides {

 @Override
 public void insertar(Efemeride efemeride) throws EfemerideException {
  try {
   Connection conexion = BaseDatos.getConnection();
   String sql = "insert into efemerides (texto, fecha) values (?, ?)";
   PreparedStatement insertar = conexion.prepareStatement(sql);

   insertar.setString(1, efemeride.getTexto());
   insertar.setDate(2, DateUtils.convertir(efemeride.getFecha()));

   insertar.executeUpdate();
   insertar.close();

  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se ha podido insertar la efeméride.");
  }
 }

 @Override
 public void eliminar(Integer id) throws EfemerideException {
  try {
   int eliminado;
   Connection conexion = BaseDatos.getConnection();
   String sql = "delete from efemerides where id=?";
   PreparedStatement eliminar = conexion.prepareStatement(sql);

   eliminar.setInt(1, id);

   eliminado = eliminar.executeUpdate();
   if (eliminado == 0) {
    throw new EfemerideException("La efeméride no existe.");
   }
   eliminar.close();

  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se ha podido eliminar la efeméride.");
  }
 }

 @Override
 public void actualizar(Efemeride efemeride) throws EfemerideException {
  try {
   int actualizado;
   Connection conexion = BaseDatos.getConnection();
   String sql = "update efemerides set texto=?, fecha=? where id=?";
   PreparedStatement actualizar = conexion.prepareStatement(sql);

   actualizar.setString(1, efemeride.getTexto());
   actualizar.setDate(2, DateUtils.convertir(efemeride.getFecha()));
   actualizar.setInt(3, efemeride.getId());

   actualizado=actualizar.executeUpdate();
   if (actualizado == 0) {
    throw new EfemerideException("La efeméride no existe, por lo que no se ha podido actualizar.");
   }
   actualizar.close();

  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se ha podido actualizar la efeméride.");
  }

 }

 @Override
 public Efemeride recuperar(Integer id) throws EfemerideException {
  Efemeride efemeride = new Efemeride();
  try {
   Connection conexion = BaseDatos.getConnection();
   String sql = "select * from efemerides where id=?";
   PreparedStatement recuperar = conexion.prepareStatement(sql);

   recuperar.setInt(1, id);

   ResultSet resultado = recuperar.executeQuery();
   if (!resultado.next()) {
    throw new EfemerideException("La efeméride no se ha recuperado porque no existe.");
   } else {
    efemeride.setId(id);
    efemeride.setTexto(resultado.getString("texto"));
    efemeride.setFecha(resultado.getDate("fecha"));
   }
  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se ha podido recuperar la efeméride.");
  }
  return efemeride;
 }

 @Override
 public List<Efemeride> hoy() throws EfemerideException {
  Date hoy = new Date();

  return recuperarPorFecha(hoy);
 }

 @Override
 public List<Efemeride> recuperarTodas() throws EfemerideException {
  List<Efemeride> listado = new ArrayList<Efemeride>();
  try {
   Connection conexion = BaseDatos.getConnection();
   Statement recuperar = conexion.createStatement();

   ResultSet resultado;
   resultado = recuperar.executeQuery("select * from efemerides");

   while (resultado.next()) {
    Efemeride efemeride = new Efemeride();
    efemeride.setId(resultado.getInt("id"));
    efemeride.setTexto(resultado.getString("texto"));
    efemeride.setFecha(resultado.getDate("fecha"));
    listado.add(efemeride);
   }
  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se han podido recuperar las efemérides.");
  }
  return listado;
 }

 @Override
 public List<Efemeride> recuperarPorFecha(Date fecha)
   throws EfemerideException {
  List<Efemeride> listado = new ArrayList<Efemeride>();
  try {
   Connection conexion = BaseDatos.getConnection();
   String sql = "select * from efemerides where day(fecha)=? and month(fecha)=?";
   PreparedStatement recuperar = conexion.prepareStatement(sql);

   recuperar.setInt(1, DateUtils.dia(fecha));
   recuperar.setInt(2, DateUtils.mes(fecha));

   ResultSet resultado = recuperar.executeQuery();
   while (resultado.next()) {
    Efemeride efemeride = new Efemeride();
    efemeride.setId(resultado.getInt("id"));
    efemeride.setTexto(resultado.getString("texto"));
    efemeride.setFecha(resultado.getDate("fecha"));
    listado.add(efemeride);
   }
  } catch (SQLException e) {
   e.printStackTrace();
   throw new EfemerideException("No se han podido recuperar las efemérides.");
  }
  return listado;
 }

}

Finalmente, la aplicación con la que interactuará el usuario se creó utilizando varias clases proporcionadas por el profesor, que permitían crear menús y recoger los datos introducidos por el usuario.

CLASE MENUEFEMERIFE

public class MenuEfemeride {

 private static Efemerides efemerides = new Efemerides();
 
 public static void main(String[] args) {

  Menu principal = new Menu("Menú principal. Efemérides");
  Menu consultar = new Menu("Consultar");
  
  Accion insertarEfemeride = new Accion("Insertar efeméride") {
   public void accion() { onInsertarEfemeride(); }
  };
  Accion eliminarEfemeride = new Accion("Eliminar efeméride") {
   public void accion() { onEliminarEfemeride(); }
  };
  Accion actualizarEfemeride = new Accion("Actualizar efeméride") {
   public void accion() { onActualizarEfemeride(); }
  };
  Accion buscarPorId = new Accion("Buscar efeméride por identificador") {
   public void accion() { onBuscarPorId(); }
  };
  Accion buscarPorFecha = new Accion("Buscar efeméride por fecha") {
   public void accion() { onBuscarPorFecha(); }
  };
  Accion efemeridesHoy = new Accion("Efemérides de hoy") {
   public void accion() { onEfemeridesHoy(); }
  };
  Accion todas = new Accion("Todas las efemérides") {
   public void accion() { onTodas(); }
  };
  
  consultar.agregar(buscarPorId);
  consultar.agregar(buscarPorFecha);
  consultar.agregar(efemeridesHoy);
  consultar.agregar(todas);
  consultar.agregar(new OpcionSalir("Volver"));
  
  principal.agregar(insertarEfemeride);
  principal.agregar(eliminarEfemeride);
  principal.agregar(actualizarEfemeride);
  principal.agregar(consultar);
  principal.agregar(new OpcionSalir("Salir"));
  
  principal.ejecutar();
  
  BaseDatos.desconectar();

 }

 protected static void onInsertarEfemeride() {

  Efemeride efemeride = new Efemeride();
  
  String texto = Entrada.leerCadena("Introduzca el texto de la efeméride");
  String fechaTexto = Entrada.leerCadena("Introduzca la fecha (dd/mm/aaaa)");
  String[] partes = fechaTexto.split("/");
  
  GregorianCalendar fecha = new GregorianCalendar(Integer.parseInt(partes[2]), (Integer.parseInt(partes[1])-1), Integer.parseInt(partes[0]));

  efemeride.setTexto(texto);
  efemeride.setFecha(fecha.getTime());
  
  try {
   efemerides.insertar(efemeride);
   System.out.println("**EFEMÉRIDE INSERTADA CON ÉXITO**");
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
  
 }
 
 protected static void onEliminarEfemeride() {

  Integer id = Entrada.leerEntero("Introduzca el identificador de la efeméride a eliminar");
  
  try {
   efemerides.eliminar(id);
   System.out.println("**EFEMÉRIDE ELIMINADA**");
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
  
 }

 protected static void onActualizarEfemeride() {

  Efemeride efemeride = new Efemeride();
  Integer id = Entrada.leerEntero("Introduzca el identificador de la efeméride a actualizar");
  try {
   Efemeride recuperada = efemerides.recuperar(id);
   System.out.println("Datos de la efeméride a actualizar:");
   System.out.println("Id: "+id+" - Texto: "+recuperada.getTexto()+" - Fecha: "+DateUtils.formatear(recuperada.getFecha()));
   
   String texto = Entrada.leerCadena("Introduzca el nuevo texto de la efeméride");
   String fechaTexto = Entrada.leerCadena("Introduzca la nueva fecha (dd/mm/aaaa)");
   
   String[] partes = fechaTexto.split("/");
   GregorianCalendar fecha = new GregorianCalendar(Integer.parseInt(partes[2]), (Integer.parseInt(partes[1])-1), Integer.parseInt(partes[0]));

   efemeride.setId(id);
   efemeride.setTexto(texto);
   efemeride.setFecha(fecha.getTime());
   
   efemerides.actualizar(efemeride);
   System.out.println("**EFEMÉRIDE ACTUALIZADA CON ÉXITO**");
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
 }
 
 protected static void onBuscarPorId() {

  Integer id = Entrada.leerEntero("Introduzca el identificador de la efeméride a buscar");
  try {
   Efemeride efemeride = efemerides.recuperar(id);
   System.out.println("DATOS DE LA EFEMÉRIDE:");
   System.out.println("Id: "+id+" - Texto: "+efemeride.getTexto()+" - Fecha: "+DateUtils.formatear(efemeride.getFecha()));
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
 }
 
 protected static void onBuscarPorFecha() {

  String fechaTexto = Entrada.leerCadena("Introduzca la fecha (dd/mm) de las efemérides a buscar");
  String[] partes = fechaTexto.split("/");
  
  GregorianCalendar fecha = new GregorianCalendar(1999, (Integer.parseInt(partes[1])-1), Integer.parseInt(partes[0]));
  
  try {
   List <Efemeride> listado = efemerides.recuperarPorFecha(fecha.getTime());
   if (listado.isEmpty()) {
    System.out.println("**NO HAY EFEMÉRIDES PARA EL DÍA ESPECIFICADO**");
   }
   else {
    System.out.println("LISTADO DE LAS EFEMÉRIDES:");
    for (Efemeride efemeride : listado) {
     System.out.println("Id: "+efemeride.getId()+" - Texto: "+efemeride.getTexto()+" - Fecha: "+DateUtils.formatear(efemeride.getFecha()));
    }
   }
   Entrada.pausa();
   
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
  
 }
 
 protected static void onEfemeridesHoy() {
  
  try {
   List <Efemeride> listado = efemerides.hoy();
   if (listado.isEmpty()) {
    System.out.println("**NO HAY EFEMÉRIDES PARA EL DÍA DE HOY**");
   }
   else {
    System.out.println("LISTADO DE LAS EFEMÉRIDES DE HOY:");
    for (Efemeride efemeride : listado) {
     System.out.println("Id: "+efemeride.getId()+" - Texto: "+DateUtils.formatear(efemeride.getFecha()));
    }
   }
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }
 }
 
 protected static void onTodas() {
  try {
   List <Efemeride> listado = efemerides.recuperarTodas();
   if (listado.isEmpty()) {
    System.out.println("**NO HAY EFEMÉRIDES ALMACENADAS**");
   }
   else {
    System.out.println("LISTADO DE TODAS LAS EFEMÉRIDES:");
    for (Efemeride efemeride : listado) {
     System.out.println("Id: "+efemeride.getId()+" - Texto: "+efemeride.getTexto()+" - Fecha: "+DateUtils.formatear(efemeride.getFecha()));
    }
   }
   Entrada.pausa();
  } catch (EfemerideException e) {
   System.err.println(e.getMessage());
   Entrada.pausa();
  }  
 }

}

También se creó una clase con utilidades para trabajar con las fechas, debido a que nos veíamos en la obligación de utilizar por una parte la clase java.util.Date y por otra java.sql.Date. Esta clase, como la clase "BaseDatos", se puede reutilizar cada vez que tengamos que trabajar con fechas en el acceso a bases de datos.

CLASE DATEUTILS

public class DateUtils {
 
 public static java.util.Date crearFecha(int dia, int mes, int anyo) {
  GregorianCalendar calendario = new GregorianCalendar(anyo, mes-1, dia);
  return calendario.getTime();
 }
 
 public static java.sql.Date convertir(java.util.Date fecha) {
  return new java.sql.Date(fecha.getTime());
 }
 
 public static int dia(java.util.Date fecha) {
  GregorianCalendar calendario = new GregorianCalendar();
  calendario.setTime(fecha);
  
  return calendario.get(Calendar.DAY_OF_MONTH);
 }
 
 public static int mes(java.util.Date fecha) {
  GregorianCalendar calendario = new GregorianCalendar();
  calendario.setTime(fecha);
  
  return calendario.get(Calendar.MONTH)+1;
 }
 
 public static int anyo(java.util.Date fecha) {
  GregorianCalendar calendario = new GregorianCalendar();
  calendario.setTime(fecha);
  
  return calendario.get(Calendar.YEAR);
 }
 
 public static String formatear(java.util.Date fecha) {
  SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
  return formatter.format(fecha);
 }

}

No hay comentarios:

Publicar un comentario