Блог программатора |
||||||||
| Главная | Последние правки | Поиcк | Все страницы | Редактор | Админ | Печать | ||||||||
Доступ к базам даных из JavaJava (не Visual J++) предоставляет доступ к даными при помощи интерфейса JDBC. Данный интерфейс по своей сути напоминает ODBC, более того, в Win32 есть шлюз JDBC-ODBC (хочу предупредить сразу - корректно он работает в семействе win9x, в nt он работает, но ... около минуты, потом GPF :-).Итак рассмотрим шаги которые необходимо предпринять для того чтобы обработать SQL запрос:
Теперь рассмотрим эти шаги более детально на пример работы с 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 Радио «Анонимус» ![]()
Blog ![]() Add bookmark: |
|||||||
|
© Komenda Viacheslav |
||||||||