[英]How to get a whole row from database using SOCI into user-defined object type?
我擴展了我的課程(從這個問題: 如何使用SOCI從數據庫中獲取整行? )有兩個私有成員,還添加了getter和setter。 但是在編譯我的程序時,我又遇到了錯誤。
myClass.h
#include <soci.h>
#include <postgresql/soci-postgresql.h>
#include <string>
class MyClass
{
public:
MyClass();
MyClass(int i, std::string);
void setI(int i);
int getI() const;
void setS(std::string s);
std::string getS() const;
private:
int i_;
std::string s_;
};
namespace soci
{
template <>
struct type_conversion<MyClass>
{
typedef MyClass base_type;
static void from_base(int i, std::string s, soci::indicator ind, MyClass & mi)
{
if (ind == soci::i_null)
{
throw soci_error("Null value not allowed for this type");
}
mi.setI(i);
mi.setS(s);
}
static void to_base(const MyClass & mi, int & i, std::string &s, soci::indicator & ind)
{
i = mi.getI();
s = mi.getS();
ind = soci::i_ok;
}
};
}
myClass.cpp
#include "myClass.h"
MyClass::MyClass()
{
}
MyClass::MyClass(int i, std:string s)
{
this->i_ = i;
this->s_ = s;
}
int MyClass::getI() const
{
return this->i_;
}
void MyClass::setI(int i)
{
this->i_ = i;
}
std::string MyClass::getS() const
{
return this->s_;
}
void MyClass::setS(std::string s)
{
this->s_ = s;
}
myClassTest.cpp
#include <iostream>
#include "myClass.h"
int main(int argc, char **argv)
{
soci::session sql;
sql.open(soci::postgresql, "dbname=mydb user=postgres password=postgrespass");
MyClass i;
sql << "SELECT id, name FROM person;", soci::into(i);
std::cout << i.getI() << " " << i.getS();
sql.close();
return 0;
}
我這樣編譯:
g ++ myClassTest.cpp myClass.h myClass.cpp -o App -lsoci_core -lsoci_postgresql -ldl -lpq -I / usr / local / include / soci -I / usr / include / postgresql
而我得到的錯誤是:
In file included from /usr/local/include/soci/into-type.h:13:0,
from /usr/local/include/soci/blob-exchange.h:12,
from /usr/local/include/soci/soci.h:18,
from myClass.h:1,
from myClassTest.cpp:2:
/usr/local/include/soci/exchange-traits.h: In instantiation of ‘soci::details::exchange_traits<MyClass>’:
/usr/local/include/soci/into.h:29:60: instantiated from ‘soci::details::into_type_ptr soci::into(T&) [with T = MyClass, soci::details::into_type_ptr = soci::details::type_ptr<soci::details::into_type_base>]’
myClassTest.cpp:27:65: instantiated from here
/usr/local/include/soci/exchange-traits.h:35:5: error: incomplete type ‘soci::details::exchange_traits<MyClass>’ used in nested name specifier
In file included from /usr/local/include/soci/into.h:13:0,
from /usr/local/include/soci/soci.h:22,
from myClass.h:1,
from myClassTest.cpp:2:
/usr/local/include/soci/type-conversion.h: In member function ‘void soci::details::conversion_into_type<T>::convert_from_base() [with T = MyClass]’:
myClassTest.cpp:34:1: instantiated from here
/usr/local/include/soci/type-conversion.h:59:9: error: no matching function for call to ‘soci::type_conversion<MyClass>::from_base(soci::type_conversion<MyClass>::base_type&, soci::indicator&, MyClass&)’
/usr/local/include/soci/type-conversion.h:59:9: note: candidate is:
myClass.h:28:21: note: static void soci::type_conversion<MyClass>::from_base(int, std::string, soci::indicator, MyClass&)
myClass.h:28:21: note: candidate expects 4 arguments, 3 provided
myClass.cpp:8:28: error: found ‘:’ in nested-name-specifier, expected ‘::’
你試過SOCI 3.2嗎? 我用這個版本做了類似的工作,效果很好:
vector<Entry> Entry::findByName(string name) {
Entry entry;
vector<Entry> entries;
//Starting a connection to database
session sql(firebird, "service=/srv/firebird/registry.gdb user=SYSDBA password=password");
//Querying data using a prepared statement and place data into a Entry object
statement st = (sql.prepare <<
"select NAME, ADDRESS, PHONE from ENTRY WHERE NAME like '%' || :NAME || '%'",
into(entry), use(name));
st.execute();
//Checking if we can fetch a row from resultset
while (st.fetch())
{
//Pushing the object with mapped data into the entries vector
entries.push_back(entry);
}
return entries;
}
您可以將其更改為:
Entry Entry::findByName(string name) {
Entry entry;
//Starting a connection to database
session sql(firebird, "service=/srv/firebird/registry.gdb user=SYSDBA password=password");
//Querying data using a prepared statement and place data into a Entry object
statement st = (sql.prepare <<
"select NAME, ADDRESS, PHONE from ENTRY WHERE NAME like '%' || :NAME || '%'",
into(entry), use(name));
st.execute();
//Checking if we can fetch a row from resultset
if (st.fetch())
{
return entry;
}
return NULL;
}
注意:它們都是我的模型類的靜態類,它實現了ActiveRecord的自定義版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.