Доступ до баз даних з Java, Java, Програмування, статті

Developers.com.ua

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

Отже розглянемо кроки які необхідно зробити для того щоб обробити SQL запит:

Тепер розглянемо ці кроки більш детально на приклад роботи з MySql.

Реєстрація JDBC-драйвера

Для реєстрації драйвера у Вас повинні бути:

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 sql_connection
{ 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.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*