C++ Sqlite3 と MySQL をサポートし、クロスプラットフォーム (Windows と Linux) をサポートするデータベース パッケージ

倉庫コードアドレス: https://gitee.com/liudegui/DatabaseLayer

概要

  • MySQLデータベース事業を利用する必要が生じたとき、アプリケーションを手早く構築したい場合があります.現時点では、MySQLの代わりに一時的にSQLiteを使用して開発することができます.ビジネスが安定するのを待ってからMySQLデータベースに切り替えることもできます.複数の人が MySQL データベースを共有するのを防ぎます。
  • DatabaseLayer は、Sqlite3 と MySQL をサポートし、クロスプラットフォーム (Windows と Linux) をサポートするデータベース パッケージです。CppSQLiteおよびPOCOのデータベース実装を参照してください。

特徴:

1. Sqlite3 と MySQL の統一された操作インターフェースを提供します
2. Sqlite3 と MySQL API の単純なパッケージ化のみ、コードは単純で理解しやすいです 3.
CppSqlite3 は stl を使用せず、組み込みプラットフォームをサポートします; CppMySQL は少量の STL を使用します。クロスプラットフォームをサポートします。
4. Unicode をサポートしていません
5. 具体的な事項と方法については、デモの例を参照してください

外部ヘッダー ファイル DatabaseLayer.h

DatabaseLayer.h で C++ マクロを使用して MySQL または SQLite を有効にします. もちろん、CppSQLite3.h または CppMySQL.h を直接使用することもできます. これら 2 つのデータベースの API は可能な限り統一されています.

/*! 
	\file		DatabaseLayer.h
*	\brief		数据库适配组件的基类
	\remmarks	只定义了基本的函数,具体请查看各个子类
*/

#pragma once

#ifndef _CppDBLayer_H_
#define _CppDBLayer_H_

#define POCO_VERSION 0x01010001

#ifdef _SQLITE3_DB
class	CppSQLite3Exception;
class	CppSQLite3DB;
class	CppSQLite3Query;
class	CppSQLite3ResultSet;
class	CppSQLite3Statement;

typedef  CppSQLite3Exception	CppDBException;
typedef  CppSQLite3DB			CppDB; 
typedef  CppSQLite3Query		CppDBQuery; 
typedef  CppSQLite3ResultSet	CppDBResultSet; 
typedef  CppSQLite3Statement	CppDBStatement; 
#endif

#ifdef _MySQL_DB
class	CppMySQLException;
class	CppMySQLDB;
class	CppMySQLQuery;
class	CppMySQLResultSet;
class	CppMySQLStatement;

typedef  CppMySQLException	CppDBException;
typedef  CppMySQLDB			CppDB; 
typedef  CppMySQLQuery		CppDBQuery; 
typedef  CppMySQLResultSet	CppDBResultSet; 
typedef  CppMySQLStatement	CppDBStatement;
#endif

/*!
	\class		DatabaseException 
	\brief		数据库异常处理基类
*/
class DatabaseException
{
    
    
public:
	virtual const int		errorCode()		= 0;
	virtual const char*		errorMessage()	= 0;
};

/*!
	\class		DatabaseLayer 
	\brief		数据库基本操作基类
*/
class DatabaseLayer	
{
    
    
public:
	virtual void			open(const char* szFile)	= 0;
	virtual void			close()						= 0;

	virtual bool			tableExists(const char* szTable) = 0;
	virtual int				execDML(const char* szSQL)	= 0;
	virtual CppDBQuery		execQuery(const char* szSQL) = 0;
	virtual int				execScalar(const char* szSQL, int nNullValue=0) = 0;

	virtual void			startTransaction()			= 0;
	virtual void			commitTransaction()			= 0;
	virtual void			rollback()					= 0;
	virtual bool			isTransaction()				= 0;
};

/*!
	\class		DatabaseQuery 
	\brief		数据库查询基类,不包含所有的数据
*/
class DatabaseQuery
{
    
    
public:
    virtual int				numFields()						= 0;
    virtual int				fieldIndex(const char* szField) = 0;
    virtual const char*		fieldName(int nCol)				= 0;
    virtual int				fieldDataType(int nCol)			= 0;

	virtual const char*		fieldValue(int nField)			= 0;
	virtual const char*		fieldValue(const char* szField) = 0;
	virtual bool			fieldDataIsNull(int nField)		= 0;

    virtual bool			eof()					= 0;
    virtual void			nextRow()				= 0;
	virtual	void			clear()					= 0;

