Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: gatoher en 23 de Agosto 2014, 18:00

Título: intervalos de fechas MySql con Java para comprobar reservas en hotel
Publicado por: gatoher en 23 de Agosto 2014, 18:00
Hola a todos, estoy realizando un ejercicio de reservas y  tengo dos problemas con las fechas. Me explico, es un ejercicio para reservas de un hotel, y cuando alguien quiere reservar una habitación por ejemplo "del 1 de agosto al 15", yo quiero recorrer todas la tabla donde almaceno todas las reservas y saber que habitaciones tengo libre.
No se me ocurre que select podría hacer.

La otra duda es que utilizo en java para apuntar las fechas dos JDate, y cada habitación tiene un costo por día. Si alguien quiere estar del 28 de agosto al 14 de septiembre no se como hacer para restar y me devuelva el número de días.

Estoy trabajando con MySql y Java.  La verdad que estoy atascado ahora mismo por que no veo como hacerlo.
Título: Re:Problema con fechas en un ejercicio
Publicado por: gatoher en 23 de Agosto 2014, 18:27
Dandole vueltas he pensado que podría ser algo a:
El usuario introduce una fecha_inicio y fecha_salida de la reserva. La select debería ser:

select idhabitacion from reservas where "fecha_inicio_nueva_reserva" y "fecha_salida_nueva_reserva" < menor fecha_inicio de todas las reservas OR  "fecha_inicio_nueva_reseva" > fecha_salida de todas las reservas

Pero no consigo construirla  >:(
Título: Re:Problema con fechas en un ejercicio
Publicado por: Ogramar en 23 de Agosto 2014, 19:35
Tienes que partir de tablas de la base de datos bien organizadas, si no lo haces así va a ser muy difícil que logres crear programas que funcionen.

La estructura habitual suele ser:

Tabla habitaciones: idHabitación, numeroDeCamas, tipoHabitacion, numeroHabitacion, etc.

Tabla reservas: idReserva, idHabitacion, fechaEntrada, fechaSalida

Cuando alguien quiere hacer una reserva para una habitación tienes que buscar en la tabla reservas todas las reservas cuyo idHabitacion coincida con la habitación de la que se va a hacer la reserva,  y cuya fechaEntrada sea mayor o igual que la fechaEntrada en la que se quiere hacer la reserva. A partir de ahí tienes que comprobar si existe solape de fechas, si existe solape la reserva no es posible. Si no existe solape, sí es posible...
Título: Re:Problema con fechas en un ejercicio
Publicado por: gatoher en 24 de Agosto 2014, 20:07
Hola Ogramar, lo he intentado asi;

"Select ha.idhabitacion, numero, piso, descripcion, caracteristicas, precio_diario, ha.estado, tipo_habitacion
from habitacion ha , reserva re where ha.idhabitacion=re.idhabitacion and  '2014-02-15' < re.fecha_ingreso
and  '2014-02-01' > re.fecha_salida and ha.estado='disponible' "

Disponible es un campo en la tabla habitación que tiene disponible, en obras, etc. Asi funciona solo si hay reservas, a ver si me explico. Al buscar en la tabla reservas, solo filtra las habitaciones que tienen reservas. En este caso hay una reserva en Febrero, pero no me aparece ninguna habitación, todas estan libres y claro no estan en la tabla reserva. Es lógico.

Si tienes  5 habitaciones y en un mes x tienes en la tabla reservas 2 reservas con dos habitaciones distintas, es una tonteria buscar ahi las habitaciones que estan libres por que ahi no aparecen.

 
Título: Re:Problema con fechas en un ejercicio
Publicado por: Ogramar en 24 de Agosto 2014, 20:30
¿Y te ha funcionado bien?
Título: Re:Problema con fechas en un ejercicio
Publicado por: gatoher en 24 de Agosto 2014, 21:05
No Ogramar, conforme esta la select no.

Select ha.idhabitacion, numero, piso, descripcion, caracteristicas, precio_diario, ha.estado, tipo_habitacion
from habitacion ha , reserva re where ha.idhabitacion=re.idhabitacion and  '2014-02-15' < re.fecha_ingreso
and '2014-02-01' > re.fecha_salida and ha.estado='disponible'   

Haber, es lógico como he explicado,con una select no se puede hacer. A ver, las fechas que estan en números son las fechas que al abrir el JFram tu escribes para saber si en esas fechas hay alguna habitación libre, y fecha_ingreso y fecha_salida son las fechas que tienen todas las reservas en la tabla reservas.
Claro, en la tabla reserva no va a aparecer una habitación si no ha sido reservada.

Pongo una immagen de bbdd
Título: Re:Problema con fechas en un ejercicio
Publicado por: gatoher en 24 de Agosto 2014, 21:11
Vaya sin querer le di a mandar, no estoy acertado hoy. A ver esta select hace justo lo contrario que yo quiero, osea me devuelve todas las habitaciones de la tabla reservas que esten ocupadas en un rango de fechas x.

Ahora faltaría poder sacar de la tabla habitaciones las que no estan ahi. Por ejemplo tengo cinco habitaciones y esta select me devuelve dos idhabitaciones:

Select ha.idhabitacion, numero, piso, descripcion, caracteristicas, precio_diario, ha.estado, tipo_habitacion
from habitacion ha , reserva re where ha.idhabitacion=re.idhabitacion and  '2014-08-02' >= re.fecha_ingreso
and '2014-08-14' <= re.fecha_salida and ha.estado='disponible'

Solonhe cambiado los signos para que me devuelva de la tabla reservas las habitaciones que en la fecha de ingreso y salida se encuentre entre el rango que le doy.
Título: Re:Problema con fechas en un ejercicio
Publicado por: Ogramar en 24 de Agosto 2014, 22:23
No sé si estaré acertado o no, pero empezaría planteando todo el proceso desde un punto de vista de lógica a aplicar para luego pasar a crear el código:

Las posibilidades de que dada una fechaSolicitaDeEntrada y fechaSalidaSolicitada exista coincidencia con una reserva serían:


Ejemplo 1: Estamos dentro del intervalo de la reserva. Solicito del 10 al 15 de octubre. Hay reserva del 10 al 12 de octubre ó hay reserva del 10 al 15 de octubre

fechaSolicitadaDeEntrada >= fechaIngresoEnLaReserva y fechaSolicitadaDeSalida<= fechaSalidaEnLaReserva


Ejemplo 2: La reserva empezó antes pero se solapa con las fechas solicitadas. solicito del 10 al 15 de octubre. Hay reserva del 7 al 12 de octubre.

fechaSolicitadaDeEntrada < fechaIngresoEnLaReserva y fechaSolicitadaDeSalida<= fechaSalidaEnLaReserva


Ejemplo 3: La solicitud empieza en un día de reserva y termina fuera de la reserva. solicito del 10 al 15 de octubre. Hay reserva del 13 al 18 de octubre.

fechaSolicitadaDeEntrada > fechaIngresoEnLaReserva y fechaSolicitadaDeEntrada < fechaSalidaEnLaReserva


En estos tres casos la habitación no está disponible para reserva, en otro caso sí está disponible.


También lo podemos plantear al revés:

Si fechaSolicitadaEntrada<fechaIngresoEnLaReserva y fechaSolicitadaSalida < fechaIngresoEnLaReserva -- > la habitación está libre (se intenta tomar antes de la reserva)

Si fechaSolicitadaEntrada > fechaSalidaEnLaReserva -- > la habitación está libre (se intenta tomar después)



Ahora esbozando lo que sería el proceso en código:

Código: [Seleccionar]

$arrayDeIdHabitaciones -- > Almacenamos aquí cada id de habitación

Ahora hacemos un bucle:

Para cada idHabitación "idHabitac" en $arrayDeHabitaciones

{
arraySeleccion = Seleccionar las filas de la tabla reservas donde (idHabitac sea igual a idHabitacion de esa fila)

Para cada fila en arraySeleccion {
(Si fechaSolicitadaEntrada<fechaIngresoEnLaReserva y fechaSolicitadaSalida < fechaIngresoEnLaReserva) ó
(fechaSolicitadaEntrada > fechaSalidaEnLaReserva) ENTONCES {estadoHabitacion[idHabitacion] = 'DISPONIBLE'; disponible[i]=idHabitacion)
ELSE
{estadoHabitacion[idHabitacion] = 'OCUPADA'}

}

}


Finalmente, mostramos las habitaciones disponibles (todas las que existan en array disponible)

El proceso lo veo un poco laborioso pero al menos creo que con esto se llegaría al resultado deseado. Quizás haya que hacer algunos ajustes y pruebas  ::)
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 00:02
Ogramar creo que lo he conseguido, pero un cacho código que no veas. Lo pongo a ver que tal lo ves, lo he probado un par de veces y parece funcionar.

Código: [Seleccionar]
public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
       
        String sql=""; //Select donde sacaremos las habitaciones que estan en la tablaReservas
        String sqlContarHab = "Select count(*) from reserva re, habitacion ha " +"\n" +
" where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"'  >= re.fecha_ingreso \n" +
"and '"+fechaInicio+"' <= re.fecha_salida and ha.estado='Disponible' ";  // tamaño que va a tener el array de habitaciones libres
        int [] habitacionesLibres = null;   // Declaramos el array donde almacenaremos los id de las habitaciones ocupadas
        int cantidadHabitaciones = 0; // Variable para almacenar el tamaño del array
        DefaultTableModel modelob; //TableModel donde mostraremos las habitaciones libres
       
  //Si la fecha del posible nuevo ingreso es mayor a la fecha de inicio de cualquier reserva
  // y al mismo tiempo la fecha de inicio es menor que la fecha de salida de cualquier reserva
  // significa que esta en el rango interior de una reserva ya realizado
        //de momento esto vale habra q estudiarlo más profundamente
