{"id":903,"date":"2022-03-29T15:14:52","date_gmt":"2022-03-29T19:44:52","guid":{"rendered":"http:\/\/gregorgonzalez.com.ve\/blog\/?p=903"},"modified":"2022-03-29T15:20:25","modified_gmt":"2022-03-29T19:50:25","slug":"java-mostrar-registros-dinamicamente-a-partir-de-una-vista","status":"publish","type":"post","link":"https:\/\/gregorgonzalez.com.ve\/blog\/java-mostrar-registros-dinamicamente-a-partir-de-una-vista\/","title":{"rendered":"Java &#8211; Mostrar registros din\u00e1micamente a partir de una vista"},"content":{"rendered":"<p>Varios de los reportes que manejo son simples tablas que muestran informaci\u00f3n, el inconveniente es que cada vez que se agrega, cambia o elimina alguna informaci\u00f3n debo cambiar los datos de las vistas y luego la aplicaci\u00f3n para realizar nuevamente un deploy al servidor.<\/p>\n<p>Ya he hecho y configurado tanto tablas din\u00e1micas como formularios din\u00e1micos a partir de una tabla de configuraci\u00f3n, esto es muy largo y tedioso, entonces me propuse a buscar un m\u00e9todo simple para solo mostrar informaci\u00f3n.<\/p>\n<p>La idea original es: Usemos una vista para indicar tanto el t\u00edtulo de las columnas como los datos de los registros para crear una tabla html autom\u00e1tica, de esta manera si necesitamos agregar, cambiar o eliminar una columna o dato, lo hagamos directamente en la vista y no en la aplicaci\u00f3n.<\/p>\n<p>Digamos que tenemos una vista de la siguiente manera:<\/p>\n<pre class=\"lang:plsql decode:true\">CREATE OR REPLACE FORCE VIEW V_DOCUMENTOS\r\nAS\r\n   SELECT ID_CLIENTE,\r\n          NRO_DOC \"NRO DOC.\",\r\n          (CASE WHEN COD = 'LO' THEN 'LOCAL' ELSE 'EXTERNO' END) \"SUCURSAL\",\r\n          FORMATO_NUMERO(SALDO) \"SALDO\",\r\n          FORMATO_NUMERO(CAPITAL) \"CAPITAL\",\r\n          REEMPLAZAR(INTER) \"INTERESES\",\r\n          CTA \"CUENTA CONTABLE\"\r\n     FROM DOCUMENTOS;\r\n<\/pre>\n<p>En la vista realizamos nuestros formatos, c\u00e1lculos y dem\u00e1s cosas necesarias para dejarla lista para mostrar, los alias de las columnas las colocamos en comillas dobles y luego las usaremos como columnas para la tabla html. Esto limita lo que se puede hacer con dicha vista pero es perfecta para el reporte.<\/p>\n<p>Luego en java para tomar la informaci\u00f3n de las columnas, hacemos uso del m\u00e9todo del statement <strong>getMetaData()<\/strong>, supongamos que tengamos un DAO con un m\u00e9todo que realiza un simple select a la vista:<\/p>\n<pre class=\"lang:java decode:true\">public Vector buscarDoc(String idCliente) throws SQLException {\r\n    conexion = getConnection();\r\n    Vector doc = new Vector();\r\n    PreparedStatement ps = null;\r\n    ResultSet rs = null;\r\n\r\n    try {\r\n        String sqlDoc = \"SELECT * FROM v_documentos WHERE id_cliente = ?\";            \r\n        ps = conexion.prepareStatement(sqlDoc);\r\n        ps.setString(1, idCliente);\r\n        rs = ps.executeQuery(); \r\n\r\n        ResultSetMetaData rsmd = rs.getMetaData();\r\n        int columnCount = rsmd.getColumnCount();   \r\n         \r\n        Vector columnas = new Vector();\r\n        for (int i = 1; i &lt;= columnCount; i++ ) { \/\/ Columnas inicia en 1\r\n            if (i != 1){ \/\/ Saltamos el primero que es el ID del cliente                 \r\n                String name = rsmd.getColumnName(i);\r\n                columnas.addElement(name);\r\n            }\r\n        }\r\n        doc.addElement(columnas);  \r\n                      \r\n        while (rs.next()) {\r\n            Vector items = new Vector();\r\n            for (int i = 0; i &lt; columnas.size(); i++ ) { \/\/ Vector inicia en 0\r\n                 String dato = rs.getString(columnas.get(i).toString());\r\n                 items.addElement(dato);\r\n            }\r\n            doc.addElement(items);\r\n        }\r\n    } catch (Exception se) {\r\n         se.printStackTrace();\r\n    } finally {\r\n        closeJdbcObjects(conexion, ps, rs);\r\n    }\r\n    return doc;\r\n}\r\n<\/pre>\n<ul>\n<li>Primero recorremos el nombre en las columnas y lo agregamos a un vector \u00abcolumnas\u00bb.<\/li>\n<li>Segundo recorremos los datos a partir de la columna anterior y lo agregamos a otro vector \u00abitems\u00bb.<\/li>\n<li>Ambos se agregan al vector principal \u00abdoc\u00bb y aunque no exista registros, siempre devolver\u00e1 las columnas.<\/li>\n<\/ul>\n<p>Toma en cuenta que nos saltamos la primera columna id_cliente, ya que es un dato que no quiero mostrar en el reporte, esto es lo \u00fanico que controlamos desde la aplicaci\u00f3n y nos limita a que no podemos elegir que otra columna no mostrar, si luego deseamos eliminar otra, simplemente se quita de la vista.<\/p>\n<p>En el lado de la vista tenemos un JSP:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;table border=\"0\" width=\"80%\" align=\"center\"&gt;\r\n    &lt;c:forEach var=\"docItems\" items=\"${doc}\" varStatus=\"iterador\"&gt;\r\n    &lt;c:if test = \"${iterador.index == 0}\"&gt; &lt;!-- Header --&gt;\r\n        &lt;tr&gt;\r\n            &lt;c:forEach var=\"item\" items=\"${docItems}\"&gt;\r\n                &lt;th&gt;&lt;c:out value=\"${item}\"\/&gt;&lt;\/th&gt;\r\n            &lt;\/c:forEach&gt;\r\n        &lt;\/tr&gt;\r\n    &lt;\/c:if&gt;\r\n    &lt;c:if test=\"${iterador.index &gt; 0}\"&gt; &lt;!-- Body --&gt;\r\n        &lt;tr&gt;\r\n            &lt;c:forEach var=\"item\" items=\"${docItems}\"&gt;\r\n                &lt;td&gt;&lt;c:out value=\"${item}\"\/&gt;&lt;\/td&gt;\r\n            &lt;\/c:forEach&gt;\r\n        &lt;\/tr&gt;\r\n    &lt;\/c:if&gt;\r\n    &lt;\/c:forEach&gt;\r\n&lt;\/table&gt;<\/pre>\n<p>Donde recorremos el vector con un simple foreach y tomando en cuenta que el primer registro son los nombres de las columnas de la tabla (HEADER) y el resto son los registros a mostrar (BODY).<\/p>\n<p>Quedando de una forma din\u00e1mica y automatizada de la siguiente manera:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-904 aligncenter\" src=\"http:\/\/gregorgonzalez.com.ve\/blog\/wp-content\/uploads\/tabla-dinamica.jpg\" alt=\"\" width=\"1055\" height=\"75\" srcset=\"https:\/\/gregorgonzalez.com.ve\/blog\/wp-content\/uploads\/tabla-dinamica.jpg 1055w, https:\/\/gregorgonzalez.com.ve\/blog\/wp-content\/uploads\/tabla-dinamica-300x21.jpg 300w, https:\/\/gregorgonzalez.com.ve\/blog\/wp-content\/uploads\/tabla-dinamica-1024x73.jpg 1024w, https:\/\/gregorgonzalez.com.ve\/blog\/wp-content\/uploads\/tabla-dinamica-768x55.jpg 768w\" sizes=\"(max-width: 1055px) 100vw, 1055px\" \/><\/p>\n<p>Esto funciona para simples datos a mostrar, tiene sus limitantes, como por ejemplo, no poder indicar estilos directamente en la vista, tambi\u00e9n que la vista solo funcionar\u00eda para ese reporte ya que las columnas est\u00e1n modificadas para tal y no ser\u00eda ideal utilizarla para consultar en otros m\u00f3dulos.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Varios de los reportes que manejo son simples tablas que muestran informaci\u00f3n, el inconveniente es que cada vez que se agrega, cambia o elimina alguna informaci\u00f3n debo cambiar los datos de las vistas y luego la aplicaci\u00f3n para realizar nuevamente un deploy al servidor. Ya he hecho y configurado tanto tablas din\u00e1micas como formularios din\u00e1micos [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":688,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[227],"tags":[340,228,241,336,341],"_links":{"self":[{"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/posts\/903"}],"collection":[{"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/comments?post=903"}],"version-history":[{"count":3,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/posts\/903\/revisions"}],"predecessor-version":[{"id":907,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/posts\/903\/revisions\/907"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/media\/688"}],"wp:attachment":[{"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/media?parent=903"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/categories?post=903"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gregorgonzalez.com.ve\/blog\/wp-json\/wp\/v2\/tags?post=903"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}