Блог программатора

Our partner
Главная | Последние правки | Поиcк | Все страницы | Редактор | Админ | Печать

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

Java (не Visual J++) предоставляет доступ к даными при помощи интерфейса JDBC. Данный интерфейс по своей сути напоминает ODBC, более того, в Win32 есть шлюз JDBC-ODBC (хочу предупредить сразу - корректно он работает в семействе win9x, в nt он работает, но ... около минуты, потом GPF :-).

Итак рассмотрим шаги которые необходимо предпринять для того чтобы обработать SQL запрос:
  • Зарегистрировать JDBC-драйвер (на этапе инициализации приложения)
  • Сформировать JDBC-URL-строку для получения соединения с базой.
  • Получить Connection
  • Сформировать SQL запрос
  • Выполнение и обработка SQL-запроса
  • Закрыть полученные соединения (ResultSet, Statament, Connection)

Теперь рассмотрим эти шаги более детально на пример работы с MySql.

Регистрация JDBC-драйвера

Для регистрации драйвера у Вас должны быть:
JAR-файл с драйвером должен быть подключен в CLASSPATH'е
Вы должны знать название класса-драйвера который вы собираетесь подключать (эту информацию ищите на сайте производителя драйверов. К примеру, покопайтесь в файле readme.txt ;-). Если совсем "в морг" - распакуйте .jar с драйверами и поройтесь в нем - где-то должен быть класс Driver - а потом по вложенности каталогов восстановите название пакета где он лежит).

JAR Вы подключили, теперь надо зарегистрировать драйвер:
String driver="org.gjt.mm.mysql.Driver";

try {
      Class.forName(driver).newInstance();
      DriverManager.registerDriver(
         (Driver)Class.forName(driver).newInstance());

    } catch(Exception e) {
      System.out.println("Exception while register driver: "+e);
    }

Формирование JDBC-URL-строки

В наиболее общем случае эта строка имеет вид:

jdbc:id_базы:параметры

В (общем) случае MySql она имеет вид:

jdbc:mysql://хост/база?user=пользователь

Например:

jdbc:mysql://127.0.0.1/GENERAL?user=root

ВНИМАНИЕ! Необходимое отступление по поводу "особенностей" работы лрайверов mysql. Для подключения необходима передача login/password в JDBC драйвер, однако JDBC-драйвера MySql которые мне встречались, вопринимали только login прописанный в строке JDBC-URL и никакими другими способами заставить воспринять драйвер необходимые параметры не получилось.

Получение Connection

Для получения Connection Вы должны вызвать DriverManager.getConnection() и передать во внутрь login/password/jdbc-url:

String url="jdbc:mysql://127.0.0.1/GENERAL?user=root";
String user="";
String password="";
Connection c=null;

try {
      c=DriverManager.getConnection(url,user,password);

    } catch(SQLException e) {
      System.out.println("Exception getting connection: "+e);
    }

Формирование SQL запроса

На данном этапе все просто - Вам необходимо сформировать обыкновенную SQL команду, например:

String str="SELECT * FROM MYTABLE";
String str="INSERT INTO MYTABLE (NAME,CNT) VALUES ('"
          +name+"',"+cnt+"')";

Выполнение и обработка SQL-запроса

Для выполнения запроса мы должны у Connection'а получить Statement и вызвать один из его методов в зависимости от типа запроса:

public int executeUpdate(String sql) throws SQLException

Применяется для SQL команд INSERT, UPDATE или DELETE. Возвращает кол-во строк над которыми выполнилась операция.

public ResultSet executeQuery(String sql) throws SQLException

Применяется для SQL команды SELECT. Возвращает ResultSet из которого можно вытянуть информация о шапке таблицы (ResultSetMetaData) и сами значения. Как это делается будет показанно ниже в примере.
public boolean execute(String sql) throws SQLException

Данный метод возвращает true/false - выполнился/не выполнился запрос. Применяется в тех случаях когда SQL запрос возвращает несколько ResultSet'ов. Для их получения используйте getMoreResults().

Пример:

String str="SELECT * FROM RASHOD WHERE USER_ID="+user;
System.out.println(str);

Statement statement = c.createStatement();  // создаем оператор

ResultSet rs = statement.executeQuery(str); // выполняем запрос

ResultSetMetaData md = rs.getMetaData();

int cnt= md.getColumnCount(); // получаем кол-во колонок (1..cnt)

int row=0;

while(rs.next()) {
 row++;
 System.out.println("Row "+row);     // вывод номера строки в базе
 for(int i = 1; i <= cnt; i++) {
   String name=md.getColumnName(i);  // получем имя колонки
   String val=rs.getString(i);       // получаем значение
   System.out.println(name+"="+val); // выводим имя и значение поля
 }
}