sql ="Select ha.idhabitacion from reserva re, habitacion ha " +"\n" +
" where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"'  >= re.fecha_ingreso \n" +
"and '"+fechaInicio+"' <= re.fecha_salida and ha.estado='Disponible' ";       
                       
        String[] titulos = {"ID",  "Numero", "Piso", "Descripcion", "Caracteristicas", "Precio Diario", "Estado", "Tipo de Habitacion"};
        String[] registro = new String [8];
        modelob = new DefaultTableModel(null, titulos);
       
        try{
           
         int i = 0;   
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sqlContarHab); //Sentencia para saber el tamaño
        while (conn.getRs().next()){
            cantidadHabitaciones = conn.getRs().getInt(1); //Almacenamos tamaño
           
        }
        habitacionesLibres = new int[cantidadHabitaciones]; //Instanciamos el array con el nuevo tamaño
        conn.ejecutaSQL(sql); //Sql que nos devuelve el id de las habitaciones ocupadas
       
          while (conn.getRs().next()) {
              habitacionesLibres[i]= conn.getRs().getInt(1); //Almacenamos en el array el id de las habitaciones ocupadas
              i++;
          }
         
          String sqlHabitacionesLibres=""; //Sentencia  para mostrar las habitaciones libres
       
          //For donde vamos cambiando el id de la habitacion en la select
            for (int h = 0; h < habitacionesLibres.length; h++) {
             
            sqlHabitacionesLibres = "Select distinct idhabitacion,numero,piso,descripcion, caracteristicas," +"\n" +
                    " precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion= "+habitacionesLibres[h]+" and idhabitacion != '"+0+"'";
                System.out.println("El sqlHabitacionesLibres vale=> " + sqlHabitacionesLibres);
         //Ejecutamos el result tantas veces como el tamaño del array de habitaciones libres
         //Esto se podría hacer de otra manera es lo primero que se me ha ocurrido
         //Y lo que he tratado de evitar desde un principio
          conn.ejecutaSQL(sqlHabitacionesLibres);
          while(conn.getRs().next()){
                registro[0] = conn.getRs().getString("idhabitacion");
                registro[1] = conn.getRs().getString("numero");
                registro[2] = conn.getRs().getString("piso");
                registro[3] = conn.getRs().getString("descripcion");
                registro[4] = conn.getRs().getString("caracteristicas");
                registro[5] = conn.getRs().getString("precio_diario");
                registro[6] = conn.getRs().getString("estado");
                registro[7] = conn.getRs().getString("tipo_habitacion");
          }

             totalRegistro = totalRegistro + 1;
                System.out.println("el total registros es " +totalRegistro);
                modelob.addRow(registro);

            }     
            conn.cerrarConexion();

        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
       
         for(int z = 0; z < habitacionesLibres.length; z++){
              System.out.println("El valor de habitacionesLibres en " + z +" es" + habitacionesLibres[z]);
         }
       
       
        return modelob;
    }   
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 00:58
No no funciona bien, el último bucle for que utilizo para cambiar el idhabitacion machaca el resulset, solo devuelve el último resultado  :'(
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: Ogramar en 25 de Agosto 2014, 10:56
No entiendo bien el comentario que pones al final de esta sentencia:

String sqlContarHab = "Select count(*) from reserva re, habitacion ha " +"\n" +
" where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"'  >= re.fecha_ingreso \n" +
"and '"+fechaInicio+"' <= re.fecha_salida and ha.estado='Disponible' ";  // tamaño que va a tener el array de habitaciones libres

Aquí lo que estás diciendo es que te diga el número de habitaciones que están en la tabla de habitaciones y en la tabla de reservas simultáneamente y la fechaSolicitadaDeInicio sea mayor o igual a la fecha de ingreso de la reserva y que la fechaSolicitadaDeInicio sea menor o igual a la fecha de salida de la reserva. Esto te selecciona las habitaciones que donde la solicitud está dentro de las fechas de una reserva.

En el comentario indicas <<tamaño que va a tener el array de habitaciones libres>> pero aquí en realidad lo que estás obteniendo son habitaciones que están ocupadas, y ni siquiera todas las que están ocupadas ¿? (no acabo de entender).


Supongamos una reserva1 que va del 10 al 15 de octubre y una reserva2 que va del 16 al 20 de octubre y se solicita del 8 al 17 de octubre.

Para la reserva1 la fechaIngreso no es menor que fechaInicio, por lo que no cuenta. Para la reserva2 la fechaInicio no es mayor que la fechaIngreso, por lo que no cuenta. 

No sé si me equivoco pero si planteas tres select:

1) fechaSolicitadaDeEntrada >= fechaIngresoEnLaReserva y fechaSolicitadaDeSalida<= fechaSalidaEnLaReserva

2) fechaSolicitadaDeEntrada < fechaIngresoEnLaReserva y fechaSolicitadaDeSalida<= fechaSalidaEnLaReserva

3) fechaSolicitadaDeEntrada > fechaIngresoEnLaReserva y fechaSolicitadaDeEntrada < fechaSalidaEnLaReserva

Ahí podrías almacenar las habitaciones que están ocupadas.

Luego unes esos resultados en un set para eliminar duplicados y tienes todas las habitaciones ocupadas.

Luego mostrarías todas las habitaciones disponibles menos las ocupadas..., que son las habitaciones libres disponibles para poder hacer la reserva en esa fecha  ::)
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 16:06
Hola Ogramar, ahora más que la propia select lo que no se como hacer es cuando tengo el id de las habitaciones ocupadas en x fechas, supongamos "idhabitacion 1,6,10,20". ¿Como hago para sacar el resto?.

Esos id son dinamicos, no puedo ir a la tabla habitaciones y decir select xxxx where idhabitacion no sea 1,6,10,20.
Lo he intentado con un bucle for, pero me machaca en cada iteracion el dataTable.

Estoy algo fustrado, he intentado crear objetos de habitacion dentro del bucle for y meterlos en un array para que no se machacasen, pero se me va de las manos  :-\
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 16:47
Voy a poner como lo tengo ahora y la salida que me hace;

Código: [Seleccionar]
public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
       
        String sql=""; //Select donde sacaremos las habitaciones que estan en la tablaReservas
        // tamaño que va a tener el array de habitaciones libres
        //Suponiendo que estan todas libres
        String sqlContarHab = "Select  count(*) from habitacion"; 
        System.out.println("El sql contar habitaciones vale => " + sqlContarHab);
        int [] habitacionesOcupadas = null;   // Declaramos el array donde almacenaremos los id de las habitaciones ocupadas
        int cantidadHabitaciones = 0; // Variable para almacenar el tamaño del array
        DefaultTableModel modelob; //TableModel donde mostraremos las habitaciones libres
       Habitacion[] miArray = new Habitacion[10];
  //Si la fecha del posible nuevo ingreso es mayor a la fecha de inicio de cualquier reserva
  // y al mismo tiempo la fecha de inicio es menor que la fecha de salida de cualquier reserva
  // significa que esta en el rango interior de una reserva ya realizado
        //de momento esto vale habra q estudiarlo más profundamente
        sql ="Select ha.idhabitacion from reserva re, habitacion ha " +"\n" +
        " where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"'  >= re.fecha_ingreso \n" +
        "and '"+fechaInicio+"' <= re.fecha_salida and ha.estado='Disponible' ";       
        System.out.println("El sql para saber que habitaciones estan ocupadas es => " + sql);
       
       
        String[] titulos = {"ID",  "Numero", "Piso", "Descripcion", "Caracteristicas", "Precio Diario", "Estado", "Tipo de Habitacion"};
        String[] registro = new String [8];
        modelob = new DefaultTableModel(null, titulos);
       
        try{
           
       
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sqlContarHab); //Sentencia para saber el tamaño, total de habitaciones que tenemos
        while (conn.getRs().next()){
            cantidadHabitaciones = conn.getRs().getInt(1); //Almacenamos tamaño
        }
        conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
       
        try{
           
            int i = 0;     
        System.out.println("La cantidad de habitaciones que estan ocupadas son => " +cantidadHabitaciones);
        habitacionesOcupadas= new int[cantidadHabitaciones]; //Instanciamos el array con el nuevo tamaño
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql); //Sql que nos devuelve el id de las habitaciones ocupadas
       
          while (conn.getRs().next()) {
              habitacionesOcupadas[i]= conn.getRs().getInt(1); //Almacenamos en el array el id de las habitaciones ocupadas
              i++;
              System.out.println("El numero de id de las habitaciones ocupadas es => " + habitacionesOcupadas[i]);
          }
        conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
       
           try{         
          String sqlHabitacionesLibres=""; //Sentencia  para mostrar las habitaciones libres
           
          //For donde vamos cambiando el id de las habitaciones ue estaban ocupadas
            for (int h = 0; h < habitacionesOcupadas.length; h++) {
            System.out.println("La longitud de habitacionesLibres es => " + habitacionesOcupadas.length); 
            sqlHabitacionesLibres = "Select distinct idhabitacion,numero,piso,descripcion, caracteristicas," +"\n" +
                    " precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != "+habitacionesOcupadas[h]+" ";
            System.out.println("El sqlHabitacionesLibres vale=> " + sqlHabitacionesLibres);
           
            //Variable para crear un objeto
            Habitacion obj=null;
            int idhabitacion;
            String numero;
            String piso;
            String descripcion;
            String caracteristicas;
            Double precio;
            String estado;
            String tipo_habitacion;         
       
       
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sqlHabitacionesLibres);
       
          while(conn.getRs().next()){
            idhabitacion = conn.getRs().getInt(1);
            numero = conn.getRs().getString("numero");
            piso = conn.getRs().getString("piso");
            descripcion = conn.getRs().getString("descripcion");
            caracteristicas = conn.getRs().getString("caracteristicas");
            precio = Double.parseDouble(conn.getRs().getString("precio_diario"));
            estado = conn.getRs().getString("estado");
            tipo_habitacion = conn.getRs().getString("tipo_habitacion");
           
             
            obj = new Habitacion(idhabitacion, numero, piso, descripcion, caracteristicas, precio, estado, tipo_habitacion);
               //hay que crear un vector de objetos habitacion
             miArray[h]= obj;
            System.out.println("" + obj.toString());   
          }
         
           //Fin del bucle for
            }
           
             for(int i=0; i<miArray.length; i++){
         
            registro[0]= String.valueOf(miArray[i].getIdhabitacion());
            registro[1] = miArray[i].getNumero();
            registro[2] = miArray[i].getPiso();
            registro[3] = miArray[i].getDescripcion();
            registro[4] = miArray[i].getCaracteristicas();
            registro[5] = String.valueOf(miArray[i].getPrecio().toString());
            registro[6] = miArray[i].getEstado();
            registro[7] = miArray[i].getTipo_habitacion();
            totalRegistro = totalRegistro + 1;
           System.out.println("el total registros es " +totalRegistro);
             modelob.addRow(registro);
        }
       
       conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
                 
                     return modelob;
   




