Consulta en Base de Datos

Saludos a todos los de Javamexico!

Hoy traigo una duda con una consulta a bd..

Esta seria la forma correcta de consultar para una aplicación web??

 public ArrayList Select(String tabla, String columns, String Where) {
        String sql = "SELECT " + columns + " FROM " + tabla + "WHERE " + Where;
        ArrayList Datos = new ArrayList();
        try {
            try (Connection con = DriverManager.getConnection(myConnection);
                    PreparedStatement ps = con.prepareStatement(sql);) {

                try (ResultSet rs = ps.executeQuery();) {
                    while (rs.next()) {
                        Datos.add(rs.getString("columnaSolicitada"));
                         .........................

                    }
                }
            }
        } catch (SQLException e) {
            //mostrar error al usuario y guardar en log
        } finally {

            //cerra todo
           
        }
        return Datos;
    }

Alguien me aconseja?
-Ques esta mal?
-que esta bien?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

No, esa es la peor

Esa es la peor forma de consultar para cualquier tipo de aplicación. Utiliza PreparedStatements con parámetros, no concatenes SQL especialmente la parte de parámetros de búsqueda, porque vuelves a tu aplicación vulnerable a ataques de inyección de SQL.

Ejemplo D:

me darías un ejemplo?

Re: ejemplo

 

Este sitio me ha ayudado mucho: http://www.google.com. Por si acaso: Cómo hacer búsquedas en Google.


P.D.: Perdón por el exabrupto. No quería perder la oportunidad de decir algo así. ¡Je!

        String sql = "SELECT

Usa prepared statements: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

    String sql = "SELECT a.a, a.b, a.c FROM a WHERE a.a = ? and a.b = ? and a.c = ?;

Donde a.a, a.b, a.c son los campos de tu tabla.

Si no lo haces así y el valor de where viene de algún valor que el usuario puede capturar te pueden hacer inyección de SQL.

    List a = select (columnas, tabla, "1 = 1; drop table users; -- ");
Imagen de pechsclk

para aplicacion cliente servidor

entonces en una aplicacion ya sea web o de escritorio (cliente servidor) se debe ocupar procediminetos almacenados, solo mandar los parametros deseados...
(clave, ide o fecha.)

Imagen de ezamudio

eh

Nadie aquí ha mencionado stored procedures, solamente queries parametrizados.

Re: para aplicacion cliente servidor

¿Es una pregunta? … O, ¿es una afirmación?


P.D. ¿Cómo va todo? Espero que por fin ya te hayas liberado de la empresa esa.

@pechsck No, los nombres

No, los nombres pueden parecerse, pero unos son "prepared statements" ( "sentencias preparadas" ) y los otros son "stored procedures" ( procedimientos almacenados).

Con las sentencias preparadas ( prepared statements ) dejas un signo de interrogación para tus parametros y el driver lo sustituye con el valor de una forma segura.

.... where a = ? and b = ? and c = ?
...etc.

Así, si por ejemplo si tienes una fecha, en vez de tener que lidiar con el formato correcto en un string concatenado como este:

// NO:  concatenar strings
String query = "SELECT a FROM bla WHERE date > '"+dateFormat.format(someDate)+"' and id  = "+someId;
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(query);

Puedes dejar que el driver lo escriba en el formato correcto por tí. Más aún y todavía más improtante te evita que se inyecte una sentencia SQL peligrosa.

Usar prepared statements no solo es más fácil y seguro sino que además es más rápido pues el motor de base de datos puede guardar la sentencia y ejecutarla más rápidamente en vez de tener que parsearla de nuevo.

Este sería el equivalente:

// SI: usar prepared statements
String query = "SELECT a FROM bla WHERE date > ? and id  = ?";
PreparedStatement s = conn.prepareStatement(query);
s.setDate(1, someDate);
s.setInt(2, someId);
ResultSet rs = s.executeQuery();

Hola!

Holaa!! Gracias por sus respuestas.! A ver les contare un poco... Soy realmente "nuevo"en el mundo java... he estado investigando, leyendo doc y todo lo relacionado pero hay muchas cosas que no entiendo aun.
De igual forma agradezco sus respuestas y aunque algunas no las entienda busco información al instante para comprender mejor.

Con respecto al tema: Quiero un único método para hacer las consultas, pero el que tengo es el peor =(
Así que haré otra pregunta: Tomando el ejemplo que me señala OscarRyz;

En mi método al enviar el query no se cuales serán los parámetros exactamente, osea no se el tipo de variable para hacer el s.settipovariable.

PD: (Jpaul ) Se como hacer búsquedas en google... Pero igual gracias :3

Re: hola

Se como hacer búsquedas en google… Pero igual gracias :3

No fue nada. Es que no estaba seguro si sabías o no. LOL

@Artixdavid Lee el la

@Artixdavid Lee el la documentación para que veas que posibilidades tienes:

http://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html

Por ejemplo el prepared statement tiene un método setObject al que le puedes pasar cualquier tipo, pero tienes que ver si es lo que necesitas.

Otra opción es revisar el tipo de dato del parámetro y poner un swtich

public void execute( Object ... args )  {
     for ( Object o : args ) {
          if ( o.getClass() == String.class ) {
             pstmt.setString( i, o );
          } else if ( o.getClass() == Integer.class ) {
             pstmt.setInt( i, o );
           etc. etc.
     }
}

Y la otra opción ( la mejor ) es que utilices alguna biblioteca o producto que te ayuden con esto, por ejemplo Hibernate es el estándar en la industria, aunque la curva de aprendizaje no es precisamente plana, pero definitivamente es mucho mejor que crear tu propio framework de base de datos

Imagen de ezamudio

ibatis

iBatis es otra opción para que no andes reinventando el hilo negro