C++ के लिए ORM: तुलना और उदाहरण
C++ की दुनिया में, डेटाबेस के साथ काम करना ऐतिहासिक रूप से Python या Java जैसी भाषाओं की तुलना में अधिक निम्न-स्तरीय रहा है। हालाँकि, आधुनिक प्रोजेक्ट्स में सुविधा और उत्पादकता की आवश्यकता होती है, इसलिए डेवलपर्स तेजी से ORM (Object-Relational Mapping) की ओर रुख कर रहे हैं। C++ के लिए ORM आपको तालिकाओं के साथ सामान्य C++ ऑब्जेक्ट्स की तरह काम करने, स्वचालित रूप से SQL क्वेरी उत्पन्न करने और स्कीमा माइग्रेशन प्रबंधित करने की अनुमति देता है। इस लेख में, हम पाँच लोकप्रिय लाइब्रेरीज़: ODB, SQLiteCpp, SOCI, cppdb और sqlpp11 पर विचार करेंगे, उनकी विशेषताओं की तुलना करेंगे और व्यावहारिक उदाहरण देंगे।
1. ODB — कॉर्पोरेट मानक
ODB C++ के लिए एक शक्तिशाली ORM फ्रेमवर्क है जो कई DBMS का समर्थन करता है: MySQL, PostgreSQL, SQLite, Oracle, SQL Server। मुख्य विशेषता कोड जनरेशन है: आप एनोटेशन के साथ हेडर फ़ाइल में मॉडल का वर्णन करते हैं, और ODB कंपाइलर (odb) DB के साथ काम करने के लिए कोड बनाता है।
// person.hxx#pragma once#include <string>#include <odb/core.hxx>
#pragma db objectclass Person {public: Person() {} Person(const std::string& name, int age) : name_(name), age_(age) {}
const std::string& getName() const { return name_; } int getAge() const { return age_; }
private: friend class odb::access; #pragma db id auto unsigned long id_; std::string name_; int age_;};odb -d mysql person.hxx चलाने के बाद, कार्यान्वयन वाली फ़ाइलें उत्पन्न होती हैं। फिर हम मानक पैटर्न का उपयोग करते हैं:
#include <odb/database.hxx>#include <odb/mysql/database.hxx>#include "person-odb.hxx"
int main() { auto db = std::make_shared<odb::mysql::database>("user", "pass", "mydb"); Person p("Alice", 30); db->persist(p); // लोड करना auto loaded = db->load<Person>(1); return 0;}लाभ: पूर्ण ORM, माइग्रेशन समर्थन, lazy loading, ट्रांज़ैक्शन के साथ काम। नुकसान: जटिल सेटअप, कोड जनरेशन की आवश्यकता, छोटे प्रोजेक्ट्स के लिए भारीपन।
2. SQLiteCpp — हल्कापन और सरलता
SQLiteCpp C++ RAII शैली में SQLite3 के ऊपर एक रैपर है। यह पूर्ण ORM नहीं है, लेकिन क्वेरी के साथ काम करने के लिए एक सुविधाजनक इंटरफ़ेस प्रदान करता है।
#include <SQLiteCpp/Database.h>#include <SQLiteCpp/Statement.h>
int main() { SQLite::Database db("test.db", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE); db.exec("CREATE TABLE IF NOT EXISTS person (id INTEGER PRIMARY KEY, name TEXT, age INT)"); SQLite::Statement insert(db, "INSERT INTO person (name, age) VALUES (?, ?)"); insert.bind(1, "Bob"); insert.bind(2, 25); insert.exec(); // पढ़ना SQLite::Statement query(db, "SELECT * FROM person WHERE age > ?"); query.bind(1, 20); while (query.executeStep()) { std::cout << query.getColumn(1) << " " << query.getColumn(2) << ""; } return 0;}लाभ: न्यूनतमता, कोड जनरेशन की आवश्यकता नहीं, केवल SQLite के साथ काम करता है। नुकसान: कोई ऑब्जेक्ट मैपिंग नहीं, मैन्युअल SQL लेखन।
3. SOCI — सार्वभौमिक एब्स्ट्रैक्टर
SOCI (The C++ Database Access Library) शुद्ध रूप में ORM नहीं है, बल्कि विभिन्न DBMS (SQLite, PostgreSQL, MySQL, Oracle) के ऊपर एक एब्स्ट्रैक्शन है। यह क्वेरी निष्पादित करने और परिणामों को C++ संरचनाओं से जोड़ने के लिए सुविधाजनक सिंटैक्स प्रदान करता है।
#include <soci/soci.h>#include <soci/sqlite3.h>
struct Person { int id; std::string name; int age;};
int main() { soci::session sql(soci::sqlite3, "test.db"); sql << "CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT, age INT)"; Person p{1, "Charlie", 35}; sql << "INSERT INTO person (id, name, age) VALUES (:id, :name