La salida por consola, ya que no se porque el modelo no me lo coje el table, y se repite varias veces por que al haber un  for para modificar la select ...
Eso pensaba solucionarlo con antes de meter el objeto en el Array de objetos Habitacion hacer un Compare to por ejemplo con el numero de la habitacion.

FechaInicio vale=>2014-08-01
El sql contar habitaciones vale => Select  count(*) from habitacion
El sql para saber que habitaciones estan ocupadas es => Select ha.idhabitacion from reserva re, habitacion ha
 where ha.idhabitacion=re.idhabitacion and  '2014-08-01'  >= re.fecha_ingreso
and '2014-08-01' <= re.fecha_salida and ha.estado='Disponible'
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.

Conexión cerrada con éxito.
La cantidad de habitaciones que estan ocupadas son => 5
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.

Conexión cerrada con éxito.
La longitud de habitacionesLibres es => 5
El sqlHabitacionesLibres vale=> Select distinct idhabitacion,numero,piso,descripcion, caracteristicas,
 precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != 0
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.
El idhabitacion es; 1
 el numero de la habitacion es; 1
 el piso es; 1
 la descripcion es; fff
 las caracteristicas son; ffff
 el precio es; 100.0
 su estado es; Disponible
 el tipo de habitacion es; ffff
El idhabitacion es; 2
 el numero de la habitacion es; 2
 el piso es; 1
 la descripcion es; con nevera
 las caracteristicas son; interior
 el precio es; 20.0
 su estado es; Disponible
 el tipo de habitacion es; Individual
El idhabitacion es; 3
 el numero de la habitacion es; 3
 el piso es; 1
 la descripcion es; dddd
 las caracteristicas son; ddddd
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; ddddd
El idhabitacion es; 4
 el numero de la habitacion es; 4
 el piso es; 1
 la descripcion es; edeee
 las caracteristicas son; eeeee
 el precio es; 300.0
 su estado es; Disponible
 el tipo de habitacion es; eeeee
El idhabitacion es; 5
 el numero de la habitacion es; 10
 el piso es; 3
 la descripcion es; Matrimonio
 las caracteristicas son; exterior
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; exterior
La longitud de habitacionesLibres es => 5
El sqlHabitacionesLibres vale=> Select distinct idhabitacion,numero,piso,descripcion, caracteristicas,
 precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != 0
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.
El idhabitacion es; 1
 el numero de la habitacion es; 1
 el piso es; 1
 la descripcion es; fff
 las caracteristicas son; ffff
 el precio es; 100.0
 su estado es; Disponible
 el tipo de habitacion es; ffff
El idhabitacion es; 2
 el numero de la habitacion es; 2
 el piso es; 1
 la descripcion es; con nevera
 las caracteristicas son; interior
 el precio es; 20.0
 su estado es; Disponible
 el tipo de habitacion es; Individual
El idhabitacion es; 3
 el numero de la habitacion es; 3
 el piso es; 1
 la descripcion es; dddd
 las caracteristicas son; ddddd
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; ddddd
El idhabitacion es; 4
 el numero de la habitacion es; 4
 el piso es; 1
 la descripcion es; edeee
 las caracteristicas son; eeeee
 el precio es; 300.0
 su estado es; Disponible
 el tipo de habitacion es; eeeee
El idhabitacion es; 5
 el numero de la habitacion es; 10
 el piso es; 3
 la descripcion es; Matrimonio
 las caracteristicas son; exterior
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; exterior
La longitud de habitacionesLibres es => 5
El sqlHabitacionesLibres vale=> Select distinct idhabitacion,numero,piso,descripcion, caracteristicas,
 precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != 0
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.
El idhabitacion es; 1
 el numero de la habitacion es; 1
 el piso es; 1
 la descripcion es; fff
 las caracteristicas son; ffff
 el precio es; 100.0
 su estado es; Disponible
 el tipo de habitacion es; ffff
El idhabitacion es; 2
 el numero de la habitacion es; 2
 el piso es; 1
 la descripcion es; con nevera
 las caracteristicas son; interior
 el precio es; 20.0
 su estado es; Disponible
 el tipo de habitacion es; Individual
El idhabitacion es; 3
 el numero de la habitacion es; 3
 el piso es; 1
 la descripcion es; dddd
 las caracteristicas son; ddddd
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; ddddd
El idhabitacion es; 4
 el numero de la habitacion es; 4
 el piso es; 1
 la descripcion es; edeee
 las caracteristicas son; eeeee
 el precio es; 300.0
 su estado es; Disponible
 el tipo de habitacion es; eeeee
El idhabitacion es; 5
 el numero de la habitacion es; 10
 el piso es; 3
 la descripcion es; Matrimonio
 las caracteristicas son; exterior
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; exterior
La longitud de habitacionesLibres es => 5
El sqlHabitacionesLibres vale=> Select distinct idhabitacion,numero,piso,descripcion, caracteristicas,
 precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != 0
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.
El idhabitacion es; 1
 el numero de la habitacion es; 1
 el piso es; 1
 la descripcion es; fff
 las caracteristicas son; ffff
 el precio es; 100.0
 su estado es; Disponible
 el tipo de habitacion es; ffff
El idhabitacion es; 2
 el numero de la habitacion es; 2
 el piso es; 1
 la descripcion es; con nevera
 las caracteristicas son; interior
 el precio es; 20.0
 su estado es; Disponible
 el tipo de habitacion es; Individual
El idhabitacion es; 3
 el numero de la habitacion es; 3
 el piso es; 1
 la descripcion es; dddd
 las caracteristicas son; ddddd
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; ddddd
El idhabitacion es; 4
 el numero de la habitacion es; 4
 el piso es; 1
 la descripcion es; edeee
 las caracteristicas son; eeeee
 el precio es; 300.0
 su estado es; Disponible
 el tipo de habitacion es; eeeee
El idhabitacion es; 5
 el numero de la habitacion es; 10
 el piso es; 3
 la descripcion es; Matrimonio
 las caracteristicas son; exterior
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; exterior
La longitud de habitacionesLibres es => 5
El sqlHabitacionesLibres vale=> Select distinct idhabitacion,numero,piso,descripcion, caracteristicas,
 precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != 0
Conectando con la base de datos
Conexión establecida con la Base de datos...

Sentencia creada con éxito.
El idhabitacion es; 1
 el numero de la habitacion es; 1
 el piso es; 1
 la descripcion es; fff
 las caracteristicas son; ffff
 el precio es; 100.0
 su estado es; Disponible
 el tipo de habitacion es; ffff
El idhabitacion es; 2
 el numero de la habitacion es; 2
 el piso es; 1
 la descripcion es; con nevera
 las caracteristicas son; interior
 el precio es; 20.0
 su estado es; Disponible
 el tipo de habitacion es; Individual
El idhabitacion es; 3
 el numero de la habitacion es; 3
 el piso es; 1
 la descripcion es; dddd
 las caracteristicas son; ddddd
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; ddddd
El idhabitacion es; 4
 el numero de la habitacion es; 4
 el piso es; 1
 la descripcion es; edeee
 las caracteristicas son; eeeee
 el precio es; 300.0
 su estado es; Disponible
 el tipo de habitacion es; eeeee
El idhabitacion es; 5
 el numero de la habitacion es; 10
 el piso es; 3
 la descripcion es; Matrimonio
 las caracteristicas son; exterior
 el precio es; 200.0
 su estado es; Disponible
 el tipo de habitacion es; exterior
el total registros es 1
el total registros es 2
el total registros es 3
el total registros es 4
el total registros es 5
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: Ogramar en 25 de Agosto 2014, 17:44
Supongamos que hacemos un select

select idHabitacion from habitacion where estado='Disponible'

El resultado de este select lo metes en un arrayList que llamamos todasHabitaciones (aquí tienes todas las habitaciones).