	virtual	int				getIntField(int nField, int nNullValue = 0)							= 0;
	virtual	int				getIntField(const char* szField, int nNullValue = 0)				= 0;
	virtual	double			getDoubleField(int nField, double fNullValue = 0.0)					= 0;
	virtual	double			getDoubleField(const char* szField, double fNullValue = 0.0)		= 0;	
	virtual	const char*		getStringField(int nField, const char* szNullValue = "")			= 0;
	virtual	const char*		getStringField(const char* szField, const char* szNullValue = "")	= 0;
};

/*!
	\class		DatabaseResultSet 
	\brief		数据库查询结果集基类,包含所有的数据
*/
class DatabaseResultSet
{
    
    
public:
    virtual int				numFields() = 0;
    virtual unsigned long	numRows()	= 0;

	virtual int				FieldColIndex(const char* szField)	= 0;
    virtual const char*		fieldName(int nCol)					= 0;
    virtual const char*		fieldValue(int nField)				= 0;
    virtual const char*		fieldValue(const char* szField)		= 0;
	virtual bool			fieldDataIsNull(int nField)			= 0;

	virtual bool			eof()		= 0;
	virtual void			nextRow()	= 0;
    virtual int				seekRow(unsigned long nRow) = 0;
	virtual	void			clear()		= 0;
};

/*!
	\class		DatabaseStatement 
	\brief		Statement基类
				
*/
class DatabaseStatement
{
    
    
public:
	virtual int				execDML()		= 0;

	virtual void			bind(int nParam, const char* szValue)	= 0;
	virtual void			bind(int nParam, const int nValue)		= 0;
	virtual void			bind(int nParam, const double dwValue)	= 0;

	virtual void			reset() = 0;
	virtual void			clear() = 0;
};

#if defined _SQLITE3_DB && !defined _CppSQLite3_H_
#include "CppSQLite3.h"
#endif

#if defined _MySQL_DB && !defined _CPPMYSQL_H_
#include "CppMySQL.h"
#endif

#ifdef _WIN32
#include "Platform_WIN32.h"
#endif

#endif

使用例

サンプル コードは、ビジネス コードで SQLite と MySQL の間でデータをすばやく切り替える方法を示しています。


#include <stdlib.h>
#include <stdio.h>
#include <ctime>
#include <iostream>

#include "DatabaseLayer.h"

using namespace std;

#ifdef _SQLITE3_DB
const char* gszDB = "CppSQLite3Demo.db";
#endif

#ifdef _MySQL_DB
const char* gszDB = "CppMySQLDemo";
#endif

