具体实施方式
为了使本发明的目的、技术方案和优点更加清楚,下面结合附图和具体实施例对本发明进行详细描述。
本发明提供的主要方法可以如图1所示,主要包括以下步骤:
步骤101:预先定义各类型数据库模板,每个数据库模板中包含该类型数据库的SQL语句以及SQL语句对应的功能标识;其中,数据库模板中具有相同功能的SQL语句对应相同的功能标识。
步骤102:访问数据库的装置启动后,加载所有模板。
步骤103:接收到调用指令后,确定当前连接的数据库类型对应的所有SQL语句构成的结果集。
步骤104:在步骤103确定的结果集中,查询调用指令包含的功能标识对应的SQL语句,执行该SQL语句以实现对数据库的访问。
下面结合具体实施例对本发明所提供的上述方法进行详细描述。图2为本发明所提供方法的执行层次示意图,主要分为SQL模板层、模板控制中间层和SQL执行层。对应执行流程可以具体包括以下步骤:
步骤201:预先定义各类型数据库模板,每个数据库模板中包含该类型数据库的SQL语句以及SQL语句对应的功能标识。
在该实施例中,模板中SQL语句及其标识的定义状况可以包括以下几种形式:
第一种形式:仅存在数据库模板,各数据库模板中包含对应类型数据库的SQL语句以及SQL语句对应的功能标识。
假设存在SQL Server数据库、Oracle数据库和MySQL数据库等,则可以根据数据库类型,分别预先定义SQL Server模板、Oracle模板和MySQL模板等。其中,SQL Server模板中存储SQL Server数据库的SQL语句,Oracle模板中存储Oracle数据库的SQL语句,MySQL模板存储MySQL数据库的SQL语句。
各数据库模板中的各SQL语句都存在与其对应的功能标识,在各类型的数据库模板中相同功能的SQL语句对应相同的功能标识,每个功能标识在一个数据库模板中是唯一的。例如,在SQL Server模板中定义query.subsql1=“select top N employee_id from tbl_employee order by salary desc”;在Oracle模板中定义query.subsql1=“select employee_id from tbl_employee whererownum<=N order by salary desc”,由于这两个SQL语句都对应查询前N个数据的功能,因此,对应相同的功能标识query.subsql1。
需要说明的是,在各模板中可以采用扩展标记语言(XML)文件的形式来进行定义,也可以采用“ID=SQL语句”的形式进行定义,本发明中以ID=SQL语句”的形式为例。
第二种形式:由于在某些情况下可能存在多种类型的数据库对应同一功能的SQL语句是相同的,为了对这种情况下的SQL语句进行复用,除了设置各类型数据库模板之外,还可以设置通用语句模板。通用语句模板中存储多种类型数据库的相同SQL语句以及SQL语句对应的功能标识,如图2中SQL模板层所示。
例如,如果某个SQL语句对于SQL Server数据库、Oracle数据库和MvSQL数据库都相同,则可以不在各类型的数据库模板中定义,仅在通用语句模板中定义即可。
第三种形式:为了最大限度地对各类型数据库的SQL语句进行复用,在第二种形式的基础上,可以在通用语句模板的SQL语句中对数据库模板中的功能标识进行引用,被引用的功能标识称为模板变量。即功能标识作为模板变量在数据库模板中定义,在通用语句模板中被引用。
例如,查询数据库中的前N个数据,对应于SQL Server数据库和Oracle数据库,必须采用特定的SQL语句,而其它数据库则采用相同的SQL语句。这种情况下,可以首先在采用特定SQL语句的SQL Server模板中定义query.subsql1=“select top10employee_id from tbl_employee order by salarydesc”。
在Oracle模板中定义query.subsql1=“select employee_id fromtbl_employee where rownum<=10order by salary desc”。
为了最大限度地复用相同的SQL语句,则在通用语句模板中定义query.test=“select N from tbl_employee where employee_id not in,并使该语句引用query.subsql1,以表征query.test和query.subsql1完成相同功能。如果采用“${模板变量}”的方式进行模板变量的引用,则通用语句模板中可以表示为:query.test=“select N from tbl_employee where employee_id notin(${query.subsql1})”。当然,本发明对模板变量的具体引用形式并不限制,还可以采用其它引用形式。
这种方式中,功能标识query.test针对SQL Server数据库对应的SQL语句应该为select top10employee_id from tbl_employee order by salary desc,针对Oracle数据库对应的SQL语句应该为select employee_id from tbl_employeewhere rownum<=10orderby salary desc,针对其它数据库对应的SQL语句为select N from tbl_employee where employee_id not in。
第四种形式:由于在实际使用时,系统可能会新增支持的数据库类型,为了在增加数据库类型的同时,不对已有模板产生影响和修改,可以在上述引用规则的基础上新增一种形式:当数据库模板中的功能标识和通用语句模板中的功能标识相同,而对应的SQL语句不同时,优先使用数据库模板中该功能标识对应的SQL语句。
例如,从数据库中选择特定名称的数据,原有的数据库类型对应的SQL语句均相同,则在通用语句模板中定义query.subsql1=“select*from tbl test”。如果后来新增加了一种类型的数据库SQL Server,而SQL Server对应的选择特定名称的数据对应的SQL语句与其它数据库并不相同,为了不对已有模板产生影响,则可以在SQL Server模板中定义query.subsql1=”select name fromtbl_test”,虽然与通用语句模板中功能标识相同,但对应的SQL语句并不相同,此时,SQL Server数据库中该功能的SQL语句以SQL Server模板中的为准。
第五种形式:在通用模板中定义的功能标识作为模板变量被数据库模板引用。
这种形式通常出现在数据库模板中的SQL语句包含子查询功能的情况下,当数据库模板中相同功能的SQL语句中可能存在一部分SQL语句相同,其它部分的SQL语句不同。通常相同部分的SQL语句具有一定的子查询功能。虽然在数据库模板中该相同功能的SQL语句不完全相同,但在这些SQL语句中相同的SQL语句可以在通用模板中定义,数据库模板中SQL语句对通用模板中的模板变量进行引用即可。
举一个具体的例子,假设功能标识salary.top10对应的功能为:取第2部门的所有员工中薪金最高的前10个人。在SQL Server数据库中,salary.top10对应的SQL语句为:select top10employee.employee_id from(select*from tbl_employee where department_no=2)employee order byemployee.salary desc。在Oracle数据库中,salary.top10对应的SQL语句为:select employee.employee_id from(select*from tbl_employee wheredepartment_no=2)employee where rownum<=10order by employee.salarydesc。
其中,两个SQL语句中具有相同的部分,即select*from tbl_employeewhere department_no=2,该相同的部分用于完成查询第2部门员工的子查询功能。在此,可以将该相同的部分定义在通用语句模板中,并采用模板变量employee.department进行表示,例如表示为:employee.department=(select*from tbl_employee where department_no=2)。然后分别在SQL Server数据库和Oracle数据库的SQL语句中进行引用,分别表示为:salary.top10=select top10employee.employee_id from${employee.department}employee order byemployee.salary desc以及salary.top10=select employee.employee_id from${employee.department}employee where rownum<=10order byemployee.salary desc。
这种形式下,对数据库模板中的SQL语句进行解析时,如果解析到的SQL语句引用了通用语句模板中的功能表示,则利用被引用的功能标识(即模板变量)在通用语句模板中对应的SQL语句替换该解析到的SQL语句中引用功能标识的部分。在上述例子中,解析到salary.top10对应的SQL语句时,将通用语句模板中select*from tbl_employee where department_no=2的SQL语句替换salary.top10对应的SQL语句中的${employee.department}即可。
步骤202:访问数据库的装置启动后,加载所有模板。
本步骤在图2所示的模板控制中间层执行,按照指定的安装目录从SQL模板层中读取全部模板至内存中。
步骤203:将各模板中的SQL语句进行解析和整合,分别得到各数据库类型对应的结果集,结果集中包含对应数据库的所有SQL语句以及SQL语句对应的功能标识。
在本步骤中,按照加载的各模板的中的定义,将各模板都解析成SQL语句对应功能标识的形式。如果模板中存在对模板变量的引用,则SQL语句中会包含模板变量。
如果加载的各模板均为数据库模板,即不存在通用语句模板(对应步骤201中的第一种形式),则直接通过上述解析过程即可获得各类型数据库的SLQ语句集合。
如果加载的各模板中还包括通用语句模板,则在解析之后还会包含整合过程,通过通用语句模板中SQL语句引用的模板变量来整合各数据库的SQL语句。各数据库的结果集除了从对应数据库模板中解析出的内容之外,还可能包含通用语句模板中的内容。对通用语句模板中的各SQL语句进行遍历,对遍历到的SQL语句执行以下操作:
如果当前遍历到的SQL语句没有引用模板变量(对应步骤201中的第二种形式),则将该SQL语句及其功能标识分别添加到各数据库的结果集中;其中在添加时,如果数据库中已经存在要添加的功能标识(对应步骤201中的第四种形式),则不执行添加操作;如果不存在要添加的功能标识,则执行添加操作。
如果当前遍历到的SQL语句引用模板变量(对应步骤201中的第三种形式),则在各数据库的结果集中查找该模板变量,并在查找到该模板变量的结果集中,将该SQL语句对应的功能标识替换查找到的模板变量,并将当前遍历到的SQL语句及其对应的功能标识添加到没有查找到该模板变量的结果集中。
步骤204:当接收到调用方的调用指令时,确定当前连接的数据库类型,并获取当前连接的数据库类型对应的结果集。
本步骤在图2所示的SQL执行层执行。当需要对数据库进行访问时,必先建立与数据库之间的连接,因此,访问数据库的装置在接收到调用方的调用指令时,首先确定当前连接的数据库类型,然后从模板控制中间层获取当前连接的数据库类型对应的结果集。
步骤205:根据调用指令中包含的功能标识,在获取的结果集中查询调用指令中携带的功能标识对应的SQL语句。
在本发明中,调用方不需要对数据库类型进行区分,只需要对数据库访问的功能进行调用,即将包含功能标识的调用指令发送给SQL执行层。由以上描述可以看出,功能标识并没有对数据库类型进行区分。
在步骤204中已经获取了要访问的数据库的所有SQL语句构成的结果集,在该结果集中查询出调用指令中携带的功能标识对应的SQL语句,该SQL语句就是对要访问的数据库执行访问操作对应的SQL语句。
步骤206:利用调用指令中的访问参数对查询的SQL语句进行赋值后,执行SQL语句以实现对数据库的访问。
在调用指令中还可以包含访问参数,利用该访问参数对SQL语句中的访问变量进行赋值。例如,当功能标识对应的访问操作是查询前N个数据时,访问参数可以是具体的N值。
另外,在该赋值过程中,除了对SQL语句中访问变量进行赋值外,还可以包含形式变更以适应SQL语法的需要。例如,当访问变量为字符串时,自动在字符串前后加上单引号;当访问变量为列表或数组时,自动转换成在各数据之间用逗号分隔的形式。
在对SQL语句完成赋值后,执行该SQL语句。如果需要进一步返回查询结果,则可以向调用方返回对数据库的访问结果。
以上是对本发明所提供的方法进行的详细描述,下面对本发明所提供的数据库访问装置进行详细描述。图3为本发明提供的装置结构图,如图3所示,该装置可以包括:SQL模板单元300、模板控制单元310和SQL执行单元320。
SQL模板单元300,用于存储多种类型的数据库模板,每种类型的数据库模板中包含该类型数据库的SQL语句以及SQL语句对应的功能标识,数据库模板中具有相同功能的SQL语句对应相同的功能标识。
模板控制单元310,用于在装置启动后,加载SQL模板单元300中存储的所有模板。
SQL执行单元320,用于接收到调用指令后,确定当前连接的数据库类型对应的所有SQL语句构成的结果集,在结果集中查询调用指令包含的功能标识对应的SQL语句,执行该SQL语句以实现对数据库的访问。
SQL执行单元320可以接收调用方的调用指令,在执行SQL语句实现对数据库的访问后,还可以进一步将访问结果返回给调用方。
上述的SQL模板单元300、模板控制单元310和SQL执行单元320对应图2中的SQL模板层、模板控制中间层和SQL执行层。
其中,模板控制单元310可以包括:模板加载子单元311、模板解析子单元312和结果处理子单元313。
模板加载子单元311,用于在装置启动后,加载所有模板。
模板解析子单元312,用于对加载的所有模板中的SQL语句进行解析。
结果处理子单元313,用于根据解析结果,分别得到各数据库类型对应的结果集,结果集中包含对应数据库的所有SQL语句以及SQL语句对应的功能标识。
更优地,为了对多种类型数据库的相同SQL语句进行复用,SQL模板单元300还存储通用语句模板,通用语句模板中包含多种类型数据库相同的SQL语句以及SQL语句对应的功能标识。
这种情况下,模板控制单元310还可以包括:语句整合子单元314,用于对解析得到的通用语句模板中的各SQL语句进行遍历,将遍历到的SQL语句及其功能标识分别添加到各数据库类型对应的结果集中。
为了最大限度的复用SQL语句,通用语句模板中的SQL语句可以引用数据库模板中的功能标识,其中,被引用的功能标识对应的SQL语句与引用该功能标识的SQL语句具有相同功能。
这种情况下,语句整合子单元314可以具体包括:语句遍历模板3141、第一判断模块3142、添加处理模块3143和标识查找模块3144。
语句遍历模块3141,用于对解析得到的通用语句模板中的各SQL语句进行遍历。
第一判断模块3142,用于判断当前遍历到的SQL语句是否引用了其它功能标识,如果否,向添加处理模块3143发送第一处理通知;如果是,将被引用的功能标识发送给标识查找模块3144。
添加处理模块3143,用于接收到第一处理通知后,将遍历到的SQL语句及其功能标识分别添加到各数据库类型对应的结果集中;接收到第二处理通知后,将当前遍历到的SQL语句及其对应的功能标识添加到没有查找到被引用的功能标识的结果集中。
标识查找模块3144,用于接收到所述被引用的功能标识后,在各数据库类型对应的结果集中查找被引用的功能标识,将查找到被引用的功能标识的结果集中,将当前遍历到的SQL语句对应的功能标识替换查找到的结果集中被引用的功能标识,并向添加处理模块3143发送第二处理通知。
更进一步地,当SQL模板单元300中新增一种类型的数据库模板时,如果新增的数据库模板中存在与通用语句模板中具有相同功能的不同SQL语句时,该具有相同功能的不同SQL语句采用相同的功能标识。
这种情况下,语句整合子单元314还可以进一步包括:第二判断模块3145,用于在添加处理模块3143在将遍历到的SQL语句及其功能标识添加到结果集中之前,判断要添加到的结果集中是否已经存在要添加的功能标识,如果是,则禁止添加处理模块3143将遍历到的SQL语句及其功能标识添加到结果集中,否则,允许添加处理模块3143将遍历到的SQL语句及其功能标识添加到结果集中。
还有一种情况,数据库模板中的SQL语句可以引用通用语句模板中的功能标识。模板解析子单元312在对数据库模板中的SQL语句进行解析时,如果解析到的SQL语句引用了通用语句模板中的功能标识,则利用被引用的功能标识在通用语句模板中对应的SQL语句替换解析到的SQL语句中引用功能标识的部分。
另外,上述SQL执行单元320可以具体包括:类型确定子单元321、语句查询子单元322、变量赋值子单元323和语句执行子单元324。
类型确定子单元321,用于接收到调用指令后,确定当前连接的数据库类型对应的所有SQL语句构成的结果集。
语句查询子单元322,用于在类型确定子单元321确定的结果集中,查询调用指令包含的功能标识对应的SQL语句。
变量赋值子单元323,用于利用调用指令中的访问参数对语句查询子单元322查询到的SQL语句进行赋值。
语句执行子单元324,用于执行赋值后的SQL语句以实现对数据库的访问。
由以上描述可以看出,本发明提供的方法和装置可以具备以下优点:
1)本发明通过模板的形式保存各数据库的SQL语言及其对应功能标识,各数据库模板中具有相同功能的SQL语句对应相同的功能标识,使得在调用方进行功能调用时,无需对数据库类型进行调用,仅需要通过调用指令发送要访问的操作对应的功能标识,数据库访问装置便能够从当前连接的数据库类型对应的所有SQL语句构成的结果集中,查询出该功能标识对应的SQL语句,并执行该SQL语句以实现数据库的访问。可以看出,本发明能够在调用方屏蔽数据库的类型差异,降低调用方操作的复杂度。
2)在本发明中通过设置通用语句模板来存储多种类型数据库相同的SQL语句及其对应的功能标识,并可以进一步结合功能标识作为模板变量的引用功能,最大限度地复用各类型数据库中相同的SQL语句。
3)当在数据库访问装置支持新的类型的数据库时,在数据库访问装置中新增对应的数据库模板,当新增的数据库模板中存在与通用语句模板中具有相同功能的不同SQL语句时,采用与通用语句模板中相同的功能标识,并且在对该数据库执行该功能标识时,采用该数据库模板中该功能标识对应的SQL语句。这种渐进式的增加方式,使得在新增加模板时,不会对已有模板中的内容产生影响。
4)采用模板的方式定义各数据库的SQL语句,相比较在代码中编写各数据库的SQL语句的方式,在进行修改和维护时仅需要对模板中的定义进行变更而不必修改已有代码,使得修改和维护更加简单和方便。
5)在各模板中采用功能标识对SQL语句进行标识,并对各数据库模板中具有同一功能的SQL语句采用相同的功能标识,增强了SQL语句的可阅读性。
以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明保护的范围之内。