Las habitaciones ocupadas las tienes en otro arrayList denominado ocupadasAL

Puedes determinar las habitaciones libres haciendo lo siguiente (lo que hace este ejemplo, pero aplicándolo a tu código):

Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class prueba {
    public static void main (String Args[]){
        int i=0;
        List<Integer> todasHabitaciones = Arrays.asList(1, 5, 6, 9, 11, 14, 18, 32, 44);
        List<Integer> ocupadasAL = Arrays.asList(5, 9, 11, 44);
        List<Integer> libres = new ArrayList<Integer>();
        for (i=0; i<todasHabitaciones.size(); i++){
            if (ocupadasAL.contains(todasHabitaciones.get(i))) {
                // Está ocupada
                System.out.println("Habitacion " + todasHabitaciones.get(i) + " esta ocupada");
            } else {
                //Está libre
                libres.add(todasHabitaciones.get(i));

            }
        }
        System.out.println("Todas las habitaciones son: " + todasHabitaciones);
        System.out.println("Las habitaciones libres son: " + libres);
        System.out.println("Las habitaciones ocupadas son: " + ocupadasAL);
    }
}
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 25 de Agosto 2014, 18:00
Hola, perdon por meterme. No se si lo que intentáis hacer es sacar las habitaciones libres de datos obtenidos de una tabla habitaciones y otra tabla reservas, pero no sería mas sencillo algo de este tipo:

Código: [Seleccionar]
SELECT * FROM habitaciones WHERE estado='Disponible' AND id_habitacion NOT IN(SELECT id_habitacion FROM RESERVAS);

Perdón por meterme pero es que os he leido y lo veo todo muy enrevesado....

Bueno un saludo y os seguiré leyendo a ver como acaba.
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: Ogramar en 25 de Agosto 2014, 18:08
Sí, la idea parece buena y no había contado con ese tipo de expresiones, pero realmente lo que va buscando no es simplemente que la habitación aparezca o no en la tabla de reservas. Lo que busca (si no me equivoco) es comprobar si la habitación está libre entre una fecha de solicitud de entrada y una fecha de solicitud de salida, con lo cual hay que meterse en comprobaciones de fechas. Quizás la habitación esté en la tabla de reservas, pero si la reserva no coincide con las fechas en que se solicita, la habitación está libre para esas fechas. Por eso le he planteado como se me ha ocurrido los tres posibles casos: la solicitud empieza antes y termina durante una reserva, la solicitud está dentro de las fechas de la reserva, o la solicitud empieza en la reserva y termina después del fin de la reserva. Esos serían los tres casos que veo para decir que la habitación está ocupada. Una vez determine si la habitación está en un caso de estos, puede responder si está ocupada o está libre.

Igual hay una forma más simple de hacerlo   ::) ::) ::)
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 25 de Agosto 2014, 18:43
Pues no se, es que creo que el problema es querer solucionarlo todo con java, es decir, lo cojo todo y ahora lo proceso, y a veces olvidamos que las bases de datos poseen una gran capacidad para procesar y filtrar datos, sigo sin verle problema a lo que busca....

Si tenemos dos parámetros FECHA_INICIO_FILTRO y FECHA_FINAL_FILTRO

una sentencia del tipo:
Código: [Seleccionar]
select * from habitaciones where estado="Disponible" and id_habitacion
   not in(select id_habitacion from reservas where (FECHA_INICIO_FILTRO  beetwen fecha_inicio_reserva and  fecha_final_reserva )
 or
( FECHA_FINAL_FILTRO  beetwen fecha_inicio_reserva and fecha_final_reserva));
 
No se ejk tampoco tengo el detalle de como tiene este hombre las tablas de la base de datos, pero vamos que con una select, menos la cama, te lo puede hacer prácticamente todo...XDD
 
 Un saludo!!

Nota: He editado la select que estaba toda mal, ahora creo que si debería dar los datos de todas las habitaciones que no están reservadas en un rango de fecha dado....
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: Ogramar en 25 de Agosto 2014, 19:32
Supón que una habitación está reservada del 10 al 15 de octubre. (día 10 es fechaInicioFiltro y día 15 fechaFinalFiltro)

La fecha en que se solicita es del 8 al 12 de octubre.

FECHA_INICIO_FILTRO < fecha_inicio_reserva and FECHA_FINAL_FILTRO < fecha_inicio_reserva no se cumple


FECHA_FINAL_FILTRO > fecha_final_reserva and FECHA_INICIO_FILTRO > fecha_final_reserva no se cumple


La habitación no consta como ocupada, pero sí está ocupada, ya que basta con que haya un solape para que la solicitud no se pueda materializar (en este caso se solapa del 10 al 12 de octubre).

Yo sigo empeñado en determinar las posibilidades (AUNQUE ME EDITO Y CAMBIO LO DICHO, antes había identificado 3 posibilidades pero ahora estoy viendo cuatro):

Ejemplo 1: Solicitud dentro del intervalo de la reserva. Solicito del 10 al 15 de octubre. Hay reserva del 5 al 20 de octubre

fechaSolicitadaDeEntrada >= fechaIngresoEnLaReserva y fechaSolicitadaDeSalida<= fechaSalidaEnLaReserva


Ejemplo 2: La reserva empezó antes pero se solapa con las fechas solicitadas. solicito del 10 al 15 de octubre. Hay reserva del 7 al 12 de octubre.

fechaSolicitadaDeEntrada > fechaIngresoEnLaReserva y fechaSolicitadaDeEntrada<= fechaSalidaEnLaReserva


Ejemplo 3: La reserva empieza después pero se solapa con las fechas solicitadas. solicito del 10 al 15 de octubre. Hay reserva del 13 al 18 de octubre.

fechaSolicitadaDeEntrada < fechaEntradaEnLaReserva y fechaSolicitadaDeSalida > fechaEntradaEnLaReserva


Ejemplo 4: la reserva queda dentro del periodo solicitado. Solicito del 10 al 15 de octubre. Hay reserva del 13 al 14 de octubre.

fechaSolicitadaDeEntrada< fechaEntradaEnLaReserva y fechaSolicitadaDeSalida > fechaSalidaEnLaReserva


En estos cuatro casos la habitación no está disponible para reserva, en otro caso sí está disponible.

Eligiendo del total de habitaciones las que no cumplen con estas condiciones, tendríamos las habitaciones libres.

Aunque plantearlo sin probarlo es difícil e igual ya estoy viendo doble