int main()
{
    
    
	try
	{
    
    
		CppDB db;
		int i, fld;

#ifdef _SQLITE3_DB
		  remove(gszDB);
#endif
#ifdef _MySQL_DB
		db.connect("127.0.0.1", "root", "root");
		db.dropDB(gszDB);
		db.createDB(gszDB);
#endif

		db.open(gszDB);

		cout << endl << "emp table exists=" << (db.tableExists("emp") ? "TRUE":"FALSE") << endl;
		cout << endl << "Creating emp table" << endl;
		db.execDML("create table emp(empno int, empname char(20));");
		cout << endl << "emp table exists=" << (db.tableExists("emp") ? "TRUE":"FALSE") << endl;

		
		// 测试DML,打印影响行
		
		cout << endl << "= 测试DML,打印影响行 =" << endl;
		int nRows = db.execDML("insert into emp values (6, '勒布朗·詹姆斯');");
		cout << nRows << " rows inserted" << endl;

		nRows = db.execDML("update emp set empname = 'LeBron James' where empno = 6;");
		cout << nRows << " rows updated" << endl;

		nRows = db.execDML("delete from emp where empno = 7;");
		cout << nRows << " rows deleted" << endl;

		nRows = db.execDML("delete from emp where empno = 6;");
		cout << nRows << " rows deleted" << endl;

		
		// 测试事务和execScalar
		
		cout << endl << "= 测试事务和execScalar =" << endl;
		int nRowsToCreate(25000);
		cout << endl << "Transaction test, creating " << nRowsToCreate;
		cout << " rows please wait..." << endl;

		db.startTransaction();

		for (i = 0; i < nRowsToCreate; i++)
		{
    
    
			char buf[128];
			sprintf(buf, "insert into emp values (%d, 'Empname%06d');", i, i);
			db.execDML(buf);
		}

		db.commitTransaction();

		cout << db.execScalar("select count(*) from emp;") << " rows in emp table";

		
		// 重新创建表emp
		
		cout << endl << "= 重新创建表emp = " << endl;
		db.execDML("drop table emp;");
	#ifdef _SQLITE3_DB
		db.execDML("create table emp(empno integer primary key, empname char(20));");
	#endif
	#ifdef _MySQL_DB
		db.execDML("CREATE TABLE emp(empno int not null auto_increment, empname char(20) not null, primary key (empno)) ENGINE=InnoDB;");
	#endif	
		cout << nRows << " rows deleted" << endl;

		for (i = 0; i < 5; i++)
		{
    
    
			char buf[128];
			sprintf(buf, "insert into emp (empname) values ('帅锅%02d');", i+1);
			db.execDML(buf);
		}

		
		// 测试CppDBQuery
		
		cout << endl << "= 测试CppDBQuery =" << endl;
		CppDBQuery q = db.execQuery("select * from emp order by 1;");

		cout <<endl<<"Num of fields: "<< q.numFields() << endl;
	#ifdef _SQLITE3_DB
		cout <<endl<<"Num of rows: "<< db.execScalar("select count(*) from emp") << endl<<endl;
	#endif
	#ifdef _MySQL_DB
		cout <<endl<<"Num of rows: "<< q.numRows() << endl<<endl;
	#endif

		for (fld = 0; fld < q.numFields(); fld++)
		{
    
    
			cout << q.fieldName(fld) << "|";
		}
		cout << endl;

		while(!q.eof())
		{
    
    
			cout << q.getStringField(0) << "|";
			cout << q.getStringField(1) << "|" << endl;
			q.nextRow();
		}

		cout << endl << "= 赋值构造函数测试 =" << endl;
		q = db.execQuery("select empname from emp;");
		cout <<endl<<"Num of fields: "<< q.numFields() << endl;

		q.clear();

		
		// CppDBResultSet测试
		
		cout << endl << "= CppDBResultSet测试 =" << endl;
		CppDBResultSet t = db.getResultSet("select * from emp order by 1;");

		cout <<endl<<"Num of fields: "<< t.numFields() << endl;
		cout <<endl<<"Num of rows: "<< t.numRows() << endl << endl;

		for (fld = 0; fld < t.numFields(); fld++)
		{
    
    
			cout << t.fieldName(fld) << "|";
		}
		cout << endl;

		int row;
		for (row = 0; row < (int)t.numRows(); row++)
		{
    
    
			t.seekRow(row);
			for (fld = 0; fld < t.numFields(); fld++)
			{
    
    
				cout << t.fieldValue(fld) << "|";
			}
			cout << endl;
		}

		cout << endl << "另一种显示ResultSet的方法" << endl;
		t.seekRow(0);	//这步不可少
		while (!t.eof())
		{
    
    
			cout << t.fieldValue(0) << "|";
			cout << t.fieldValue(1) << "|";
			cout << endl;

			t.nextRow();
		}
		t.clear();

		
		// 测试CppDBStatement
		
		cout << endl << "= 测试CppDBStatement = " << endl;
		cout << " rows please wait..." << endl;
		db.execDML("drop table emp;");
		db.execDML("create table emp(empno int, empname char(20));");

		db.startTransaction();

		nRowsToCreate = 200;
		cout << endl << "Creating with bind by number" << endl;
		CppDBStatement stmt = db.compileStatement("insert into emp values (?, ?);");
		for (i = 0; i < nRowsToCreate; i++)
		{
    
    
			char buf[16];
			sprintf(buf, "EmpName%02d", i);
			stmt.bind(1, i);
			stmt.bind(2, buf);
			stmt.execDML();
			stmt.reset();
		}
		stmt.clear();
		db.commitTransaction();
		
		cout << db.execScalar("select count(*) from emp;") << " rows in emp table " << endl;

		t = db.getResultSet("select * from emp limit 10;");

		for (fld = 0; fld < t.numFields(); fld++)
		{
    
    
			cout << t.fieldName(fld) << "|";
		}
		cout << endl;

		for (row = 0; row < (int)t.numRows(); row++)
		{
    
    
			t.seekRow(row);
			for (fld = 0; fld < t.numFields(); fld++)
			{
    
    
				cout << t.fieldValue(fld) << "|";
			}
			cout << endl;
		}

		cout << endl << "End of tests" << endl;

	}
	catch (CppDBException& e)
	{
    
    
		cerr <<endl<< "Exception:"<<e.errorCode() << ":" << e.errorMessage() << endl;
	}

	
	// Loop until user enters q or Q
	
	char c(' ');

	while (c != 'q' && c != 'Q')
	{
    
    
		cout << "Press q then enter to quit: ";
		cin >> c;
	}

	return 0;
}



おすすめ

転載: blog.csdn.net/stallion5632/article/details/125819143