Criando-um-metodo-que-recebe-um-objeto-qualquer-e-faz-uma-insercaeo-em-uma-tabela-de-um-banco-de-dad

From Qt Wiki
Revision as of 15:32, 3 March 2015 by AutoSpider (talk | contribs) (Add "cleanup" tag)
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Como prometi no topico "Como Manipular uma Classe Qualquer?":http://forum.qt.io/viewthread/26452/, vou mostrar agora como fazer um metodo que recebe uma classe qualquer.

O objetivo em questao é receber um objeto qualquer e fazer um "insert" em um banco de dados (no caso usei o sqlite) a partir das propriedades do objeto.

segue o código:

meu objeto "C1"

#ifndef C1_H
#define C1_H

#include <QObject>
#include <QtScript/QScriptClass>

class C1 : public QObject
{
 Q_OBJECT

//aqui definiremos as propriedades do objeto e seus respectivos metodos de leitura, onde:
// Q_PROPERTY(<tipo e nome da propriedade> READ <nome funçao que retorna o valor da sua propriedade>)
// o "READ" serve para especificar qual a funçao que retornara o valor da minha propriedade
 Q_PROPERTY(int x READ X)
 Q_PROPERTY(QString campo1 READ Campo1)
 Q_PROPERTY(int campo2 READ Campo2)
 Q_PROPERTY(QString parameters READ parameters)

public:
 explicit C1(QObject *parent = 0);

QString parameters()
 {
//aqui eu posso retornar os parametros a seguir:
 return "table(c1);colums(campo1,campo2,x)";
//ou nada, indicando que todas as propriedades serao inseridas na tabela
 //return "";
 }

QString Campo1();//const;
 int Campo2();
 int X();

private:
 int x;
};

#endif // C1_H

arquivo cpp do meu objeto:

#include "c1.h"

C1::C1(QObject *parent) :
 QObject(parent)
{
 x=20;

//aqui, se preferirem indiquem o um nome para o objeto…
// no caso, estou usando ele para referenciar o nome da tabela
//se nao for informado o nome da tabela sera o mesmo da minha classe…
 // this->setObjectName("C1");
}

QString C1::Campo1()
{
 return "Rodrigo";
}

int C1::Campo2()
{
 return 3;
}

int C1::X()
{
 return this->x;
}

minha classe "ConnectionDB":

#ifndef CONNECTIODB_H
#define CONNECTIODB_H

#include <QObject>
#include <qsql.h>

class ConnectioDB : public QObject
{
 Q_OBJECT
public:
 explicit ConnectioDB(QObject *parent = 0);

//o metodo a seguir é responsavel por abrir uma conexao com o meu banco de dados
 static bool createConnection(QString plugin, bool memory ,QString connectionName,
 QString DBname,QString Hostname, QString user, QString pass);

static bool insert(QObject *obj,QString connectionName);
// static bool update(QObject *obj,QString connectionName);
// static bool remove(QObject *obj,QString connectionName);

signals:

public slots:

};

#endif // CONNECTIODB_H

arquivo de codigo do meu "ConnectionDB"

#include "connectiodb.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include "QString"
#include "QDebug"
#include "QtGui"
#include "QMetaObject"
#include <QVariant>