(http://aprenderaprogramar.com/images/thumbs_portada/thumbs_intranet/62_programador_fuera_de_si.jpg)
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 25 de Agosto 2014, 20:16
Ya me he dado cuenta de que no era tan facil.

Pero me he picado XDD
A ver si gatoher nos puede adjuntar el script sql y así podríamos hacer pruebas...

Pero creo que esta se va acercando:

Código: [Seleccionar]
select * from habitaciones where estado="Disponible" and id_habitacion
   not in(select id_habitacion from reservas
where
 (FECHA_INICIO_FILTRO  beetwen fecha_inicio_reserva and  fecha_final_reserva )
 or
( FECHA_FINAL_FILTRO  beetwen fecha_inicio_reserva and fecha_final_reserva)
or
((FECHA_INICIO_FILTRO<fecha_inicio_reserva)
 and
(FECHA_FINAL_FILTRO> fecha_inicio_reserva))
or
((FECHA_FINAL_FILTRO>fecha_final_reserva)
 and
(FECHA_INICIO_FILTRO< fecha_final_reserva)));

es cuestión de currarsela, y cuando se tenga, solo hay que coger java realizar una consulta... y ya lo tienes...

Bueno si gatoher nos pasa el script.sql lo volveré a intentar hasta que salga porque ademas es un caso que no se mee había presentado en sql, comprobar si un rango pertenece a otro rango, mola sacar consultas kilometricas....XDDD

Un saludo!!
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 21:34
Hola Dongo gracias por participar. La verdad que no es nada sencillo. Subo el script aunque
no tienes las reglas de integridad referecial, "on delete cascade, on update cascade, etc".
La verdad que no he sabido exportar la bbdd desde MySql worbrench, si me lo podeis explicar guay.

Aqui el problema es que hay dos tablas y en una se almacenas las reservas con unas determinadas fechas de inicio y fin. Yo lo que quería era que al intentar ingresar  una reserva nueva se habre un JFram y pones las fechas que el cliente solicita. Y se te muestran las habitaciones que en esas fechas no estan ocupadas.

Yo lo estaba haciendo la select en la tabla de reservas, y es ahí donde yo pienso que esta el error, pues si me devuelve x ids de habitaciones luego no se trabajar con ellas.
Pues si intento hacer una select con varias idhabitaciones tengo que hacer un bucle para recorrer el Array y luego me machaca el resultado del JTable."Vamos que solo me aparece la última habitación que esta libre". Algo tipo:

Código: [Seleccionar]
//bucle para recorrer el array con las habitaciones ocupadas
for (int h = 0; h < habitacionesOcupadas.length; h++) {
            System.out.println("La longitud de habitacionesLibres es => " + habitacionesOcupadas.length); 
            sqlHabitacionesLibres = "Select distinct idhabitacion,numero,piso,descripcion, caracteristicas," +"\n" +
                    " precio_diario,estado, tipo_habitacion  from habitacion where idhabitacion != "+habitacionesOcupadas[h]+" ";

El problema viene cuando quieres almacenarlo en el modelo del JTable. Cada pasada del bucle for elimina los datos de la anterior iteración.

Por lo tanto hay que hacer la select, que devuelva desde la tabla habitaciones.

Subo el script.
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 25 de Agosto 2014, 22:56
A ver si te vale esto para exportarla y nos la pasas con los datos, ejk lo suyo es que tengan datos dentro.

http://www.alvarolara.com/2013/02/25/backup-de-base-de-datos-desde-mysql-workbench/ (http://www.alvarolara.com/2013/02/25/backup-de-base-de-datos-desde-mysql-workbench/)

Otra cosa la forma mas fácil de rellenar un jtable es con su constructor
JTable(Object[][] rowData, Object[] columnNames);

Este constructor recibe un array de dos dimensiones con los datos, y otro array de na dimensión con los títulos de las columnas y bueno eso, lo que te comento, si nos pudieras pasar el script sql con los datos seria estupendo...

Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 25 de Agosto 2014, 23:29
Hola Dongo, para rellenar el JTablo yo lo hago asi;

Código: [Seleccionar]
public DefaultTableModel mostrar (String buscar){
    DefaultTableModel modelob;
    //Podemos usar el metodo varias veces con like %variable%
    String sql = "Select * from habitacion where idhabitacion like '%"+buscar+"%' order by idhabitacion";
    System.out.println("El sql en mostrar es; " + sql);
    String [] titulos = {"ID", "Número", "Piso", "Descripción", "Carácteristicas", "Precio diario", "Estado", "Tipo de habitación"};
    String [] registro = new String [8];
    modelob = new DefaultTableModel(null, titulos);
   
   
    try {
       
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql);
       
        while (conn.getRs().next()){
            registro [0]= conn.getRs().getString("idhabitacion");
            registro[1] = conn.getRs().getString("numero");
            registro[2] = conn.getRs().getString("piso");
            registro[3] = conn.getRs().getString("descripcion");
            registro[4] = conn.getRs().getString("caracteristicas");
            registro[5] = conn.getRs().getString("precio_diario");
            registro [6] = conn.getRs().getString("estado");
            registro [7] = conn.getRs().getString("tipo_habitacion");
           
            totalRegistro = totalRegistro + 1;
            modelob.addRow(registro);
           
           
        }
       conn.cerrarConexion();
   
       
    } catch (SQLException e) {
        JOptionPane.showMessageDialog(null, "No se ha podido recuperar el dato.");
    }
               
        return modelob;
}
   



Te subo la BBDD con 6 habitaciones  y 8 reservas.
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 26 de Agosto 2014, 10:57
Mira aquí tienes un método, al que le pasas una fecha de inicio, una fecha fin en formatos "d-m-y" y te devuelve una sentencia que al ejecutarla te devolverá las habitaciones libres en ese periodo:

Código: [Seleccionar]
public static String creaHabitacionesLibresQuery(String fecha_inicio, String fecha_fin) {
        String cadena = "select * from habitacion where estado='Disponible'  and idhabitacion\n"
                + "not in(select idhabitacion from reserva\n"
                + "where"
                + "( STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')  between fecha_reserva and  fecha_salida )\n"
                + "or\n"
                + "( STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')  between fecha_reserva and fecha_salida)\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')<fecha_reserva)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')> fecha_reserva))\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')>fecha_salida)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')< fecha_salida)))\n";

        return cadena;
    }


La forma de usarlo seria:

Código: [Seleccionar]
public static void main(String[] arg){
     String consulta = HabitacionesDisponibles.creaHabitacionesLibresQuery("01-01-2014", "25-01-2014");//esto es así porke yo he llamado HabitacionesDisponibles a la clase ke contiene este metodo
     System.out.println(consulta);
}



Lo único que faltaría sería coger esa cadena generada por ese método y ejecutarla con un statment, después simplemente rellenas la tabla con los datos devueltos por esta consulta...

Ahora si me aburro durante la mañana, te haré una clase de ejemplo de como yo relleno una tabla, y como dividir la funcionalidad en distintos métodos para que no este todo dentro de un mismo método.

Un saludo!

Nota:Yo he probado distintas sentencias y me ha devuelto siempre las habitaciones libres, si detectas que da error en algún caso, comentanoslo.
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 26 de Agosto 2014, 13:57
Hola Dogo, gracias por el interes que estas mostrando, te lo agradezco. He visto el método con la select y parece que va funcionar, pero mi poblema es que no se que hacer con ese Array de habitaciones disponibles.

Vamos para que quede claro, si me devuelve 2id de habitaciones libres 1,5,20, 30" no se luego como hacer para seleccionar esas id de la tabla habitaciones. "Hay que pensar que esas id van a ir cambiando, son dinamicas". Ese era mi problema de un principio más que el saber que habitaciones eran las que estaban libres.

Mira te pongo la clase como la tengo yo, al final esta el método que debe devolver el modelo con Table de las habitaciones disponibles;

Código: [Seleccionar]

mport Datos.Habitacion;
import Datos.Reservas;
import Presentacion.frmEscritorio;
import java.awt.HeadlessException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author carlos
 */
public class LReservas {

    Conexion conn = new Conexion();
    Reservas obj;
    public int totalRegistro = 0;

    /**
     * Metodo para buscar en el table model
     *
     * @param buscar Recibe un String para ser ejecutado en el MySql
     * @return Devuelve un TableModel
     */
    public DefaultTableModel mostrar(String buscar) {
       
        String sql="";
       
       
        DefaultTableModel modelob;
       
        //Podemos usar el metodo varias veces con like %variable%
        sql = "Select r.idreserva,r.idhabitacion,h.numero,r.idcliente," +
                "(select nombre from persona where idpersona=r.idcliente) as Ncliente," +
                "(select apaterno from persona where idpersona=r.idcliente) as Acliente," +
                "r.idtrabajador, (select nombre from persona where idpersona =r.idtrabajador)as Ntrabajador," +
                "(select apaterno from persona where idpersona=r.idtrabajador) as Atrabajador," +
                "r.tipo_reserva, r.fecha_reserva,r.fecha_ingreso,r.fecha_salida,"+
                "r.costo_alojamiento,r.observacion, r.estado from reserva r inner join habitacion h on h.idhabitacion=r.idhabitacion" +
                " where r.idreserva like '%"+buscar+"%'  order by r.idreserva desc";
           
        System.out.println("El sql en mostrar en Reservas vale ===>>>" + sql);
       
       
        String[] titulos = {"ID", "Id Habitación", "Número", "Id Cliente", "Cliente", "Id Trabajador", "Trabajador", "Tipo Reserva", "Fecha Reserva", "Fecha Ingreso", "Fecha Salida", "Total", "Observaciones", "Estado" };
        String[] registro = new String [14];
          modelob = new DefaultTableModel(null, titulos);
         
        try{
           
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql);
            while (conn.getRs().next()) {
                registro[0] = conn.getRs().getString("idreserva");
                registro[1] = conn.getRs().getString("idhabitacion");
                registro[2] = conn.getRs().getString("numero");
                registro[3] = conn.getRs().getString("idcliente");
                registro[4] = conn.getRs().getString("Ncliente")+ " " + conn.getRs().getString("Acliente");
                registro[5] = conn.getRs().getString("idtrabajador");
                registro[6] = conn.getRs().getString("Ntrabajador") + " " + conn.getRs().getString("Atrabajador");
                registro[7] = conn.getRs().getString("tipo_reserva");
                registro[8] = conn.getRs().getString("fecha_reserva");
                registro[9] = conn.getRs().getString("fecha_ingreso");
                registro[10] = conn.getRs().getString("fecha_salida");
                registro[11] = conn.getRs().getString("costo_alojamiento");
                registro[12] = conn.getRs().getString("observacion");
                registro[13] = conn.getRs().getString("estado");

             totalRegistro = totalRegistro + 1;
                System.out.println("el total registros es " +totalRegistro);
                modelob.addRow(registro);

            }
            conn.cerrarConexion();

        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrar." + e);
        }
       
       
       
       
        return modelob;
    }

    /**
     * Funcion insertar habitacion en la bbdd.
     *
     * @param obj recive un objeto de habitacion
     * @return devuelve el número de filas al realizar la operación
     *
     */
    public int insertar(Reservas obj) {

        //SQL para persona
        String sql = "insert into reserva (idhabitacion,idcliente, idtrabajador,tipo_reserva, fecha_reserva, fecha_ingreso, fecha_salida, costo_alojamiento, observacion, estado)"
                + " values ("+ obj.getIdhabitacion() + "," + obj.getIdcliente() + "," + obj.getIdtrabajador() + ",'" + obj.getTipoReserva() + "','" + obj.getfReserva() + "','" + obj.getfIngreso() + "','"
                + obj.getfSalida() + "'," + obj.getTotal() + ",'" + obj.getObservacion() + "','" + obj.getEstado()+ "' )";
        System.out.println("La sql insertar en RESERVAS vale => " +sql);
       
        int resultado = -1;
       
        try {

            conn.conecta();
            conn.crearSentencia();
            resultado = conn.updateSQL(sql); //Intentamos ingresar a la persona

            if (resultado >= 0) {

                JOptionPane.showMessageDialog(null, "La reserva ha sido ingresada con exicto.");
               
            } else {
                JOptionPane.showMessageDialog(null, "La reserva no se ha ha podido ser ingresada.");
            }
            conn.cerrarConexion();
        } catch (HeadlessException | SQLException e) {
            JOptionPane.showMessageDialog(null, "Error: " + e);
        }

        return resultado;
    }

    /**
     * Metodo para actualizar la bbdd
     *
     * @return Un entero para saber el numero de filas afectadas
     * @param obj Recibe objeto de habitacion
     */
    public int actualizar(Reservas obj) {

        String sql = "Update reserva set idhabitacion=" + obj.getIdhabitacion() + ",idcliente=" + obj.getIdcliente() + ",idtrabajador=" + obj.getIdtrabajador() + ",tipo_reserva='"
                + obj.getTipoReserva() + "', fecha_reserva='" + obj.getfReserva() + "',fecha_ingreso='" + obj.getfIngreso() + "',fecha_salida='"
                + obj.getfSalida() + "',costo_alojamiento=" + obj.getTotal() + ",observacion='"+obj.getObservacion()+"',estado='"+obj.getEstado()+"' where idreserva=" + obj.getIdreserva() + "";

       

        int resultado = -1;
       

        System.out.println("sql actualizar una RESERVA=> " + sql);
       

        try {

            conn.conecta();
            conn.crearSentencia();
            resultado = conn.updateSQL(sql);

            if (resultado >= 0) {

                JOptionPane.showMessageDialog(null, "La reserva se ha actualizado correctament.");
            } else {
                JOptionPane.showMessageDialog(null, "La reserva  no ha podido ser actualiza.");
            }
            conn.cerrarConexion();

        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "El error al actualizar ha sido, " + e);
        }

        return resultado;

    }

    /**
     * Metodo para eliminar habitaciones de la bbdd
     *
     * @param id Recibe el id de la habitación para ser eliminada
     * @return Devuelve el número de filas afectadas
     */
    public int eliminar(int id) {

        String sqlT = "Delete from reserva where idreserva =" + id + "";
       

        System.out.println("sql al eliminar Reserva => " + sqlT);
       

        int resultado = -1;
     

        try {

            conn.conecta();
            conn.crearSentencia();
            resultado = conn.updateSQL(sqlT);

            if (resultado >= 0) {

                JOptionPane.showMessageDialog(null, "La reserva ha sido eliminadoa correctamente.");

            } else {
                JOptionPane.showMessageDialog(null, "No hemos podido eliminar el la reserva.");
            }

            conn.cerrarConexion();

        } catch (SQLException e) {

            JOptionPane.showMessageDialog(null, "Hemos tenido un problema al eliminar la habitación, " + e);
        }

        return resultado;
    }

   
 /**
     * Metodo para buscar en el table model
     *las habitaciones disponibles en las fechas indicadas
     * @param fechaInicio
     * @param fechaSalida
     * @param buscar Recibe un String para ser ejecutado en el MySql
     * @return Devuelve un TableModel
     */
    public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
       
        String sql="";   
        // SQL saber habitaciones ocupadas
        sql ="Select ha.idhabitacion from reserva re, habitacion ha " +"\n" +
        " where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"'  >= re.fecha_ingreso \n" +
        "and '"+fechaInicio+"' <= re.fecha_salida and ha.estado='Disponible' ";       
       
       
        DefaultTableModel modelob = null;
        String[] titulos = {"ID",  "Numero", "Piso", "Descripcion", "Caracteristicas", "Precio Diario", "Estado", "Tipo de Habitacion"};
        String[] registro = new String [8];
       
        modelob = new DefaultTableModel(null,titulos);
        try{
           
       
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql); //Sentencia para saber el tamaño, total de habitaciones que tenemos
        while (conn.getRs().next()){
           
        }
        conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
 
           return modelob;
    }   
                   