ВНИМАНИЕ! Применяйте executeUpdate/executeQuery/execute тогда когда они уместны - не вызывайте executeQuery для INSERT'а !!!

Закрытие полученных соединений (ResultSet, Statament, Connection)

Тут все просто - у каждого из них есть метод

close();

Почему так важно закрывать соединения ? Те кто работал с Oracle улыбнутся подобному вопросу - mysql позволяет безболезненно плодить незакрытые соединения (он их сам прибивает со временем), Oracle наоборот - число Connection у него ограниченно (если не ошибаюсь это ограничение на кол-во клиентов), поэтому исчерпав кол-во Connection'ов Вы можете "повесить" свое приложение. Поэтому не стоит приучаться к худшему и затруднять возможную миграцию приложения с MySql на другой SQL-сервер.

Заключение

В заключении хочу рассказать как все это я использую в своих сервлетах. У меня есть класс sql_connection (экземпляр которого создается в init'е) и у которого я получаю Connection'ы:
import java.sql.*;

/**
  * Class for simpling connection to SQL-server's
  * @author General
  */
public class SqlConnection {

 private String user;
 private String password;
 private String url;
 private Connection c;
 /**
   * Register specified driver and store user/password/url
   * in internal variables (it need for getConnectio()).
   *
   * @author General
   */
 public sql_connection(String user, String password
                      ,String url,  String driver) {
   this.user=user;
   this.password=password;
   this.url=url;
   try{ Class.forName(driver).newInstance();
        DriverManager.registerDriver(
             (Driver)Class.forName(driver).newInstance());
        c=DriverManager.getConnection(url,user,password);
        c.close();
   } catch(Exception e)
     { System.out.println("Exception while register driver: "+e);}
 }

 /**
   * Return Connectio to SQL-server
   * @return Connection to SQL-server
   * @author General
   */
 final public Connection getConnection() {
   try{ c=DriverManager.getConnection(url,user,password);
      } catch(SQLException e) {
         System.out.println("Exception getting connection: "+e);
      }
   return(c);
 }

 final protected void finalize() {
   try{ c.close();
      } catch(SQLException e)
   { System.out.println("Exception while close connection: "+e);}
 }
}

Он не завист от имени jdbc драйверов (url, login, password и имя класса вычитываются из ini-файла. Дальше я его применяю следующим образом:

public void view(HttpServletRequest req, HttpServletResponse res) {
try{ Statement statement = con.getConnection().createStatement();
      String str="SELECT * FROM RASHOD WHERE ID="+id;
      System.out.println(str);
      ResultSet rs = statement.executeQuery(str);
      ResultSetMetaData md = rs.getMetaData();
      int cnt= md.getColumnCount();

      while(rs.next())
      { for(int i = 1; i <= cnt; i++)
        { String name=md.getColumnName(i);
          String val=rs.getString(i);
          ...
        }
      }

      rs.close();
      statement.close();
      res.setContentType(conf.CONTENT_TYPE);
      PrintWriter out = res.getWriter();
      ...

    } catch(Exception e) {System.out.println(""+e);}
}

И еще пару слов о необходимости Connection pool. Это такая вещь которая кеширует соединения с базами - например в сервлетах слишком долго каждый раз устанавливать соединения, или например в Oracle ограничение на кол-во одновременно открытых соединений. Поэтому Вам следует подумать над ее использванием. К примеру в вебсервере jakarta tomcat реализован такой pool.

Коментарии

Отслеживать новые комментарии

Дворак Fri, 25 Jun 2010 06:07:44 -0400
Хорошо

Прокоментируйте эту статью!

Автор:
Введите текст с картинки:
Коментарий


Главная
Софт
Хард
Политеги

SimpleWiki 

Почта 



Мой номер ICQ
 456824974 

Архив:

01.2010
02.2010
03.2010
04.2010
05.2010
06.2010
07.2010


Радио «Анонимус» 
Реклама java
Wed, 30 Jun 2010 13:56:00 -0400
Копипаста: История программных революций от Microsoft
Mon, 14 Jun 2010 04:19:00 -0400
Как восстановить grub2 и mbr
Thu, 10 Jun 2010 17:33:00 -0400
Установить/сменить пароль администратора на свежем postgresql'е
Sun, 23 May 2010 18:18:00 -0400
Президент Виктор Янукович получил по морде венком
Tue, 18 May 2010 09:31:00 -0400
Наконец-то ! Контакт с инопланетянами !
Thu, 18 Mar 2010 08:01:00 -0400
Панкота: группа Флiт
Sat, 13 Mar 2010 08:11:00 -0500

Blog

Add bookmark:
Bookmark and Share



© Komenda Viacheslav
Запрещается перепечатка материалов, без письменного разрешения автора.

Последнее обновление: Fri, 25 Jun 2010 06:07:44 -0400