Qt 5.x Acceso a base de datos

El acceso a una base de datos es un elemento importante al momento de desarrollar una aplicación de cualquier tipo, por ello el Framework Qt nos provee el módulo SQL el cuál nos facilita el proceso de conexión y consulta de datos, este módulo soporta oficialmente las bases de datos: SQLite, MySQL, ODBC, y PostgreSQL.

Conexión a SQLite con Qt

SQLite es un motor de datos que nos permitirá crear bases de datos embebidas, ya sea en memoria o almacenadas en un archivo, además es muy fácil de usar ya que no requiere configuración y esta soportada por Qt. 

Lo primero que debemos hacer es configurar el proyecto para agregar el soporte para el módulo SQL, por ello abrimos el archivo .pro y editamos lo siguiente:

QT += core sql

Luego utilizamos la clase QSqlDatabase para conectarnos al motor de datos, por medio de addDatabase("...") indicamos la base de datos, mediante setDatabaseName("...") establecemos en nombre de la misma, en este caso ":memory:" indicada a SQLite que debe crear una BD en memoria, si deseas una BD persistente solo debes cambiar el nombre.

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");                       
db.setDatabaseName(":memory:");                                               
                                                                              
if(db.open()) {                                                                             
    cout << "Conexion a [SQLITE] preparada." << endl << endl;                                                                                                                                                             
    db.close();                                                               
}

El método open() abre la conexión y devuelve un booleano que indica si se pudo o no conectar, mientras que close() la cierra.

Crear tabla e insertar datos

Una vez tenemos la conexión podemos lanzar consultas contra la BD, vamos a crear la primera tabla, para ello requerimos crear un objeto QSqlQuery y usar el método exec("...") para enviar la consulta.

void createTablePerson()
{
    QSqlQuery query;

    if(query.exec("CREATE TABLE person(id int primary key, name varchar(50), lastname varchar(50), age int);"))
    {
        cout << "Tabla [PERSON] creada correctamente." << endl;
    }
    else
    {
        cout << query.lastError().text().toStdString() << endl;
    }
}

El método lastError().text() devuelve la cadena de texto que contiene información sobre el error.

Ya tenemos la tabla, para ingresar datos en ella hacemos el mismo procedimiento, solo debemos cambiar la consulta, ejemplo:

void insertDataPerson()
{
    QSqlQuery query;

    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (1, 'Juan', 'Perez', 18);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (2, 'Ana', 'Maria', 19);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (3, 'Maria', 'Lopez', 20);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (4, 'Luis', 'Diaz', 28);");
}

En este código a diferencia del anterior omitimos la comprobación de errores, lo hicimos solo por brevedad y simplicidad, en una aplicación real es algo que siempre debes tener presente.

Consultar datos

El proceso para realizar una consulta SELECT es similar, salvo que utilizaremos el método next() para iterar a través de los resultados obtenidos, con value(int) obtenemos el valor de la columna respectiva, debemos indicar el índice de la columna, si lo deseamos también podemos indicar su nombre.

QSqlQuery query;                                                          
 query.exec("SELECT * FROM person;");                                      
                                                                           
 while(query.next()) {                                                     
                                                                           
     int id = query.value(0).toInt();                                      
     int age = query.value(3).toInt();                                     
                                                                           
     string name = query.value(1).toString().toStdString();                
     string lastname = query.value(2).toString().toStdString();            
                                                                           
     cout << id << ", " << name << ", " << lastname << ", " << age << endl;
 }

El método value(int) devuelve un objeto QVariant, para obtener el dato respectivo de la columna debemos convertir este objeto a al tipo correspondiente a la columna en la BD, para esto utilizamos los métodos: toInt(), toString(), toDouble(), ..., .

Código completo

#include <QCoreApplication>
#include <QSql>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>

#include <iostream>

using namespace std;

void createTablePerson()
{
    QSqlQuery query;

    if(query.exec("CREATE TABLE person(id int primary key, name varchar(50), lastname varchar(50), age int);"))
    {
        cout << "Tabla [PERSON] creada correctamente." << endl;
    }
    else
    {
        cout << query.lastError().text().toStdString() << endl;
    }
}

void insertDataPerson()
{
    QSqlQuery query;

    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (1, 'Juan', 'Perez', 18);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (2, 'Ana', 'Maria', 19);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (3, 'Maria', 'Lopez', 20);");
    query.exec("INSERT INTO person(id, name, lastname, age) VALUES (4, 'Luis', 'Diaz', 28);");
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");

    if(db.open())
    {
        cout << "Conexion a [SQLITE] preparada." << endl << endl;

        // comprobar si existe la tabla person
        if(!db.tables().contains("person")) {
            createTablePerson();
            insertDataPerson();
        }

        QSqlQuery query;
        query.exec("SELECT * FROM person;");

        while(query.next()) {

            int id = query.value(0).toInt();
            int age = query.value(3).toInt();

            string name = query.value(1).toString().toStdString();
            string lastname = query.value(2).toString().toStdString();

            cout << id << ", " << name << ", " << lastname << ", " << age << endl;
        }

        db.close();
    }

    return a.exec();
}

Ejecuta el programa y observa los resultados.

Conectar a MySQL

Para realizar la conexión al servidor MySQL solo debemos establecer los datos de conexión y cambiar el nombre de la base de datos a QMYSQL, asumimos que tienes el servidor instalado y ejecutándose, además de tener una BD llamada tutorial, por ejemplo:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");                          
db.setPort(3306);                                     
db.setUserName("root");                               
db.setPassword("123456");                             
db.setDatabaseName("tutorial");

Si al tratar de ejecutar se presenta el siguiente error:

QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7

Esto, probablemente se debe a que te falta instalar el correspondiente conector, puedes descargarlo o agregarlo desde MySQL Installer.

Qt MySQL conexión de datos

Ahora debes ubicar el archivo: "C:\Program Files\MySQL\MySQL Connector.C 6.1\lib\libmysql.dll" podemos hacer dos cosas, primero agregar la carpeta que contiene el archivo a la variable de entorno PATH o copiar el archivo libmysql.dll y pegarlo en el directorio en donde se construye el proyecto.

Descargar código: qt-basedatos.zip

Comentarios

  1. Muy claros los ejemplos, puedes poner el de postgres y describir como resolver el que no puede cargar el driver, gracias.

    ResponderEliminar
  2. UNA CONSULTA COMO PUEDO CONSULTAR DATOS DESDE LA BASE DE DATOS DE TIPO QMYSQL?

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

tkinter Canvas

Histogramas OpenCV Python

Python Binance API