///clase   

}


Como comento, mi problema es que aunque consiga el array con las habitaciones libres no se como manejarlo.

Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 26 de Agosto 2014, 14:45
Entonces tu problema creo que es la forma en la que intentas crear el JTable.

Haber la clase DefaultTableModel es una clase abstracta, lo que significa que esta diseñada para ser extendida. Esto se hace mayormente cuando se le quiere dar un aspecto diferente a cada fila o columna o se quiere añadir un listener a una celda,..., por ejemplo imagina que quieres obtener un listado de todas las habitaciones y crear una tabla en que las disponibles salen con letra verde, y las ocupadas en rojo.

En este caso si seria adecuado crear una clase que extienda de DefaultTableModel e implementar esta funcionalidad, osea tendrías que ir fila por fila y dependiendo de si esta ocupada o libre pintarla de un color.

Ahora si lo que quieres es crear una tabla sin mas, solo con datos, la forma mas sencilla es como ya te dije, con el constructor:

Código: [Seleccionar]
JTable(Object[][] rowData, Object[] columnNames);

Con este constructor no nos es necesario andar yendo fila por fila rellenando la tabla sino que las filas se rellenan automáticamente.

Te adjunto un ejemplo con lo mínimo para poder crear un jtable:

Fichero CreaTabla.java:
Código: [Seleccionar]

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;


public class CreaTabla extends JFrame {


    public CreaTabla(String titulo) {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//finaliza el programa cuando se da click en la X
        this.setSize(640, 480);//configurando tamaño de la ventana
        this.setLocationRelativeTo(null);
        this.setVisible(true);//configurando visualización de la ventana

    }
    public static void main(String[] arg) {
        CreaTabla cr = new CreaTabla("habitaciones");
        //creo el array de datos para la tabla
        String[][] datos = {{"1", "Disponible", "doble"}, {"2", "Disponible", "Simple"}, {"3", "No disponible", "Simple"},
        {"4", "Disponible", "Simple"}, {"5", "Disponible", "Simple"}, {"6", "Disponible", "Simple"}, {"7", "Disponible", "Simple"},
        {"8", "Disponible", "Simple"}, {"9", "Disponible", "Simple"}, {"10", "Disponible", "Simple"}};
        //creo el array con los nombres de las columnas
        String[] nombresColumnas = {"id_habitacion", "estado", "tipo"};
        //creo el jtable con el array de datos y el array de nombrs columnas
        JTable tabla=new JTable(datos,nombresColumnas);
        //creo un jscrollpane  y le paso como parametro del constructor la tabla
        //esto ahi ke hacerlo asi para ke salgan los titulos de las columnas y barra de scroll derecha
        JScrollPane panel_temp =new JScrollPane(tabla);
        //añado el Jscroll al contenedor del JFrame
        cr.add(panel_temp);
        //hago el JFrame visible
        cr.setVisible(true);
       
    }
}
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 26 de Agosto 2014, 14:54
Holo Dogo, tú olvidate del JTable. Mira yo puedo hacer esto;

Select numero_habitacion,estado,color  from habitacion where idhabitacion= 5, and idhabitacion=10 etc,etc

Es sencillo. Bien, tú ahora tienes una variable que es un Array con id de habitaciones, que es lo que tú has conseguido en el método.

¿Como haces la select, utilizando las variables que hay en el Array?
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 26 de Agosto 2014, 15:04
A mi lo mas sencillo que se me ha ocurrido es crear una reserva para cada habitacion = null
todos los campos en la tabla reserva, de esa forma puedo hacer;

select idhabitacion,numero,piso,descripcion,caracteristicas,precio_diario,estado,tipo_habitacion
from habitacion ha, reserva re where ha.idhabitacion=re.idhabitacion and fecha-entrada
+ todas las posiblidades.  :o


Es la unica forma que veo que puedo hacerlo, pero para ello como comento tengo que hacer una reserva inicial de toddas las habitaciones en la tabla reserrvas,dejandolo todo a null para poder comparar las fechas, con las reservas que si "son autenticas".

No me parece elegante la verdad, pero bueno.   :-\
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 26 de Agosto 2014, 15:34
Una prueba rápida que he hecho y parece funcionar bien, "OJO, he hecho una reserva para todas y cada una de las habitaciones con null en todos los campos" ;


Código: [Seleccionar]

 public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
       
        String sql="";
   
        // SQL saber habitaciones libres
        sql ="Select distinct ha.idhabitacion,numero,piso,descripcion,caracteristicas,precio_diario,ha.estado,tipo_habitacion  "
                + " from reserva re, habitacion ha " +"\n" +
        " where ha.idhabitacion=re.idhabitacion and  '"+fechaInicio+"' < re.fecha_ingreso \n" +
        "and '"+fechaSalida+"' < re.fecha_ingreso or '"+fechaInicio+"' > fecha_salida and "
        + "ha.estado='Disponible' ";       
        System.out.println("La sql habitaciones libres vale=>" + sql);
       
        DefaultTableModel modelob = null;
        String[] titulos = {"ID",  "Numero", "Piso", "Descripcion", "Caracteristicas", "Precio Diario", "Estado", "Tipo de Habitacion"};
        String[] registro = new String [8];
       
        modelob = new DefaultTableModel(null,titulos);
        try{
           
       
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql);
        while (conn.getRs().next()){
           
                registro[0] = conn.getRs().getString("idhabitacion");
                registro[1] = conn.getRs().getString("numero");
                registro[2] = conn.getRs().getString("piso");
                registro[3] = conn.getRs().getString("descripcion");
                registro[4] = conn.getRs().getString("caracteristicas");
                registro[5] = conn.getRs().getString("precio_diario");
                registro[6] = conn.getRs().getString("estado");
                registro[7] = conn.getRs().getString("tipo_habitacion");
               
                totalRegistro = totalRegistro + 1;
                System.out.println("el total registros es " +totalRegistro);
                modelob.addRow(registro);
        }
        conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
 
           return modelob;
    }   
                   



Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 26 de Agosto 2014, 16:02
Pues si te funciona estupendo, pero como tu dices, no es la forma mas elegante de hacerlo teniendo que meter esas id a null en la tabla reservas....

Por eso te vuelvo a pegar el código del método que te genera la select...

