业务中涉及到要实现数据库操作的通用化,想了一种思路,欢迎讨论
提到通用性,然后又用c++,这两个放到一起总是让人抓狂。。
业务中有些服务需要进行数据同步,无非就是将一个表中的数据抽取出来,放到另一个表中对应好,而这块业务又经常会用到,原来的方法是每个不同的业务分别开发一个对应的数据同步服务,理论上是没错,但是业务量上去了之后,每次开发一个,显得很是繁琐,于是就想到能不能一次开发,多次使用,不同的业务放到配置文件里去配置。
捋了一下之后,每个不同的服务不同之处只是操作的表不一样,如果能把这一层抽出来就好了,但是c++的数据库操作,不管是ADO,ODBC,还是OCI,解析sql语句的时候只能根据不同的表定义不同的结构体,然后根据字段类型定义变量类型,然后再跟变量绑定。
能不能有一种方法,将表结构和字段类型都定义成通用的呢,通用,表结构该怎么定义呢?
首先表中字段不确定个数,那么自然就想到动态数组vector,但是字段类型跟字段值怎么办呢,怎么将字段名,字段类型,字段值这三个对应起来然后存储,然后就想到了用三个vector分别对应这三个,但是怎么来保证三个vector映射起来呢,一般的map结构只能映射两个,一对一的关系,不爽,那我就自定义一个map类,将三个vector映射起来,通过定义一些用的着的成员函数分别操作三个成员字段名,字段类型,字段值的vector,这样就完成了映射。一个map结构就对应了表里的一行记录。自定义的map类如下:
#pragma once
#pragma warning(disable:4996)
#include <DEQUE>
#include <ASSERT.H>
//=============================================================================
/**
* Map table.
* Edit by Mr.zhu 2016/12/5
*/
template<class T1, class T2, class T3>
class CTableMap
{
public:
// T1 ==> T2
T2 First_to_Second(const T1& t1, const T2& t2Default) const
{
int i = GetIndexT1(t1);
return (i == -1) ? t2Default : m_t2Tab[i];
}
// T2 ==> T1
T1 Second_to_First(const T2& t2, const T1& t1Default) const
{
int i = GetIndexT2(t2);
return (i == -1) ? t1Default : m_t1Tab[i];
}
// T1 ==> T3
T3 First_to_Third(const T1& t1, const T3& t3Default) const
{
int i = GetIndexT1(t1);
return (i == -1) ? t3Default : m_t3Tab[i];
}
// 获取元素个数.
int SizeCol() const
{
if (m_t1Tab.size() == m_t2Tab.size())
return (int)m_t1Tab.size();
assert(false);
return 0;
}
int SizeValue() const
{
if (m_t1Tab.size() == m_t2Tab.size() && m_t1Tab.size() == m_t3Tab.size())
return (int)m_t1Tab.size();
assert(false);
return 0;
}
// 查找元素T1索引号,找不到返回-1
int GetIndexT1(const T1& t1) const
{
for (size_t i = 0; i < m_t1Tab.size(); i++)
{
if (m_t1Tab[i] == t1)
return (int)i;
}
return -1;
}
// 查找元素T2索引号,找不到返回-1.
int GetIndexT2(const T2& t2) const
{
for (size_t i = 0; i < m_t2Tab.size(); i++)
{
if (m_t2Tab[i] == t2)
return (int)i;
}
return -1;
}
// 查找元素T3索引号,找不到返回-1.
int GetIndexT3(const T3&am