Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] Automatizar SQL con DatabaseMetaData

Estas en el tema de Automatizar SQL con DatabaseMetaData en el foro de Java en Foros del Web. Hola a todos, quería hacerles una consulta resulta que estoy tratando de automatizar las consultas sql con DatabaseMetaData digamos que con los insert, update, delete ...
  #1 (permalink)  
Antiguo 28/09/2016, 22:15
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Automatizar SQL con DatabaseMetaData

Hola a todos, quería hacerles una consulta resulta que estoy tratando de automatizar las consultas sql con DatabaseMetaData digamos que con los insert, update, delete y selectxId no estoy teniendo problemas con un select genérico que quiero automatizar los inner join no sé cómo lo puedo encarar xq los campos y los where los puedo hacer, pero los inner me complican tanto que no sé cómo seguir.

Acá pongo el código:

Código Java:
Ver original
  1. public String select(String[] cols, String[] tables, String[] where){
  2. String Consulta = "select ";
  3. if(cols == null){
  4. Consulta += "* ";
  5. } else {
  6. for(String c : cols){
  7. Consulta += c;
  8. if(!cols[cols.length -1].equals(c)){
  9. Consulta += ",";
  10. } else {
  11. Consulta += " ";
  12. }
  13. }
  14. }
  15. Consulta += "from " + this.getTable();
  16. if(tables != null){
  17. char primera = this.getTable().charAt(0);
  18. char prox;
  19. Consulta += " " + primera + " ";
  20. for(String t : tables){
  21. Consulta += "inner join " + t + " on ";
  22. if(!tables[tables.length -1].equals(t)){
  23. Consulta += ",";
  24. } else {
  25. Consulta += " ";
  26. }
  27. }
  28. }
  29. if(where != null){
  30. Consulta += " where ";
  31. for(String w : where){
  32. Consulta += w + " = ?";
  33. if(!where[where.length -1].equals(w)){
  34. Consulta += " and ";
  35. }
  36. }
  37. }
  38. return Consulta;
  39. }

Espero sus respuestas y saludos.
  #2 (permalink)  
Antiguo 29/09/2016, 22:58
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Respuesta: Automatizar SQL con DatabaseMetaData

Hola a todos, les cuento que estuve trabajando en el select genérico y este es el resultado:

Código Java:
Ver original
  1. public String select(String[] cols, String[] tables, String style, String[] where){
  2. String Consulta = "select ";
  3. if(cols == null){
  4. Consulta += "* ";
  5. } else {
  6. Consulta += this.createColumns(cols, tables);
  7. }
  8. Consulta += "from " + this.getTable();
  9. if(tables != null){
  10. String[] tab = this.prepareTables(tables);
  11. Consulta += " " + this.getTable().charAt(0);
  12. Consulta += this.createJoin(style,tab);
  13. }
  14. if(where != null){
  15. Consulta += " where ";
  16. for(String w : where){
  17. Consulta += w + " = ?";
  18. if(!where[where.length -1].equals(w)){
  19. Consulta += " and ";
  20. }
  21. }
  22. }
  23. return Consulta;
  24. }
  25. private String createJoin(String style,String[] tables){
  26. String join = " ";
  27. if(tables != null){
  28. for(String t : tables){
  29. if(!t.equals(this.getTable())){
  30. char ps = t.charAt(0);
  31. join += style + " join " + t + " " + ps + " on" + this.createCombos(tables);
  32. }
  33. }
  34. }
  35. return join;
  36. }
  37. private String[] prepareTables(String[] tables){
  38. String[] tab = new String[tables.length +1];
  39. tab[0] = this.getTable();
  40. for(int i = 0; i < tables.length; i++){
  41. tab[i+1] = tables[i];
  42. }
  43. return tab;
  44. }
  45. private String createCombos(String[] tables){
  46. String combo = " ";
  47. for(int i = 0; i < tables.length -1; i++){
  48. char fk = tables[i+1].charAt(0);
  49. char pk = tables[i].charAt(0);
  50. LinkedList<String> keys = this.objbd.getPrimaryKeys(tables[i+1]);
  51. LinkedList<String> fays = this.objbd.getForeignKeys(tables[i]);
  52. for(String f : fays){
  53. for(String k : keys){
  54. if(k.equals(f)){
  55. combo += fk +"."+f +" = "+pk +"."+k;
  56. }
  57. }
  58. }
  59. }
  60. return combo;
  61. }
  62. private String createColumns(String[] cols,String[] tables){
  63. String columns = "";
  64. for(String c : cols){
  65. if(tables == null){
  66. columns += c;
  67. } else {
  68. for(String t : tables){
  69. char s = t.charAt(0);
  70. LinkedList<String>temp = this.objbd.getColumns(t);
  71. for(String c1 : temp){
  72. if(c1.equals(c)){
  73. columns += s + "." + c;
  74. }
  75. }
  76. }
  77. }
  78. if(!cols[cols.length -1].equals(c)){
  79. columns += ",";
  80. } else {
  81. columns += " ";
  82. }
  83. }
  84. return columns;
  85. }