Código: [Seleccionar]
public static String creaHabitacionesLibresQuery(String fecha_inicio, String fecha_fin) {
        String cadena = "select idhabitacion, numero,piso,descripcion,caracteristicas,precio_diario,estado,tipo_habitacion\n "
                + "from habitacion where estado='Disponible'  and idhabitacion\n"
                + "not in(select idhabitacion from reserva\n"
                + "where"
                + "( STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')  between fecha_reserva and  fecha_salida )\n"
                + "or\n"
                + "( STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')  between fecha_reserva and fecha_salida)\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')<fecha_reserva)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')> fecha_reserva))\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')>fecha_salida)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')< fecha_salida)))\n";

        return cadena;
    }


si ejecutas este método con fecha_inicio("01-01-2014") y fecha_fin("25-01-2014") te devolverá esta cadena de texto:

Código: [Seleccionar]
select idhabitacion, numero,piso, descripcion, caracteristicas, precio_diario, estado, tipo_habitacion
 from habitacion where estado='Disponible'  and idhabitacion
not in(select idhabitacion from reserva
where( STR_TO_DATE('01-01-2014', '%d-%m-%Y')  between fecha_reserva and  fecha_salida )
or
( STR_TO_DATE('25-01-2014', '%d-%m-%Y')  between fecha_reserva and fecha_salida)
or
((STR_TO_DATE('01-01-2014', '%d-%m-%Y')<fecha_reserva)
and
(STR_TO_DATE('25-01-2014', '%d-%m-%Y')> fecha_reserva))
or
((STR_TO_DATE('25-01-2014', '%d-%m-%Y')>fecha_salida)
and
(STR_TO_DATE('01-01-2014', '%d-%m-%Y')< fecha_salida)))

Si ejecutas esa consulta en mysql workbench te darás cuenta que ahí ya tienes todos los datos de las habitaciones disponibles, y no te hace falta tener filas a null ni cosas raras...

Ya no se si tu duda es esta, o el código del DefaultTableModel, si es como rellenar un array con los datos de un resultSet, o que, en cada post te entiendo una cosa diferente...XD

Pero no te preocupes a veces es difícil entender lo que se quiere hacer...

Nada tio si ya te funciona pos nada, estupendo a seguir palante ;)

Un saludo!!
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 26 de Agosto 2014, 16:41
Vale Dongo, he probado lo que me has pasado y parece que funciona. Yo pensaba que una subconsulta solo podía devolver un valor, solo un unico valor de una unica fila y columna. Vamos un valor escalar.

Tu has hecho una subconsulta que te devuelve varios valores. A mi muchas veces me devuelve el siguiente error:

SQL Error: Subquery returns more than 1 row

A ver por eso todo el lio que yo comenteba/hacia de crear un array con las habitaciones que estaban ocupadas en Reservas, y luego como he comentado no sabia que hacer con esas id, y intentaba hacer un bucle.
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 26 de Agosto 2014, 17:40
Bueno, yo empezaría por añadir estos métodos a tu clase Conexión.

El primero recibe un String con una consulta y un objeto de tipo conexion y devuelve un array bidimensional con todos los datos de la consulta, ya tenga 1 fila o tenga 1 millon.

El segundo, recibe un String con una consulta y un objeto de tipo conexion y devuelve un array unidimensional con el nombre de las columnas de esa consulta.

Método 1:
Código: [Seleccionar]
//metodo ke recibe una cadena de texto con una consulta, un objeto de tipo Conection y
    //devuelve un array con los datos( metodo generico para cualquier consulta )
    /*Nota: Este metodo deberia estar en una clase aparte llamada por ejemplo JDBCUtil*/

    public static String[][] ejecutaConsulta(String consulta, Connection p_Conexion) {
        //creamo el array vacio ke contendrá los datos
        String[][] datos = null;

        //creamos un objeto statement vacio
        Statement st = null;
        try {
            //inicio el objeto statement ke me permitira obtener un resultSet recorrible en ambos sentidos y de solo lectura
            st = p_Conexion.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            //creo el resultset y ejecuto la consulta pasada por parametro a traves del objeto statement
            ResultSet rs = st.executeQuery(consulta);
            //Obtengo un resultSet con los metadatos de la consulta(num columnas, nom columnas, ....)
            ResultSetMetaData rsm = rs.getMetaData();
           
            //obtengo el numero de columnas del resultsetmetadata y lo guardo en la variable ke cree para ello
            int numCol = rsm.getColumnCount();
            //me voy a la ultima fila del resultSet
            rs.last();
            //creo una variable y el asigno el valor de la fila actual, en este caso la ultima.
            int numFilas = rs.getRow();
            //vuelvo al principio del resultset para empezar a recorrerlo
            rs.beforeFirst();
            //inicializo el array de datos con el numero de filas y el numero de columnas
            datos = new String[numFilas][numCol];
            //creo un contador
            int i = 0;
            //recorro el resultSet columna a columna y fila a fila y guardo el dato en el array
            while (rs.next()) {
                for (int j = 0; j < datos[0].length; j++) {
                    datos[i][j] = rs.getString(j + 1);
                }
                i++;
            }
        } catch (SQLException e) {
            //error si la consulta falla
            System.out.println("Error al ejecutar la consulta " + e.getMessage());
        }
        //Cierro el objeto statement.
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException ex) {
            //error si el statment no se puede cerrar...
            System.out.println("Error cerrando el resultset " + ex.getMessage());
        }
        //devuelvo los datos
        return datos;

    }

Método 2:
Código: [Seleccionar]
//metodo ke recibe una cadena con una consulta, un objeto de tipo Conection y
    //devuelve los nombres de las columnas de esa consulta (metodo generico para cualkier consulta)
    //este metodo viene hacer lo mismo ke el anterior pero obtengo el nombre de las columnas
    //del objeto ResultSetMeataData
    /*Nota: Este metodo deberia estar en una clase aparte llamada por ejemplo JDBCUtil*/

public static String[] getNombresColumnas(String consulta, Connection p_Conexion) {
        String[] nombresColumnas = null;

        Statement st = null;
        try {
            st = p_Conexion.createStatement();

            ResultSet rs = st.executeQuery(consulta);
            ResultSetMetaData rsm = rs.getMetaData();
            nombresColumnas = new String[rsm.getColumnCount()];

            for (int i = 0; i < rsm.getColumnCount(); i++) {
                nombresColumnas[i] = rsm.getColumnLabel(i + 1);
            }
        } catch (SQLException e) {
            System.out.println("Error obteniendo nombres de las columnas " + e.getMessage());
        }
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException ex) {
            System.out.println("Error cerrando el resultset " + ex.getMessage());
        }
        return nombresColumnas;
    }

Bien, lo siguiente que haría, sería crear un método que me genere la cadena de texto con la consulta, que es el método que te pase antes:

Código: [Seleccionar]
public static String creaHabitacionesLibresQuery(String fecha_inicio, String fecha_fin) {
        String cadena = "select idhabitacion, numero,piso,descripcion,caracteristicas,precio_diario,estado,tipo_habitacion\n "
                + "from habitacion where estado='Disponible'  and idhabitacion\n"
                + "not in(select idhabitacion from reserva\n"
                + "where"
                + "( STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')  between fecha_reserva and  fecha_salida )\n"
                + "or\n"
                + "( STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')  between fecha_reserva and fecha_salida)\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')<fecha_reserva)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')> fecha_reserva))\n"
                + "or\n"
                + "((STR_TO_DATE('" + fecha_fin + "', '%d-%m-%Y')>fecha_salida)\n"
                + "and\n"
                + "(STR_TO_DATE('" + fecha_inicio + "', '%d-%m-%Y')< fecha_salida)))\n";

        return cadena;
    }

Bien, una vez te tengo los métodos para obtener los datos de una consulta, obtener los nombres de las columnas de una consulta y obtener la sentencia sql que quiero ejecutar, simplemente crearíamos el método
que crea el modelo y que contendría el siguiente código.

Código: [Seleccionar]
public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
Connection conn;
/*aki debemos iniciar el objeto conn con una conexion a tu base de datos*/
//Una vez el conn esta iniciado solo deberemos hacer:
String consulta= NombreClase.creaHabitacionesLibresQuery(fechaInicio,fechaSalida);
String[] nombresColumnas= NombreClase.getNombresColumnas(consulta, conn);
String[][] datos= NombreClase.ejecutaConsulta(consulta, conn);
DefaultTableModel modelo=new DefaultTableModel(datos, nombresColumnas);

return modelo;
}


Fíjate ke debes crear un objeto conection y después ir llamando a los métodos creados anteriormente
al ser estáticos, Yo he puesto NombreClase, esto debes cambiarlo por el nombre de la clase donde crees estos métodos.

Te recomiendo eches un ojo a los dos primeros métodos, ya que son métodos genéricos para ejecutar una consulta cualquiera y obtener un array con los datos ...

Y bueno, esta es la forma "mas sencilla" en que yo haría para crear un modelo para un jtable con una consulta.