ConnectioDB::ConnectioDB(QObject '''parent) :
 QObject(parent)
{

}

bool ConnectioDB::createConnection(QString plugin, bool memory, QString connectionName, QString DBname, QString Hostname, QString user, QString pass)
{
 /'''
 Essa funçao abrira uma conexão, se for passado as seguintes informações:

plugin* - É informado o plugin referente ao banco de dados que sera feito a conexão.

local* - Apenas para o QSQLITE onde pode assumir os valores "memory" ou "null"

connectionname* - Nome da conexão que sera criada

Hostname - Local onde esta o servidor. Desnecessario quando o plugin for o QSQLITE

user - Usuário, necessario quando a conexao requer autenticaçao.

pass - Senha, necessario quando a conexao requer autenticaçao.

OBS: os parametros descritos com o simbolo * indica que o parametro é obrigatorio. Demais
 pode ser informado o valor null para indicar que nao sera usado.

'''falta descrever alguns parametros.

*/
 QSqlDatabase db = QSqlDatabase::addDatabase(plugin, connectionName);
 if(!memory)
 {
 if(!Hostname.isEmpty())
 db.setHostName(Hostname);
 if(!user.isEmpty())
 db.setUserName(user);
 if(!pass.isEmpty())
 db.setPassword(pass);
 if(!DBname.isEmpty())
 db.setDatabaseName(DBname);
 }
 else db.setDatabaseName(":memory:");

if (!db.open())
 {
 QMessageBox::critical(0, qApp->tr("Cannot open database"),
 qApp->tr("Unable to establish a database connection."
 "This example needs SQLite support. Please read "
 "the Qt SQL driver documentation for information how "
 "to build it."
 "Click Cancel to exit."), QMessageBox::Cancel);
 qDebug()<<"Create Connection"<<connectionName<<false<<"- DATA BASE:"<<DBname;
 return false;
 }

qDebug()<<"Create Connection"<<connectionName<<true<<"- DATA BASE:"<<DBname;
 return true;
}

bool ConnectioDB::insert(QObject '''obj, QString connectionName)
{

 const QMetaObject''' metaObject = obj->metaObject();
 QString colums="";
 QString table=obj->objectName();//estou usando o nome do objeto para referenciar o nome da tabela
 QString values="";
 //processa os parametros

//pega a propriedade que possui o nome "parameters"
 // QVariant v = obj->property(metaObject->property(metaObject->indexOfProperty("parameters")).name());
 QVariant v = obj->property("parameters");//retorna um valor a partir do nome da propriedade

//leitura dos parametros
 QString parameters=v.toString();
 //separa e joga em uma lista
 QStringList list=parameters.split(";");

for (int i = 0; i < list.size(); +''i)
 {
 QString str=list.at(i).toLocal8Bit().constData();
 if(str.contains("colums"))
 {
 // str.remove("colums(");
 str.remove("colums");
 // str.remove(")");
 colums=str;
 qDebug()<<"colums="<<colums;
 }else if(str.contains("table"))
 {
 str.remove("table(");
 str.remove(")");
 table=str;
 qDebug()<<"table="<<table;
 }
 }

 //reunindo os valores a serem inseridos
 if(colums.isEmpty())
 {
 for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount();i)
 {

 QVariant v = obj->property(metaObject->property(i).name());
 if(!QString(metaObject->property(i).name()).contains("parameters",Qt::CaseInsensitive))//remove "parameters" da inserçao
 {
 if(!colums.isEmpty())
 colums''=",";
 colums+=QString::fromLatin1(metaObject->property(i).name()).toLower();

if(colums.contains(QString::fromLatin1(metaObject->property(i).name()).toLower()))
 {
 if(!values.isEmpty()) values+=",";
 values+="'"''v.toString()''"'";
 }
 }
 }
 colums="("''colums''")";
 } else
 {
 QString aux=colums;
 aux.remove("(");
 aux.remove(")");
 QStringList columsList=aux.split(",");

for (int i = 0; i < columsList.size(); +''i)
 {

 // QVariant v2 = obj->property(metaObject->property(metaObject->indexOfProperty(QString(columsList.at(i).toLocal8Bit()).toAscii())).name());
QVariant v2 = obj->property(QString(columsList.at(i).toLocal8Bit()).toAscii());
 if(!values.isEmpty()) values''=",";
 values+="'"''v2.toString()''"'";
 }
 }

//faz a inserçao no banco de dados
 QSqlQuery *query=new QSqlQuery(connectionName,QSqlDatabase::database(connectionName));
 qDebug() <<"values ="<<values<<"colums ="<<colums<<query->exec("INSERT INTO "''table+colums''"VALUES ("+values+");");
}

meu arquivo main:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <c1.h>
#include <connectiodb.h>
#include <QSqlQuery>

int main(int argc, char *argv[])
{
 C1 *c1 = new C1;
 ConnectioDB::createConnection("QSQLITE",false,"meubd","teste.db",NULL,NULL,NULL);
 QSqlQuery *query=new QSqlQuery("meubd",QSqlDatabase::database("meubd"));
// qDebug() <<query->exec("CREATE TABLE C1 ( "
// "cod INTEGER PRIMARY KEY"
// "NOT NULL, "
// "campo1 VARCHAR( 128 ), "
// "campo2 INT, "
// "x INT "
// ");");
 c1->setObjectName("c1");
 ConnectioDB::insert(c1,"meubd");
 return 0;
}

é isso, próximo post vou mostrar como escrever em um objeto qualquer fazendo um metodo que busca um objeto em uma tabela.