lo que me faltaría es ver bien las condiciones, los order y group by, además debería probar con los renombramientos de sql xq de momento esta sólo obteniendo la primer letra cosa que no es muy buena idea, ya que si hay otra tabla con la misma letra inicial, la consulta queda fastidiada, no sé que me sugieren?
  #3 (permalink)  
Antiguo 30/09/2016, 22:22
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Respuesta: Automatizar SQL con DatabaseMetaData

Mejoré un poco la cosa:

Código Java:
Ver original
  1. public String select(String[] cols, String[] tables, String[] style, String[] where, String[] conditions,String[] parts){
  2.         String Consulta = "select ";
  3.         if(cols == null){
  4.             Consulta += "* ";
  5.         } else {
  6.             Consulta += this.createColumns(cols, tables);
  7.         }
  8.         Consulta += "from " + this.getTable();        
  9.         if(tables != null){
  10.             String[] tab = this.prepareTables(tables);
  11.             Consulta += " " + this.getTable().charAt(0);            
  12.             Consulta += this.createJoin(style,tab);
  13.             if(where != null && conditions != null){
  14.                 Consulta += " " + this.createConditions(tab,where, conditions, parts);
  15.             }
  16.         }        
  17.         return Consulta;
  18.     }
  19.     private String createJoin(String[] style,String[] tables){
  20.         String join = " ";
  21.         if(tables != null && style != null){
  22.             for(int i = 0; i < tables.length; i++){
  23.                 if(!tables[i].equals(this.getTable())){
  24.                     String ps = "" + tables[i].charAt(0);
  25.                     String pp = "" + tables[i -1 ].charAt(0);
  26.                     if(ps.equals(pp)){
  27.                         ps += tables[i].charAt(1);
  28.                     }
  29.                     join += style[i-1] + " join " + tables[i] + " " + ps + " on" + this.createCombos(tables[i],tables[i -1]);
  30.                     if(!tables[tables.length -1].equals(tables[i])){
  31.                         join += " ";
  32.                     }
  33.                 }
  34.             }
  35.         }
  36.         return join;
  37.     }
  38.     private String createCombos(String emisor, String receptor){
  39.         String combo = " ";
  40.         String fk = "" + emisor.charAt(0);
  41.         String pk = "" + receptor.charAt(0);
  42.         if(fk.equals(pk)){
  43.             fk += receptor.charAt(1);
  44.         }
  45.         LinkedList<String> keys = this.objbd.getPrimaryKeys(emisor);
  46.         LinkedList<String> fays = this.objbd.getForeignKeys(receptor);
  47.         for(String f : fays){
  48.             for(String k : keys){
  49.                 if(k.equals(f)){
  50.                     combo += pk +"."+k +" = "+fk +"."+f;
  51.                     break;
  52.                 }                                    
  53.             }
  54.         }                        
  55.         return combo;
  56.     }
  57.     private String[] prepareTables(String[] tables){
  58.         String[] tab = new String[tables.length +1];
  59.         tab[0] = this.getTable();
  60.         for(int i = 0; i < tables.length; i++){
  61.             tab[i+1] = tables[i];
  62.         }
  63.         return tab;
  64.     }  
  65.     private String createColumns(String[] cols,String[] tables){
  66.         String columns = "";
  67.         for(String c : cols){
  68.             if(tables == null){
  69.                 columns += c;
  70.             } else {
  71.                 for(int i = 0; i < tables.length; i++){
  72.                     String ps = "" + tables[i].charAt(0);
  73.                     if(tables.length > 1 && i > 0){
  74.                         String pp = "" + tables[i-1].charAt(0);
  75.                          if(ps.equals(pp)){
  76.                             ps += tables[i].charAt(1);
  77.                         }
  78.                     }                    
  79.                     LinkedList<String>temp = this.objbd.getColumns(tables[i]);
  80.                     for(String c1 : temp){
  81.                         if(c1.equals(c)){
  82.                             columns += ps + "." + c;
  83.                         }
  84.                     }
  85.                 }                
  86.             }            
  87.             if(!cols[cols.length -1].equals(c)){
  88.                 columns += ",";
  89.             } else {
  90.                 columns += " ";
  91.             }
  92.         }
  93.         return columns;
  94.     }
  95.     private String createConditions(String[] tables, String[] where, String[] conditions, String[] parts){
  96.         String condition = "where ";
  97.         for(int i = 0 ; i < where.length; i++){
  98.             if(tables != null){
  99.                 for(int j = 0; j < tables.length; j++){
  100.                     String ps = "" + tables[j].charAt(0);
  101.                     if(tables.length > 1 && j > 0){
  102.                         String pp = "" + tables[j-1].charAt(0);
  103.                          if(ps.equals(pp)){
  104.                             ps += tables[j].charAt(1);
  105.                         }
  106.                     }
  107.                     LinkedList<String>temp = this.objbd.getColumns(tables[j]);
  108.                     for(String c1 : temp){
  109.                         if(c1.equals(where[i])){
  110.                             where[i] = ps + "." + where[i];
  111.                         }
  112.                     }
  113.                 }                
  114.             }
  115.         }
  116.         for(int i = 0 ; i < where.length; i++){
  117.             if(conditions[i].equals("between") || conditions[i].equals("not between")){
  118.                 condition += where[i] + " " + conditions[i] + " ? and ?";
  119.             }else if(conditions[i].equals("not null") || conditions[i].equals("null")){
  120.                 condition += where[i] + " " + conditions[i];
  121.             } else {
  122.                 condition += where[i] + " " + conditions[i] + " ?";            
  123.             }
  124.             if(!where[where.length -1].equals(where[i])){
  125.                 condition += " " + parts[i] + " ";
  126.             }
  127.         }        
  128.         return condition;
  129.     }