Y nada un saludo!!
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: gatoher en 27 de Agosto 2014, 15:31
Hola Dogo, ayer ya no puede responderte, estaba liado haciendo cosas en casa  >:(
Bueno he visto como haces para llenar el Table, te pogo como lo tengo yo:

Clase Conexion"para todo el proyecto":

Código: [Seleccionar]
/**
     * Metodo para conectarnos a la base de datos
     * @throws java.sql.SQLException
     */
   
    public void conecta () throws SQLException{
     
       
        try {
        //Registramos el driver
        String driver="com.mysql.jdbc.Driver";
        //Class.forName metodo de la clase DriverManager
        Class.forName(driver).newInstance();
         //Abrimos la conexion con la base de datos
        System.out.println("Conectando con la base de datos");
        String jdbcUrl = "jdbc:mysql://localhost:3306/reservas";
        //objeto de tipo connection, hay varios metodos getConnection
         //creamos una conexion con la base de datos
         conn = DriverManager.getConnection(jdbcUrl,"root","");
         System.out.println("Conexión establecida con la Base de datos...");
       
        }catch( SQLException error){
            Throwable fillInStackTrace = error.fillInStackTrace();
            JOptionPane.showMessageDialog(null, "Error al intentar conectar con la base de datos."+ fillInStackTrace);
        } catch (Exception error){
            JOptionPane.showMessageDialog(null, "Error al cargar el driver.");
           
            error.fillInStackTrace();
        }
       
    }
   
   
   /**
    * Metodo que prepara la sentencia y
    * dice como va a ser el resultSet
    * @throws java.sql.SQLException
    */
    public void crearSentencia() throws java.sql.SQLException{
     
        sentencia=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
        System.out.println("\nSentencia creada con éxito.");
    }   
   
    /**
     * Metodo que cierra la sentencia, resulset y
     * la conexion
     * @throws java.sql.SQLException
     */
    public void cerrarConexion() throws java.sql.SQLException{
        if(rs !=null){
            rs.close();
        }
        if(sentencia !=null){
            sentencia.close();
        }
        if(conn!=null){
            conn.close();
        }
        System.out.println("\nConexión cerrada con éxito.");
    }
   
     /**
      * Metodo que nos devuelve un resultSet
      * con todos los datos que devuelve la base.
      *
      * @param sql String con la select a ejecutar
      * @throws java.sql.SQLException
      */
    public void ejecutaSQL(String sql) throws java.sql.SQLException{
     
        rs= sentencia.executeQuery(sql);
    }
   
   
    /**
     * Metodo que recibe una select y
     * actualiza, inserta o borra en la bbdd.
     * Si tiene exicto develve las filas que han sido modificadas,
     * sino devuelve un -1.
     * @param sql String a ejecutar en la base de datos.
     * @return  Retorna un entero para saber las filas modificadas,
     * se usa para dejar los campos vacios en el formulario.
     * @throws java.sql.SQLException
     */
    public int updateSQL(String sql) throws java.sql.SQLException  {
        int upd = -1;
       
        try {
           
             upd = sentencia.executeUpdate(sql);
             }
        catch (SQLException e ) {
            JOptionPane.showMessageDialog(null, "Hemos tenido un problema en el updateSQL" + e.getMessage());
            upd = -1;
        }
        System.out.println("el valor de upd es=> " + upd);
        return upd;
    }
   
   
    //+ los metodos get y set


Luego para llenar el JTable, de paso al final he dejado asi el método, he modificado algo tú select:

Código: [Seleccionar]
/**
     * Metodo para buscar en el table model
     *las habitaciones disponibles en las fechas indicadas
     * @param fechaInicio
     * @param fechaSalida
     * @param buscar Recibe un String para ser ejecutado en el MySql
     * @return Devuelve un TableModel
     */
    public DefaultTableModel mostrarHabitacionesLibres(String fechaInicio, String fechaSalida) {
       
        String sql="";
   
        // SQL saber habitaciones libres
        sql = "select idhabitacion, numero,piso,descripcion,caracteristicas,precio_diario,estado,tipo_habitacion\n "
                + "from habitacion where estado='Disponible'  and idhabitacion\n"
                + "not in(select idhabitacion from reserva\n"
                + "where "
                + "'" + fechaInicio + "' not  between fecha_ingreso and  fecha_salida \n"
                + "or\n"
                + "'" + fechaSalida + "' not  between fecha_ingreso and fecha_salida\n"
                + "or\n"
                + "'" + fechaInicio + "' <fecha_ingreso\n"
                + "and\n"
                + "'" + fechaSalida + "' > fecha_ingreso \n"
                + "or\n"
                + "'" + fechaSalida + "' >fecha_salida \n"
                + "and\n"
                + "'" + fechaInicio + "' < fecha_salida)\n";
       
       //Básicamente si te fijas creo dos  array, uno para las cabeceras otro para los datos "claro el problema que no es dinámico y si un día modifico algun dominio de la tabla hay que venir y modificar el script"
       
//Declaro y instancio un modelo a null       
        DefaultTableModel modelob = null;
//Array para los titulos
        String[] titulos = {"ID",  "Numero", "Piso", "Descripcion", "Caracteristicas", "Precio Diario", "Estado", "Tipo de Habitacion"};
//Array par los datos
        String[] registro = new String [8];
        //Uso el propio constructor del Modelo, primero aun a nulo y el segundo parametro el array de los titulos
        modelob = new DefaultTableModel(null,titulos);
        try{
         
//Conecto bbdd
 
        conn.conecta();
        conn.crearSentencia();
        conn.ejecutaSQL(sql);
        while (conn.getRs().next()){
           
                registro[0] = conn.getRs().getString("idhabitacion");
                registro[1] = conn.getRs().getString("numero");
                registro[2] = conn.getRs().getString("piso");
                registro[3] = conn.getRs().getString("descripcion");
                registro[4] = conn.getRs().getString("caracteristicas");
                registro[5] = conn.getRs().getString("precio_diario");
                registro[6] = conn.getRs().getString("estado");
                registro[7] = conn.getRs().getString("tipo_habitacion");
               
                totalRegistro = totalRegistro + 1;
                System.out.println("el total registros es " +totalRegistro);
                modelob.addRow(registro); // Añado como primer parametro al modelo el array de con los datos
        }
        conn.cerrarConexion();
        } catch (SQLException e) {
            JOptionPane.showMessageDialog(null, "No se ha podido recuperar los datos desde mostrarHabitacionesLibres." + e);
        }
 
           return modelob; //Retorno modelo
     
    }   

//Creo que esta forma es más sencilla y limpia aunque tiene la pega que no es dinámica la tuya si.


Bueno Dongo también puedes observa que te he modificado la select, primero he quitado esta parte de la línea:

STR_TO_DATE('" + fechaInicio + "', '%d-%m-%Y')

No me hace falta ya que la fecha se introduce con un JDateChooose y no hace falta cambiar el orden. La segunda es que tú habías comparado  < y > con la fecha de reserva y esa fecha yo no la utilizo para este fin.

Pero me has dejado con la duda de que te pregunte sobre las select anidada, por que no te da el error de que la subselect devuelve mas de una fila. No lo entiendo, mira este ejemplo sencillo:

Código: [Seleccionar]
select idhabitacion from habitacion where (select idhabitacion from habitacion where idhabitacion > 2)
La subselect me debería devolver  o más idhabitaciones, estan en la misma columna claro, pero me responde:
Código: [Seleccionar]
12:24:18 select idhabitacion from habitacion where (select idhabitacion from habitacion where idhabitacion > 2) Error Code: 1242. Subquery returns more than 1 row 0.032 sec


¿Por que a tu select que devuelve más de una fila la subselect no te lo hace?
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 27 de Agosto 2014, 16:55
aaaa Amigo, jeje la select con la subconsulta no me da error por que uso el operador IN.

Si hago una consulta con subconsulta de este tipo, Usare la tabla habitación y la tabla reserva de tu BBDD:

Código: [Seleccionar]
SELECT * FROM habitacion WHERE idhabitacion IN( SELECT idhabitacion FROM reservas);

Me devolverá todas las filas de la tabla habitación, cuya id este en la tabla reservas.

El operador IN lo que espera es una lista de valores, pues yo le doy una lista de valores a través de una select.

Por otro lado si quiero las habitaciones que no están en la tabla reservas solo tendré  que negar el operador(NOT IN).

Resumiendo el operador IN es un operador que espera una lista de valores, y una select, no es más que... una lista de valores. El lenguaje sql es un lenguaje que si lo conoces a fondo te facilita mucho la vida...

Apostaría a que no sabías que se podía montar una sentencia de este tipo....:
Código: [Seleccionar]
SELECT concat( idhabitacion, " Numero de habitaciones: ",(SELECT count(*) FROM habitacion)) FROM habitacion

Bueno, eso es una de las cosas que yo echo de menos entre la variedad de cursos de esta web, a veces pensamos que una base de datos es para guardar datos y ya esta, y es un sofware muy poderoso con muchísimas capacidades, véase PL/SQL...

La verdad que me podría pasar horas hablando de las ventajas que tiene saber bien sql, pues a la hora de procesar datos podemos delegar muchas funciones sobre la base de datos.

Y nada yo creo que hoy en día no hay aplicación empresarial sin una base de datos por detrás por eso creo que saber sql es una cuestión fundamental para todo desarrollador.

Y nada mas, te animo a que lo estudies porque te sorprenderás de las cosas que puedes hacer con él.

Un saludo!!

P.D. Por cierto, sigo pensando que tu manera de crear el jtable es ganas de complicarse la vida....
Título: Re:intervalos de fechas MySql para reservas en hotel
Publicado por: dongo en 27 de Agosto 2014, 17:12
Por cierto a tu select en la condición es que le falta la mitad, le falta la columna de la select principal con la que vas a comparar la subselect y también le falta el operador...

Código: [Seleccionar]
select idhabitacion from habitacion where idhabitacion in (select idhabitacion from habitacion where idhabitacion > 2)


Si te fijas entre el where y la subselect, yo le he metido:

Si la ejecutas, con esas dos cosas, ya te funciona... que te haga lo que tu quieres ya es otra cosa, pero al menos ya devuelve algo...