MySQL & mSQL

Динамический доступ к базе данных


До сих пор мы имели дело с приложениями, в которых во время компиляции точно известно, что нужно будет делать. Если бы это был единственный тип поддержки, обеспечиваемый JDBC, никто не смог бы написать для Mysql и msql интерактивные инструменты командной строки, способные во время исполнения принимать команды SQL и выполнять их. Класс JDBC Statement поддерживает метод execute() для выполнения SQL-команд, которые могут быть запросами или обновлениями. Кроме того, экземпляры ResultSet обеспечивают предоставление о себе информации времени исполнения через интерфейс с именем ResultSetMetaData, доступ к которому осуществляется через вызов метода getMetaData() для ResultSet.

Метаданные

Термин метаданные звучит официозно, но на самом деле это не более чем дополнительные данные о некотором объекте, которые, если бы действительно хранились в объекте, просто зря тратили бы ресурсы. Например, для простых приложений не нужны имена колонок, связанных с результирующим набором ResultSet: программисту они, скорее всего, известны во время написания программы. Поэтому помеще

ние этих дополнительных данных в класс ResultSet не рассматривается разработчиками JDBC как нечто существенное для функциональности ResultSet. Однако в некоторых случаях программирования баз данных i такие вещи, как имена колонок, очень важны, особенно при осуществлении динамического доступа к базам данных. Доступ к этим дополнительным данным - метаданным - разработчики JDBC обеспечили через интерфейс ResultSetMetaData. Этот класс позволяет узнать:

  • Число колонок в результирующем наборе.

  • Является ли NULL допустимым значением в колонке.

  • Метку, используемую для заголовка колонки.

  • Имя заданной колонки.

  • Таблицу, служащую источником данных для данной колонки.

  • Тип данных колонки.

    Другим примером класса, поставляемым вместе с драйвером mSQL-JDBC, является приложение Exec. Оно принимает любую команду SQL, задаваемую в командной строке, и выполняет ее. В примере 14-6 приводится соответствующий исходный код.


    Пример 14-6. Исходный код приложения Exec для выполнения динамического SQL



    import java.sql.*;

    public class Exec {

    public static void main(String args[]) {

    Connection con = null; String sql = "";

    for(int i=0; i<args.length; i++) {

    sql = sql + args[i];

    if( i < args.length - 1 ) {

    sql = sql + " ";

    }

    }

    System, out. рrintln("Выполнение: " + sql);

    try {

    Class.forName("com.imaginary. sql.msql.MsqlDriver").newlnstance();

    String url = "jdbc:msql://athens.imaginary.com:1114/db_test";

    con = DriverManager.getConnection(url, "borg", "");

    Statement s = con.createStatement();

    if( s.execute(sql) ) {

    ResultSet r = s.getResultSet();

    ResultSetMetaData meta = r.getMetaData();

    int cols = meta.getColumnCount();

    int rownum = 0;

    while( r.next() ) { rownum++;

    System, out. println("Crpокa: " + rownum);

    for(int i=0; i<cols; i++) {

    System.out.print(meta.getColumnLabel(i+1) + ": ' + r.getObject(i+1) + ", ");

    }

    System.out.println("");

    }

    }

    else

    {

    System.out.println(s.getUpdateCount() + " строк обработано.");

    }

    s.close();

    con.close();

    }

    catch( Exception,e ) { e. printStackTrace();

    }

    finally

    {

    if( con != null )

    {

    try { con.close();

    }

    catch( SQLException e ) { }

    }

    }

    }

    }

    Для каждого результирующего набора обеспечивается получение экземпляра ResultSetMetaData с помощью метода getMetaData(). При динамическом доступе к базе данных необходимо узнать, сколько колонок в результирующем наборе, чтобы с уверенностью извлечь все колонки и их имена для вывода пользователю. Метаданные нашего результирующего набора обеспечивают получение всех этих данных с помощью методов getColumnCount() и getColumnLabel().

    Обработка динамического SQL

    В примере 14-6 введено понятие динамического вызова SQL. Поскольку мы не знаем, будет это запрос на получение данных или обновление, нужно передать вызов SQL через метод execute (). Этот метод возвращает true, если команда возвратила результирующий набор, и false в противном случае. В нашем примере, если возвращается true, то приложение получает возвращаемый ResultSet через вызов метода getResultSet(). Затем приложение может перейти к обычной обработке результирующего набора. Если, напротив, команда произвела какую-либо модификацию базы данных, можно вызвать метод getUpdateCu-unt() для подсчета числа строк, модифицированных командой.




    Содержание раздела