Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.07.2009, 20:23   #1
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию Работа с MySQL в С++ с использованием библиотеки mysql++

Под впечатлением от этой статьи я решил написать свой небольшой мануал по работе с СУБД 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.

Код:
#include <mysql++.h>
using namespace 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()

Вот теперь мы точно готовы к тому, что бы написать наше первое простейшее приложение

Последний раз редактировалось oleg kutkov; 31.07.2009 в 20:43.
oleg kutkov вне форума Ответить с цитированием
Старый 31.07.2009, 20:24   #2
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию

Данное приложения представляет собой очень простой и детально расписанный пример, который поможет разобраться новичкам.

Код:
//подключаем необходимые заголовочные файлы, пространства имен
#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;
	}				
}
Как видно, программа очень проста и легка для понимания. В начале мы пробуем подключится к базе данных 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().
Далее будет описано как добавлять и удалять строки в таблице.

Последний раз редактировалось oleg kutkov; 31.07.2009 в 20:44.
oleg kutkov вне форума Ответить с цитированием
Старый 31.07.2009, 20:24   #3
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию

В предидущем примере мы научились получать интересующие нас записи, теперь мы научимся добавлять и удалять их.
Я не буду повторять код всей программы, а просто лишь опишу способы, с помощью которых достигается нужный нам результат. В примере ниже показано, как можно добавить строку в нашу таблицу 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; //выполнение запроса с выводом результата
Как видно, все очень и очень просто, инициализируем строку запроса, и вызываем метод execute(), который возвращает нам объект класса SimpleResult, и используя метод rows() последнего мы получаем сколько строк изменено, т.е. в данном случае добавлено. Полученный результат сразу же шлем в поток вывода. Я написал все без введения дополнительных, промежуточных, переменных, для компактности и экономичности.

Все прочие операции, модификация, удаление строк выполняются аналогично, отличия будут только в самом тексте 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; //выполнение запроса с выводом результата
oleg kutkov вне форума Ответить с цитированием
Старый 31.07.2009, 20:25   #4
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию

Случается, что запросы могут некорректно работать с кириллическими символами, для устранения этой возмутительной ошибки следует выполнить особый запрос:

Код:
	querystring = "SET CHARSET UTF8"; //задаем кодировку
	conn.query(querystring).execute(); //выполняем запрос
В данном примере указана кодировка UTF8, как основная на современных Linux системах. Вам следует задать кодировку вашей системы, для корретной обработки киррилицы.
Для компиляции программы следуюет выполнить команду:
Код:
c++ -o proga -I/usr/include/mysql -I/usr/include/mysql++ -lmysqlpp -L/usr/lib/mysql -L/usr/local/lib/mysql++ main.cpp
В этой команде файл с исходным кодом main.cpp компилируется, подключая необходимые библиотеки.

Заключение.
Выше были описаны примеры, позволяющие взаимодействовать с базой данных MySQL на различных платформах. Были затронуты лишь общие методы работы с библиотекой mysql++, список же классов и их методов намного обширнее, полностью ознакомится с ними можно на этой странице.
А здесь доступна полная документация, на английском языке, с различными примерами.

Последний раз редактировалось oleg kutkov; 01.08.2009 в 02:33.
oleg kutkov вне форума Ответить с цитированием
Старый 20.09.2009, 15:38   #5
artush1984
Форумчанин
 
Аватар для artush1984
 
Регистрация: 27.04.2009
Сообщений: 184
По умолчанию Вопрос по юникоду

Вопрос вот в чём ! на мои запроси он возврашает мне строки типа char а нелзя сделат так что бы он мне wchar_t возвращал?
Hа C я могy пpосто делать ошибки, на C++ я могy их наследовать!
artush1984 вне форума Ответить с цитированием
Старый 30.12.2010, 16:40   #6
ololo-schoolboy
Форумчанин
 
Регистрация: 25.12.2010
Сообщений: 247
По умолчанию

при компиляции возникли ошибки:
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\eh.h(61) : error C2039: MysqlNull:: is not a member of "vc_attributes::Pre"
c:\program files\microsoft visual studio 9.0\vc\include\codeanalysis\sourcea nnotations.h(71): see declaration of 'vc_attributes::Pre'
и так далее
ololo-schoolboy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с MySQL в C++ psycho-coder C/C++ Базы данных 121 07.12.2015 13:39
Голосование с использованием MySQL veter_s_morya PHP 12 15.02.2009 10:02
Работа с MySQL igroman PHP 10 29.09.2008 16:15
MySQL нужна библ. для Visual C++ (MySql++) Alexoid Visual C++ 8 07.05.2008 18:29
Работа с MySql zetrix PHP 1 18.06.2007 15:02