Lambdas en JDBC Data

En una entrada anterior, puse un ejemplo de como usar expresiones Lambas, como me parece que es un tema interesante, este de la programación funcional, voy a insistir en este tema.

Una cosa  muy común en Java es  tener que pesarle como argumento a una función externa, una objeto que implemente una función donde nosotros pondremos el código a ejecutar en nuestra  aplicación.

Un ejemplo practico es en el uso de  la clase JdbcOperations, que es utilizada por Spring para poder realizar operaciones JDBC, la cual tiene la función: 

T query(java.lang.String sql, java.lang.Object[] args, ResultSetExtractor rse)   throws DataAccessException

Lo que hay que entender es que como funciona realmente esta función **query **. Esta función necesita tres parametros:

  • sentencia SQL  a ejecutar, 
  • Argumentos de la sentencia SQL
  • Clase ResultSetExtractor donde nuestro programa hará algo con los resultados obtenidos.

Así, voy a suponer que queremos realizar una consulta sobre una tabla, buscando el nombre de un usuario, a través de su identificador. La tabla **usuarios, **tendría solo estos dos campos:

  • identificador, que seria un varchar de 15 caracteres (un texto para los que no conocen SQL)
  • nombre, que seria otro de varchar  de 50 caracteres (otro texto, vamos).

Es decir queremos buscar, el nombre de un usuario, sabiendo su identificador. La sentencia SQL para realizar esta búsqueda seria

La interrogación final hace referencia al parámetro que pasaremos, es decir el identificador del usuario.

Por lo tanto, en nuestro programa pondremos una sentencia, como la siguiente:

jdbc.query("select nombre from usuarios where identificador = ?", new[] { "usuario1" },  OBJETO_RESULTSETEXTRACTOR)

El parámetro **new Object[] { “usuario1” } **simplemente crea un array de Objetos con los diferentes parámetros que necesitara nuestra sentencia SQL. En este caso solo necesita un parámetro que es el identificador del usuario. Vamos a buscar el usuario que tiene como identificador usuario1.

Y nos queda por definir el objeto del tipo ResultSetExtractor, donde interactuaremos con los resultados de nuestra sentencia SQL.

Ese tipo de objeto esta definido en el interface ResultSetExtractor el cual solo tiene una función, que detallo a continuación:

T mapRow(java.sql.ResultSet rs,  int rowNum)            throws java.sql.SQLException

Antes de Java 1.8, deberíamos crear una clase que implemente el interfaz ResultSetExtractor. Esa clase seria algo así como:

class miResultSetExtractor implements ResultSetExtractor
{
   @Override
   public T mapRow(java.sql.ResultSet rs, int rowNum) throws java.sql.SQLException { 
          System.out.println("El nombre del Usuario es: "+rs.getString("nombre")); // <strong>CODIGO A EJECUTAR</strong>
    }
}

Y ejecutaríamos la llamada a la función query de esta manera:

También podríamos crear una clase abstracta, a la hora de llamar a la función **query, ** con una sentencia como esta:

El caso es que tenemos que poner un montón de código auxiliar  cuando nosotros solo quisiéramos poner nuestro System.out.println.

Y ahora es cuando viene al rescate las expresiones Lamba.

La expresión lambda se compone de dos partes. Los parámetros a mandar y el código a ejecutar.

Así, nosotros mandaremos dos parametros: **param1 **y param2. (le podriamos haber puesto los nombres que quisieramos)

Como se ve, no hay que especificar de que tipo son esos parámetros, Java, se encargara de eso. Te estarás preguntado, pero, ¿ como funciona esto ?.

Bueno, en primer lugar, Java, cuando compile nuestro código buscara que que objeto debe crear, dependiendo del parámetro esperado por la función **jdbc.query(). **Vera que espera un objeto que implemente el interface **ResultSetExtractor **y comprobara que ese interface solo tiene una función, por lo cual, sabrá fácilmente que parámetros se tipo de objetos se deben pasar como objetos.

Es por eso que solo se pueden aplicar este tipo de expresiones lambda cuando el interface implemente una única función.

Una vez que Java, sabe que objetos debe pasar, el sustituirá nuestras variables **param1 **y **param2 **y las usara en el cuerpo de nuestra expresión Lambda. Por ello ahora nuestro código: **System.out.println(“El nombre del Usuario es: “+param1.getString(“nombre”))  **cogera la variable **param1 **y la usara sabiendo que es un objeto tipo ResultSet. Observar que aunque la variable param2, no la usamos en nuestro código, debemos definirla igualmente.

Espero haberme explicado bien, y no dudéis en preguntar o seguirme en mi cuenta de twitter.

¡ Hasta la próxima !!