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, 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?, 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"

  1. ifndef C1_H
  2. define C1_H
  1. include <QObject>
  2. 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;

};

  1. endif // C1_H

arquivo cpp do meu objeto:

  1. 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":

  1. ifndef CONNECTIODB_H
  2. define CONNECTIODB_H
  1. include <QObject>
  2. 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:

};

  1. endif // CONNECTIODB_H

arquivo de codigo do meu "ConnectionDB"

  1. include "connectiodb.h"
  2. include <QMessageBox>
  3. include <QSqlDatabase>
  4. include <QSqlError>
  5. include <QSqlQuery>
  6. include "QString"
  7. include "QDebug"
  8. include "QtGui"
  9. include "QMetaObject"
  10. 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:

  1. include "mainwindow.h"
  2. include <QApplication>
  3. include <QDebug>
  4. include <c1.h>
  5. include <connectiodb.h>
  6. 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.