Saltar la navegación

3.7.3.- Ejecución de consultas XQuery

La API XQJ facilita los dos mecanismos a través de las interfaces:

  • XQExpression, Para la ejecución inmediata de sentencias.
  • XQPreparedExpression, Para la ejecución de sentencias parametrizadas.

Para ejecutar una sentencia XQExpression, crearemos un objeto XQExpression a partir del método XQConnection.createExpression(). Disponemos de dos sobrecargas de este método:

XQExpression createExpression throws XQException ;
XQExpression createExpression ( XQStaticContext properties )throws XQException ;

En ambas sobrecargas obtiene un objeto XQExpression que podremos utilizar para ejecutar sentencias XQuery / Update de manera inmediata. La segunda sobrecarga permite indicar las propiedades del contexto estático que se tendrán en cuenta al evaluar la expresión, mientras que la primera sobrecarga toma como contexto estático el asociado a la conexión.

La interfaz XQStaticContext provee un conjunto de métodos get y set para recuperar y establecer las propiedades de un contexto estático. La interfaz XQConnection facilita los métodos getStaticContext() y setStaticContext() para recuperar y establecer el contexto estático de la conexión.

Una vez tengamos el objeto XQExpression, podremos a través de él ejecutar consultas y otras órdenes de manera inmediata. Recordemos que en XQuery hay que distinguir, como en SQL, las sentencias "consulta" que pueden devolver un conjunto de resultados que habrá que procesar, de las sentencias "no consulta" que permiten ejecutar una orden (inserción, eliminación o actualización e incluso órdenes específicas del'SGBD), de la que se nos informa, como mucho, del éxito o fracaso de su ejecución. De ahí que la interfaz XQExpression distingue los métodos executeQuery para las "consultas" de los métodos executeCommand para las "no consultas":

void executeCommand ( java.lang.String cmd ) throws XQException ;
void executeCommand ( java.io.Reader cmd )  throws XQException ;
XQResultSequence executeQuery ( java.Lang.String query ) throws XQException ;
XQResultSequence executeQuery ( java.Io.Reader query ) throws XQException ;
XQResultSequence executeQuery ( java.Io.InputStream query ) throws XQException ;

Además de los métodos anteriores, disponemos del método close() para cerrar la expresión, liberando todos los recursos asociados cuando ya no sea necesaria. La ejecución del método close() sobre la conexión cierra todas las expresiones definidas sobre ella. También disponemos del método isClosed() para poder averiguar si una expresión está abierta o cerrada:

void close throws XQException ;
boolean isClosed;

Fijémonos que el método executeQuery() devuelve, si todo va bien, un objeto XQResultSequence, interfaz que deriva de la interfaz XQSequence, la cual nos facilita un conjunto de métodos para evaluar la secuencia de resultados obtenidos con el método executeQuery():

La interfaz XQResultSequence representa una secuencia de elementos siguiendo la definición de XDM (XQuery 1.0 and XPath 2.0 Data Model, de W3C ). Un vistazo a la documentación de esta interfaz nos muestra que disponemos de métodos para:

  • Procesar sus elementos: next(), previous(), getItem(), getPosition(), count(), first(), last(), isFirst(), isLast(), isBeforeFirst(), isAfeterLast() y un conjunto de métodos get para obtener el contenido de un elemento en el formato adecuado ( getBoolean(), getByte(), getDouble()...).
  • Obtener una versión seriada de la secuencia como un objeto String (método getSequenceAsString()).
  • Obtener una versión seriada de la secuencia (método getSequenceAsStream()) como un objeto XMLStreamReader (interfaz del API Stax de Java, que permite la iteración, hacia delante, de un documento XML en modo lectura, utilizando los métodos next() y hasNext()).

Según sea la gestión que tengamos que efectuar, utilizaremos unos u otros métodos. Así, ante un programa de sentencia abierta (en el que el usuario pueda introducir la sentencia a ejecutar), sólo podremos pensar en mostrar el resultado a través de la versión seriada hacia String o vía objeto Transformer a partir de la seriación hacia XMLStreamReader. Y ante un programa de sentencia cerrada (sentencia perfectamente conocida en escribir el programa), dado que se conoce la forma de la respuesta, podemos pensar en efectuar un tratamiento específico.