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 13:23, 27 April 2015 by AutoSpider (talk | contribs) (Don't #include the module prefix)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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?, 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 <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.