Escolar Documentos
Profissional Documentos
Cultura Documentos
Clase java para recorrer registros de tabla SQL Server con botones primero, anterior, siguiente y ultimo. El objetivo de esta entrada de blog es mostrar una clase diseada por mi para facilitar la navegacion por los registros de una tabla. Se me ocurrio esto debido a que en muchas ocasiones en los programas necesitamos recorrer los registros de una tabla con los tipicos botones: Primero Permite ir al primer registro de la tabla. Anterior Permite ir al anterior registro. Siguiente Permite ir al siguiente registro. Ultimo Permite ir al ultimo registro. La siguiente imagen muestra un ejemplo clasico donde se requieren estos botones (los botones con flechas verdes):
Como se puede imaginar con ayuda de estos botones nos podemos colocar en cualquier registro de la tabla y una vez posicionados en el registro deseado se pueden usar otros botones para modificar o eliminar el registro. Bueno sin mas preambulos muestro el codigo de la clase: GonzaBD.java El truco de esta clase es almacenar en un array todos los campos llave de la tabla que se desee manipular (por cada tabla se debe crear un nuevo objeto de esta clase). Al llamar al metodo primero() con ayuda de una variable se accede al primer elemento del arreglo de llaves primarias. Al llamar al metodo ultimo() con ayuda de una variable se accede al ultimo elemento del arreglo de llaves primarias. Al llamar al metodo siguiente() con ayuda de una variable; si por ejemplo estamos en la fila 5, se accede al elemento 5 +1, del arreglo de llaves primarias. Despues se realiza un Select hacia la tabla y los datos quedan en un Objeto Resultset (llamado rs) que es local a esta clase. Bueno a continuacion muestro el codigo: /* * Instituto Tecnologico de Zacatepec Clase que contiene metodos para recorrer los registros de una
* Descripcion: tabla *
siguiente o ultimo registro * Archivo: GonzaBD.java * author Gonzalo Silverio * fuente: */ import java.sql.*; gonzasilve@hotmail.com
http://gonzasilve.wordpress.com
public class GonzaBD { String strSentenciaSQL = ""; String strCadenaConexion = ""; String strOrdenarPor = ""; String strCampoLLave = ""; String strTabla = "";
//Los posibles tipos del campo llave son cadena y entero //Por defecto el campo llave es de tipo cadena String strTipoCampoLlave = "cadena";
String strDriverMySQL
="com.mysql.jdbc.Driver";
String strManejador String strBaseDatos String strServidor String strUsuario String strPassword String strControlador String strPuerto
public GonzaBD() {
//se mueve a la primera fila y devuelve true si se pudo, false sino se pudo ir a la primera fila public { try { intFilaActual = 0; if( strTipoCampoLlave.equals("cadena") ) rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'"); else rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]); boolean primero()
//se mueve a la anterior fila y devuelve true si se pudo, false sino se pudo ir a la anterior fila public { try { intFilaActual--; if(intFilaActual<0) intFilaActual=0; boolean anterior()
if( strTipoCampoLlave.equals("cadena") ) rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'"); else rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
//se mueve a la siguiente fila y devuelve true si se pudo, false sino se pudo ir a la siguiente fila public { try { intFilaActual++; if(intFilaActual>intTotalRegistros-1) intFilaActual=intTotalRegistros-1; boolean siguiente()
if( strTipoCampoLlave.equals("cadena") ) rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'"); else rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
//se mueve a la ultima fila y devuelve true si se pudo, false sino se pudo ir a la ultima fila public { try { intFilaActual = intTotalRegistros-1; boolean ultimo()
if( strTipoCampoLlave.equals("cadena") ) rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"='"+strArrayCamposLlave[intFilaActual]+"'"); else rs = ejecutarConsulta("SELECT * FROM " + strTabla + " WHERE "+strCampoLLave+"="+intArrayCamposLlave[intFilaActual]);
//Obtiene el controlador del manejador mysql o postgres public { if(manejador.equals("sqlserver")) return strDriverSqlServer; else if(manejador.equals("mysql")) return strDriverMySQL; else if(manejador.equals("postgres")) return strDriverPostgres; String obtenerDriverManejador(String manejador)
return strDriverMySQL; }
//Conecta a la BD con los datos por default public boolean conectarBD() throws SQLException { try { return conectarServidor(strManejador,strServidor,strUsuario,strPassword,strBaseDatos,str Controlador); } catch ( SQLException e ) { e.printStackTrace(); return false; } }
//Conecta a la BD con los datos especificados public boolean conectarBD(String usuario, String password, String BD, String manejador) //throws SQLException { boolean ress; try {
strControlador = obtenerDriverManejador(manejador); strUsuario strPassword strBaseDatos strManejador ress = conectarServidor(manejador,strServidor,usuario,password,BD,strControlador); return ress; } catch ( SQLException e ) { e.printStackTrace(); return false; } } = usuario; = password; = BD; = manejador;
//Conecta a la BD con los datos del usuario, bd y password especificados, para los demas toma los k estan por default public boolean conectarBD(String usuario, String password, String BD )// throws SQLException { boolean ress; try { strUsuario strPassword = usuario; = password;
strBaseDatos ress =
= BD;
//permite especificar el campo por el que se van a ordenar los registros public { strOrdenarPor = campo; } void ordenarPor(String campo)
//Realiza una conexion a sqlserver, mysql o postgres con los datos especificados public boolean conectarServidor(String manejador,String servidor,String usuario,String pw,String bd, String driver) throws SQLException { if(manejador.equals("sqlserver")) { try
{ Class.forName(driver); strCadenaConexion = "jdbc:jtds:sqlserver://"+servidor+"/"+bd+";instance=SQLSERVEREXPRESS;"; con = DriverManager.getConnection(strCadenaConexion,usuario,pw); if (con == null ) return false; return true; } catch(SQLException sqlex) { sqlex.printStackTrace(); return false; } catch(Exception e) { e.printStackTrace(); return false; } } else if(manejador.equals("mysql")) { try {
return true; } catch(SQLException sqlex) { sqlex.printStackTrace(); return false; } catch(Exception e) { e.printStackTrace(); return false; } } else if(manejador.equals("postgres")) { try { Class.forName(driver);
return false; }
public ResultSet ejecutarConsulta(String cadSQ) throws SQLException { rs = null; if( ! strOrdenarPor.equals("") ) cadSQ += " ORDER BY " +strOrdenarPor;
public {
void obtenerCamposLlave()
obtenerCamposLlave(strTabla); }
//Si el campo llave es de tipo entero guarda los campos llave en un arreglo de enteros //Si el campo llave es de tipo cadena guarda los campos llave en un arreglo de Strings public { int c=0; try { rs = ejecutarConsulta("SELECT * FROM " + tabla); while(rs.next()) c++; intTotalRegistros = c; strArrayCamposLlave = new String[intTotalRegistros]; intArrayCamposLlave = new int[intTotalRegistros]; void obtenerCamposLlave(String tabla)
cerrar(rs);
//Ejecutar nuevamente la consulta rs = ejecutarConsulta("SELECT * FROM " + tabla); rs.next(); //Moverse al primer registro
// Cierra un objeto Resultset public static void cerrar(ResultSet rs) { try { rs.close(); } catch(Exception ex)
{ ex.printStackTrace(); } }
// cierra un objeto Statemet public static void cerrar(Statement st) { try { st.close(); } catch(Exception ex) { ex.printStackTrace(); } }
// Cierra un objeto Connection public static void cerrar(Connection con) { try { con.close();
//Permite especificar cual es el campo llave de la tabla public { strCampoLLave = campo; } void setCampoLlave(String campo)
//Permite especificar cual es el campo llave y su tipo, de la tabla public { strCampoLLave = campo; strTipoCampoLlave = tipo; } void setCampoLlave(String campo, String tipo)
//Especifica la tabla sobre la k se va a trabajar public { try { strTabla = tabla; st=con.createStatement(); } catch(SQLException ex) { ex.printStackTrace(); } void setTabla(String tabla)
} } //Fin de la clase
Como se puede observar en la linea 229 de la clase GonzaBD.java estoy usando un nombre de instancia llamadoSQLSERVEREXPRESS Esta clase se podria editar para recibir tambien como parametro el nombre de la instancia de SQL Server que se desee utilizar, se queda de tarea. Lo interesante de esta clase es que esta preparada para recorrrer los registros de tablas que esten creadas en cualquera de los manejadores SQL Server, MySQL o de Postgres, obviamente que los .jar de los JConnector de dichos DBMS deben estar copiados en C:\Program Files\Java\jdk1.6.0_23\jre\lib\ext, Lo que esta en negrita lo e resaltado debido a que la version del JVM puede cambiar segun la que tengas instalada. Los JConnector que e usado para probar esta clase son los siguientes (puedes dar click en el enlace para descargarlo sino lo tienes). JConnector de SQL Server: jtds-1.2.5.jar JConnector de Postgres: postgresql-9.1-901.jdbc4.jar JConnector de MySQL: mysql-connector-java-5.1.18-bin.jar Para ejemplificar el uso de la clase anterior e usado una tabla que esta en SQL Server. Los parametros de conexion son:
Manejador de Base de datos (DBMS): SQL Server 2005 Express Base de datos: prueba Tabla: alumnos Usuario: sa Password: root El Script para crear la tabla alumnos en SQL Server es el siguiente: create table alumnos(matricula int, nombre char(50), apellidos char(100), edad int, peso decimal(10,2),sexo char(1), PRIMARY KEY(matricula) ); La imagen de la tabla ya creada en SQL Server se ve asi:
BREVE EXPLICACION DE LOS ATRIBUTOS DE LA CLASE gonzaBD: Atributo Descripcion Contiene un nmero que se usa como ndice para acceder a una llave primaria intfilaActual dentro del arreglo strArrayCamposLlave o el arreglo strArrayCamposLlave (dependiendo de si la llave primaria es de tipo cadena o tipo entero, respectivamente). Este atributo contiene el nmero actual de fila-1. Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Cadena. Arreglo que contiene las llaves primarias de la tabla en caso de que el tipo de dato del campo llave sea Entero. Contiene los datos de la fila actual mostrandose. Cada vez que se manda a rs llamar al mtodo primero(), anterior(), siguiente() o ultimo() se realiza una consulta y este atributo (tipo Resultset) se actualiza con los campos de la nueva fila. COMO SE USA LA CLASE gonzaBD A continuacion voi a poner un fragmento de codigo con la intencion mostrar los pasos a realizar para usar correctamente la clase. //Crear un objeto de esta clase GonzaBD a = new GonzaBD(); //AHORA SE DEBE REALIZAR LO SIGUIENTE EN EL MISMO ORDEN //Primeramente se debe indicar especificar cual es la llave primaria de la tabla y su tipo a.setCampoLlave("matricula","entero");
strArrayCamposLlave[]
intArrayCamposLlave[]
//Se de desea se puede indicar que si se desean ordenar los registros de la tabla por un campo, //este paso es opcional en todo caso sino se realiza, no se ordenan por ningn campo a.ordenarPor("nombre"); //A continuacin usamos un metodo sobrecargado para conectarse al DBMS, aqu es donde //indicamos a que manejador se debe accesar a.conectarBD("sa","root","prueba","sqlserver"); //Una vez que ya estamos conectados se debe especificar la tabla que se va a manipular a.setTabla("alumnos"); //Ahora se manda a llamar al mtodo que rellena el arreglo de llaves primarias dentro de la clase; //dependiendo del tipo de dato del campo llave se rellena el arreglo de Strings o el arreglo de //enteros. a.obtenerCamposLlave(); //Ahora ya se puede llamar a cualquiera de los mtodos primero(), anterior(), siguiente() o ultimo()... Despues de realizar lo anterior, para que el objeto rs se rellene con los datos de la primera fila se invoca al metodo: a.primero(); Despus de que se invoco ese metodo, el atributo rs de la clase gonzaBD se quedara con los datos de la fila 1. Supongamos que la tabla alumnos contiene las siguientes filas, rs apuntara a la fila:
Si inmediatamente despues se llama al mtodo siguiente() a.siguiente(); El atributo rs apuntara al siguiente registro despues del primero, es decir rs apuntara a la fila:
Y asi sucesivamente, una observacin: si te fijas en el codigo de los metodos (siguiente() y anterior()) cuando se ha llegado a la ultima fila, es decir, si rs apunta al registro 4 y se ejecuta una llamada al mtodo siguiente() (se intenta accesar una fila despus de la ultima); dicho mtodo contiene un candado para detectar eso y siempre dejara a rs apuntando al ultimo registro. El mtodo anterior() igualmente tiene esa precaucion y siempre que se intente accesar a un registro antes del primero automticamente mover a rs para que apunte a la primera fila. De esta manera no es posible sobrepasar los limites (inferior ni superior) de filas de la tabla que se este manipulando. Finalmente Para ilustrar el uso de la clase gonzaBD anterior he creado una ventana muy basica. JfrPrincipal.java Esta clase crea una ventana de formulario con 6 campos y los 4 botones; primero, anterior, siguiente y ultimo en la parte inferior de dicha ventana. Es la misma clase que utilice para ilustrar como usar ventanas de formulario en Java, pero la he modificado y adaptado para este ejemplo mas elaborado. Bueno ahora muestro el codigo: /* * Instituto Tecnologico de Zacatepec Clase que crea una GUI para ilustrar el uso de la clase EasyBD
* Descripcion:
http://gonzasilve.wordpress.com
//Se usara para cambiar los Margenes de los botones import java.awt.Insets;
public class JfrPrincipal extends JFrame { //Campos de texto y sus etiquetas JLabel jlbMatricula; JLabel jlbNombre; JLabel jlbApellidos; JLabel jlbEdad; JLabel jlbPeso; JLabel jlbSexo; JTextField JTextField JTextField JTextField JTextField JComboBox jtfMatricula; jtfNombre; jtfApellidos; jtfEdad; jtfPeso; jcbSexo;
//Botones de navegacion de los registros JButton btnPrimero; JButton btnAnterior; JButton btnSiguiente; JButton btnUltimo;
//Objeto de la clase que nos ayuda a navegar por los registros de la tabla GonzaBD bd = new GonzaBD();
JfrPrincipal(String strTitulo, int intAncho, int intAlto) { super(strTitulo); this.setSize(intAncho, intAlto); this.setResizable(false); this.setLocationRelativeTo(null); pantalla //Ventana no redimensionable //Centrar ventana en
//Box vertical por que los botones van a estar abajo Box boxVContenidoVerticalVentana = Box.createVerticalBox(); crearCamposVentana(); crearBotones(); //Espacio del borde superior de la ventana al primer Campo boxVContenidoVerticalVentana.add(Box.createVerticalStrut(30)); boxVContenidoVerticalVentana.add(boxVCamposVentana); //Espacio entre el ultimo campo (sexo) y los botones Guardar y Cancelar boxVContenidoVerticalVentana.add(Box.createVerticalStrut(20)); boxVContenidoVerticalVentana.add(panBotones);
this.add(boxVContenidoVerticalVentana);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Conecta la Base de datos conectarBD(); bd.primero(); rellenarCampos(); datos del primer registro //Posicionarse en el primer registro //Rellenar los campos con los
//ASIGNAR UN ESCUCHADOR PARA CADA BOTON DE NAVEGACION //Boton Primero btnPrimero.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { bd.primero(); rellenarCampos(); } }); //Boton Anterior btnAnterior.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { bd.anterior(); rellenarCampos();
} }); //Boton Siguiente btnSiguiente.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { bd.siguiente(); rellenarCampos(); } }); //Boton Ultimo btnUltimo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { bd.ultimo(); rellenarCampos(); } });
//Crea los campos de la ventana (cada caja tiene su correspondiente etiqueta) private void crearCamposVentana() { Box boxHMatricula = Box.createHorizontalBox(); jtfMatricula = new
panMatricula.add(boxHMatricula);
Box boxHNombre =
panNombre.add(boxHNombre);
Box boxHApellidos =
panApellidos.add(boxHApellidos);
Box boxHEdad =
panEdad.add(boxHEdad);
Box boxHPeso =
panPeso.add(boxHPeso);
Box boxHSexo =
panSexo.add(boxHSexo);
boxVCamposVentana = Box.createVerticalBox(); boxVCamposVentana.add(panMatricula); boxVCamposVentana.add(Box.createVerticalStrut(10)); boxVCamposVentana.add(panNombre); boxVCamposVentana.add(Box.createVerticalStrut(10)); boxVCamposVentana.add(panApellidos); boxVCamposVentana.add(Box.createVerticalStrut(10)); boxVCamposVentana.add(panEdad); boxVCamposVentana.add(Box.createVerticalStrut(10)); boxVCamposVentana.add(panPeso); boxVCamposVentana.add(Box.createVerticalStrut(10)); boxVCamposVentana.add(panSexo);
btnPrimero = new JButton("|< Primero"); btnAnterior = new JButton("< Anterior"); btnSiguiente = new JButton("Siguiente >"); btnUltimo = new JButton("Ultimo >|"); //Cambiar los margenes de los botones //Insets(margen_sup, margen_izq, margen_inf, margen_der) btnPrimero.setMargin(new Insets(0, 2, 0, 2)); btnAnterior.setMargin(new Insets(0, 2, 0, 2)); btnSiguiente.setMargin(new Insets(0, 2, 0, 2)); btnUltimo.setMargin(new Insets(0, 2, 0, 2));
panBotones =
panBotones.add(boxHBotones); } //Conecta con la BD y devuelve true si se conecto correctamente //false en cualquiero otro caso public boolean conectarBD() { // Especificar cual es la llave primaria de la tabla y su tipo bd.setCampoLlave("matricula","entero"); bd.ordenarPor("nombre"); //Ordena los registros de la tabla por este campo
//especifica la tabla sobre la que se va a manipular bd.setTabla("alumnos"); //Dentro del objeto bd rellena un arreglo con las llaves //primarias de la tabla que se esta manipulando bd.obtenerCamposLlave();
return true; }
//Rellena los campos de texto con los datos del registro actual public void rellenarCampos() { try { jtfMatricula.setText(aCadena(bd.rs.getInt("matricula"))); jtfNombre.setText(bd.rs.getString("nombre").trim ()); jtfApellidos.setText(bd.rs.getString("apellidos").trim ()); jtfEdad.setText(aCadena(bd.rs.getInt("edad"))); jtfPeso.setText(aCadena(bd.rs.getFloat("peso"))); jcbSexo.setSelectedItem( bd.rs.getString("sexo").equals("f") ? "Femenino" : "Masculino" );
//Recibe un numero entero y lo devuelve como Cadena (String) private String aCadena(int num)
{ return String.valueOf(num); }
//Recibe un numero decimal y lo devuelve como Cadena (String) private String aCadena(float num) { return String.valueOf(num); }
public static void main(String args[]) { JfrPrincipal prueba1 = new JfrPrincipal("Recorrer registros de SQL Server en Java",400,400); prueba1.mostrar(); } } Y aqui una imagen de la ejecucion:
Como decia anteriormente lo interesante es que si ahora deseamos que la tabla alumnos este creada en MySQLo Postgres, entonces la creamos en dicho manejador (con ayuda del script que puse mas arriba) y en la linea 216 de la clase JfrPrincipal.java, cambiamos los parametros de Conexion (usuario,pass,bd, manejador) de dicho manejador, la clase automaticamente usara el Driver adecuado y se conectara a dicho DBMS sin problemas. Sin querer se hizo un poco largo este ejemplo, pero no era para mas, espero haber sido lo suficiente explicito y no haber dejado muchas dudas, los ya avanzados en Java supongo que mi codigo lo habran digerido sin problemas y los que empiezan de todas maneras pregunten sin compromiso, les aseguro que yo tambien soy un novato y seguro hay alguna manera mas fina y elegante de hacer esto del recorrido de registros, solo es una idea. . Y es que a la clase GonzaBD.java la simplifique y le quite mucho codigo para que quedara simple y sencilla de entender ya que mi version original tiene muchos mas metodos para realizar las cuatro Operaciones SQL de manera mas simple (INSERT, DELETE, UPDATE, SELECT), pero me reservo el codigo y posiblemente mas adelante lo libere en este mismo blog, por ahora creo que seria demasiado y requeria mas tiempo para explicarlo y estoy en el fin de mi ultimo semestre de la carrera!!! poryectos por aqui, proyectos por allaa. Bueno no me queda mas que decir hasta pronto y si a alguien le interesan los fuentes basta con pedirlos y se los envio, hasta pronto y gracias x visitar.