pero no me pasa que para el group by y order by es parecido a lo anterior, ¿quería preguntar cómo mejorar los renombramientos? ya que hice que para que no me duplique que en tabla que le haga el join me concatene su segunda letra pero eso no funcionará por mucho, además me quedé pensando cómo hacer si tengo subconsultas?? ahí no sé que hacer.

espero sus respuestas y saludos.
  #4 (permalink)  
Antiguo 04/10/2016, 21:46
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Respuesta: Automatizar SQL con DatabaseMetaData

Hola a todos, les comento que estuve tocando código y la verdad es q logré darle buenos avances a la automatización de los select pero tengo problemas en cómo armar el array del having y cómo armar la función del having necesito sugerencias, luego falta pulir el createColumns para que pueda aceptar renombramientos y funciones agregadas, por otro lado necesito ayuda para automatizar las subconsultas que ahí no tengo ni una idea de cómo llevarlo a cabo.

Pongo el pastebin: http://pastebin.com/6ghUPA3g.

Espero sus respuestas y Saludos
  #5 (permalink)  
Antiguo 05/10/2016, 09:56
(Desactivado)
 
Fecha de Ingreso: enero-2015
Mensajes: 393
Antigüedad: 9 años, 3 meses
Puntos: 52
Respuesta: Automatizar SQL con DatabaseMetaData

Borrá todo eso y usa un ORM.

http://hibernate.org/
  #6 (permalink)  
Antiguo 05/10/2016, 17:30
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Respuesta: Automatizar SQL con DatabaseMetaData

agleiva gracias por responder, verás más adelante pienso usar JPA y hibernate....

La cuestión es que quería hacer algo a mano automatizando SQL ya que la clase Model.java es una clase abstracta que otros modelos la heredarán pero quería primero automatizar todo SQL.

Con respecto a lo que pregunté, me puedes dar una idea de cómo llevar a cabo lo preguntado???

Espero sus respuestas y Saludos.
  #7 (permalink)  
Antiguo 05/10/2016, 18:40
(Desactivado)
 
Fecha de Ingreso: enero-2015
Mensajes: 393
Antigüedad: 9 años, 3 meses
Puntos: 52
Respuesta: Automatizar SQL con DatabaseMetaData

Cita:
Iniciado por detective_jd Ver Mensaje
agleiva gracias por responder, verás más adelante pienso usar JPA y hibernate....

La cuestión es que quería hacer algo a mano automatizando SQL ya que la clase Model.java es una clase abstracta que otros modelos la heredarán pero quería primero automatizar todo SQL.

Con respecto a lo que pregunté, me puedes dar una idea de cómo llevar a cabo lo preguntado???

Espero sus respuestas y Saludos.
No, no te puedo dar una idea. Gracias a Dios no he tenido que tocar una sola linea de java en mi vida, y no pienso empezar ahora. De hecho ni siquiera puedo leer detenidamente tu codigo sin que me duela la cabeza por lo horrendo, retrógrado, dinosaurio y vomitivo que es el lenguaje java, sobre todo si uno está acostumbrado a lenguajes modernos y bien diseñados.

Dicho esto, entré a este foro solamente para ayudarte enormemente con el comentario anterior y que te ahorres esfuerzo en implementar algo que no tiene ningun sentido.

Lamento pincharte el globo (*), pero todo tu codigo es un error enorme. Concatenar strings para generar SQL es una pésima idea y un gran agujero de seguridad a menos que sanitices todos tus inputs. Para el momento que llegues a eso, felicidades, reinventaste la rueda (una rueda bastante ineficiente) en lugar de usar Hibernate. Tu rueda es mas bien cuadrada, no se adapta a ningun modelo de auto y tiene fallas que pueden provocar accidentes fatales.

Te sugiero que desistas de esta pésima idea y utilices o bien un ORM, un Micro ORM, o al menos prepared statements como para que tu codigo no sea inmediatamente vulnerable a inyeccion SQL.

(*) - No, la verdad que no lo lamento.

Última edición por agleiva; 05/10/2016 a las 18:51
  #8 (permalink)  
Antiguo 05/10/2016, 19:55
Avatar de detective_jd  
Fecha de Ingreso: abril-2011
Ubicación: Salto
Mensajes: 437
Antigüedad: 13 años
Puntos: 6
Respuesta: Automatizar SQL con DatabaseMetaData

créeme quería ver cómo sería todo a mano pero bueno, haré un poco cómo antes, veré q sale. Saludos

Etiquetas: automatizar, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:24.