Под впечатлением от этой
статьи я решил написать свой небольшой мануал по работе с СУБД MySQL,
используя библиотеку mysql++. Данная библиотека представляет собой
кроссплатформенное решение, написанное на С++, предоставляет богатый
набор классов и позволяет эффективные приложения. Т.к. моей основной
операционной системой является Linux – я буду рассматривать процесс
создания приложения под Unix платформу. Под платформу Windows все будет
практически точно так же, за исключением собственно подключения
библиотеки, ее заголовочных файлов к IDE (MS Visual studio, Dev-c++).
Для создания приложения в среде Unix наличие IDE, как и собственно графической оболочки не необходимо, процесс написания и компиляции может проходить в голой консоли.
Для начала необходимо скачать саму библиотеку, это можно сделать по следующим ссылкам:
Исходный код, для самостоятельной компиляции+документация
Бинарные RPM сборки (следует попробовать разные версии, т.к. некоторые могут не установиться):
RPM ver1
RPM ver2
RPM ver3
Версия для MS Visual C++
Я не буду описывать установку библиотеки для каждой платформы, т.к. это выходит за рамки данной статьи.
Теперь пришло время познакомится с библиотекой, рассмотреть ее классы и создать простое приложение, которое будет подключаться к базе данных и запрашивать данные из таблицы, добавлять новые, модифицировать существующие записи.
Для того, что бы воспользоваться возможностями библиотеки, следует подключить заголовочный файл mysql++.h и пространство имен mysqlpp.
Далее воспользуемся классом Connection, который обеспечивает
подключение и аунтефикацю на интересующей нас базе данных. Кратко
рассмотрим этот класс и наиболее интересные его методы.
Класс имеет два конструктора:
Connection(bool te=true) – создание экземпляра класса, без подключения к бд
Connection (const char *db, const char *server=0, const char *user=0, const char *password=0, unsigned int port=0) - создание экземпляра класса с подключением к указанной бд по указанным параметрам. Думаю, что названия параметров говорят сами за себя и не требуют пояснений
client_version() – возвращает строку типа string, содержащую версию библиотеки.
connect (const char *db=0, const char *server=0, const char *user=0, const char *password=0, unsigned int port=0) - то же самое, что и описанный выше конструктор, применяется в случае использования конструктора Connection(true).
connected() – возвращает true, в случае если выполнено подключение к базе и false, если подключение не выполнено.
disconnect() – выполнить отключение от базы данных.
error() – возвращает последнюю ошибку.
query (const char *qstr=0) – возвращает объект типа query, позволяющий выполнить запрос (об этом ниже).
count_rows (const std::string &table) – возвращает результат типа unsigned long, количество строк в указанной таблице table.
Класс Connection имеет еще ряд методов, но они нам пока не интересны. Теперь рассмотрим класс query. В нем нас интересуют следующие методы:
store() – возвращает результат запроса, типа StoreQueryResult.
execute() – выполнить запрос, не требующий возвращения данных, метод возвращает результат SimpleResult.
Класс StoreQueryResult – именно он позволяет обратиться к запрошенной таблице, представленной как двумерный массив, получить количество вовращенных строк.
num_rows() – возвращает количество строк
empty() – возвращает true, в случае, если запрос ничего не вернул и false, если запрос вернул данные.
Класс SimpleResult, у этого класса нас может интересовать всего один единственный метод
rows() – возвращает количество строк, подвергшися изменению, во время вызова execute()
Данное приложения представляет собой очень простой и детально расписанный пример, который поможет разобраться новичкам.
Как видно, программа очень проста и легка для понимания. В начале мы
пробуем подключится к базе данных database, которая находится на сервере
dataserver, как пользователь datauser с паролем password. В случае
ошибки – перехватываем исключение типа ConnectionFailed, которое имеет
метод what(), возвращающий текстовое описание проблемы
(так же у класса ConnectionFailed есть метод errnum (), возвращающий номер ошибки). После успешного подключения, проверяем еще раз, подключены ли мы, т.к. в случае нестабильной связи или по иным причинам – соединение может успеть отвалиться. В случае успешной проверки связи, инициализируем строку запроса querystring, наш запрос имеет вид: “SELECT * FROM Datatable”, что означает вернуть все абсолютно все записи из некой таблицы Datatable. После этого вызываем метод query, класса соединения, и у возвращенного объекта, вызываем метод store(), возвращенный результат запроса сохраняем в queryres. Далее проверяем, не пуст ли результат. Если нет – построчно выводим записи на экран.
В классе StoreQueryResult, экземпляром которого является queryres, строки хранятся в виде двумерного ассоциативного массива, это дает возможность обратиться к соотвествующему столбцу по его имени. Как в данном случае: queryres[rc]["colname_sec"] – обращаемся к rc-ой строке и столбцу под названием colname_one.
После окончания работы с бд следует обязательно закрыт соединение, что мы и делаем вызывая метод disconnect().
В предидущем примере мы научились получать интересующие нас записи, теперь мы научимся добавлять и удалять их.
Я не буду повторять код всей программы, а просто лишь опишу способы, с помощью которых достигается нужный нам результат. В примере ниже показано, как можно добавить строку в нашу таблицу Datatable.
SQL запрос в данном случае выглядит как INSERT INTO Datatable(colname_one, colname_sec) VALUES(‘data1′, ‘data2′).
А для выполнения этого запроса будем использовать метод execute().
Как видно, все очень и очень просто, инициализируем строку запроса, и
вызываем метод execute(), который возвращает нам объект класса
SimpleResult, и используя метод rows() последнего мы получаем сколько
строк изменено, т.е. в данном случае добавлено. Полученный результат
сразу же шлем в поток вывода. Я написал все без введения дополнительных,
промежуточных, переменных, для компактности и экономичности.
Все прочие операции, модификация, удаление строк выполняются аналогично, отличия будут только в самом тексте SQL запроса:
Модификация:
Удаление:
В данном примере указана кодировка UTF8, как основная на современных
Linux системах. Вам следует задать кодировку вашей системы, для
корретной обработки киррилицы.
Для компиляции программы следуюет выполнить команду:
В этой команде файл с исходным кодом main.cpp компилируется, подключая необходимые библиотеки.
Для создания приложения в среде Unix наличие IDE, как и собственно графической оболочки не необходимо, процесс написания и компиляции может проходить в голой консоли.
Для начала необходимо скачать саму библиотеку, это можно сделать по следующим ссылкам:
Исходный код, для самостоятельной компиляции+документация
Бинарные RPM сборки (следует попробовать разные версии, т.к. некоторые могут не установиться):
RPM ver1
RPM ver2
RPM ver3
Версия для MS Visual C++
Я не буду описывать установку библиотеки для каждой платформы, т.к. это выходит за рамки данной статьи.
Теперь пришло время познакомится с библиотекой, рассмотреть ее классы и создать простое приложение, которое будет подключаться к базе данных и запрашивать данные из таблицы, добавлять новые, модифицировать существующие записи.
Для того, что бы воспользоваться возможностями библиотеки, следует подключить заголовочный файл mysql++.h и пространство имен mysqlpp.
Код:
#include <mysql++.h>
using namespace mysqlpp;
Класс имеет два конструктора:
Connection(bool te=true) – создание экземпляра класса, без подключения к бд
Connection (const char *db, const char *server=0, const char *user=0, const char *password=0, unsigned int port=0) - создание экземпляра класса с подключением к указанной бд по указанным параметрам. Думаю, что названия параметров говорят сами за себя и не требуют пояснений
client_version() – возвращает строку типа string, содержащую версию библиотеки.
connect (const char *db=0, const char *server=0, const char *user=0, const char *password=0, unsigned int port=0) - то же самое, что и описанный выше конструктор, применяется в случае использования конструктора Connection(true).
connected() – возвращает true, в случае если выполнено подключение к базе и false, если подключение не выполнено.
disconnect() – выполнить отключение от базы данных.
error() – возвращает последнюю ошибку.
query (const char *qstr=0) – возвращает объект типа query, позволяющий выполнить запрос (об этом ниже).
count_rows (const std::string &table) – возвращает результат типа unsigned long, количество строк в указанной таблице table.
Класс Connection имеет еще ряд методов, но они нам пока не интересны. Теперь рассмотрим класс query. В нем нас интересуют следующие методы:
store() – возвращает результат запроса, типа StoreQueryResult.
execute() – выполнить запрос, не требующий возвращения данных, метод возвращает результат SimpleResult.
Класс StoreQueryResult – именно он позволяет обратиться к запрошенной таблице, представленной как двумерный массив, получить количество вовращенных строк.
num_rows() – возвращает количество строк
empty() – возвращает true, в случае, если запрос ничего не вернул и false, если запрос вернул данные.
Класс SimpleResult, у этого класса нас может интересовать всего один единственный метод
rows() – возвращает количество строк, подвергшися изменению, во время вызова execute()
Данное приложения представляет собой очень простой и детально расписанный пример, который поможет разобраться новичкам.
Код:
//подключаем необходимые заголовочные файлы, пространства имен
#include <mysql++.h>
#include <iostream>
using namespace mysqlpp;
using namespace std;
//создаем экзмемпляры необходимых объектов
Connection conn;
StoreQueryResult queryres;
string querysring;
int main()
{
try
{
conn.connect("database", "dataserver", "datauser", "password"); //пробуем подключиться к базе
}
catch (ConnectionFailed err) //перехватываем возможное исключение типа ConnectionFailed
{
cout << "Не удалось подключится к базе данных, причина: " << err.what() << endl;
return 1;
}
if(conn.connected()) //проверяем, подключены ли мы к базе данных
{
querystring = "SELECT * FROM Datatable"; //инициализируем строку запроса
queryres = conn.query(querystring.c_str()).store(); //выполняем запрос
if(!res.empty()) //если что-то вернулось
{
for(int rc = 0; rc < (int)queryres.num_rows(); ++i) //построчно выводим на экран
cout << queryres[rc]["colname_one"] << queryres[rc]["colname_sec"] << endl;
} else
cout << "Запрос не вернул данных" << endl; //иначе сообщаем что ничего не вернулось
conn.disconnect(); //отключаемся от базы данных
} else
{
cout << "Подключение к базе данных потеряно..." << endl; //иначе сообщаем что коннект отвалился
return 1;
}
}
(так же у класса ConnectionFailed есть метод errnum (), возвращающий номер ошибки). После успешного подключения, проверяем еще раз, подключены ли мы, т.к. в случае нестабильной связи или по иным причинам – соединение может успеть отвалиться. В случае успешной проверки связи, инициализируем строку запроса querystring, наш запрос имеет вид: “SELECT * FROM Datatable”, что означает вернуть все абсолютно все записи из некой таблицы Datatable. После этого вызываем метод query, класса соединения, и у возвращенного объекта, вызываем метод store(), возвращенный результат запроса сохраняем в queryres. Далее проверяем, не пуст ли результат. Если нет – построчно выводим записи на экран.
В классе StoreQueryResult, экземпляром которого является queryres, строки хранятся в виде двумерного ассоциативного массива, это дает возможность обратиться к соотвествующему столбцу по его имени. Как в данном случае: queryres[rc]["colname_sec"] – обращаемся к rc-ой строке и столбцу под названием colname_one.
После окончания работы с бд следует обязательно закрыт соединение, что мы и делаем вызывая метод disconnect().
В предидущем примере мы научились получать интересующие нас записи, теперь мы научимся добавлять и удалять их.
Я не буду повторять код всей программы, а просто лишь опишу способы, с помощью которых достигается нужный нам результат. В примере ниже показано, как можно добавить строку в нашу таблицу Datatable.
SQL запрос в данном случае выглядит как INSERT INTO Datatable(colname_one, colname_sec) VALUES(‘data1′, ‘data2′).
А для выполнения этого запроса будем использовать метод execute().
Код:
querystring = "INSERT INTO Datatable(colname_one, colname_sec) VALUES('data1', 'data2')";
cout << "Добавлено строк: " << conn.query(querystring).execute().rows() << endl; //выполнение запроса с выводом результата
Все прочие операции, модификация, удаление строк выполняются аналогично, отличия будут только в самом тексте SQL запроса:
Модификация:
Код:
querystring = "UPDATE Datatable SET colname_sec = 'data3' WHERE colname_one = 'data1'";
cout << "Изменено строк: " << conn.query(querystring).execute().rows() << endl; //выполнение запроса с выводом результата
Код:
querystring = "DELETE FROM Datatable WHERE colname_one = 'data1'";
cout << "Удалено строк: " << conn.query(querystring).execute().rows() << endl; //выполнение запроса с выводом результата
Случается, что запросы могут некорректно работать с кириллическими
символами, для устранения этой возмутительной ошибки следует выполнит
особый запрос:
Код:
querystring = "SET CHARSET UTF8"; //задаем кодировку
conn.query(querystring).execute(); //выполняем запрос
Для компиляции программы следуюет выполнить команду:
Код:
c++ -o proga -I/usr/include/mysql -I/usr/include/mysql++ -lmysqlpp -L/usr/lib/mysql -L/usr/local/lib/mysql++ main.cpp
Заключение.
Выше были описаны примеры, позволяющие взаимодействовать с базой данных MySQL на различных платформах. Были затронуты лишь общие методы работы с библиотекой mysql++, список же классов и их методов намного обширнее, полностью ознакомится с ними можно на этой странице.
А здесь доступна полная документация, на английском языке, с различными примерами.
Выше были описаны примеры, позволяющие взаимодействовать с базой данных MySQL на различных платформах. Были затронуты лишь общие методы работы с библиотекой mysql++, список же классов и их методов намного обширнее, полностью ознакомится с ними можно на этой странице.
А здесь доступна полная документация, на английском языке, с различными примерами.
Комментариев нет:
Отправить комментарий