基于对象关系映射的数据处理方法和数据处理装置与流程

文档序号:29406373发布日期:2022-03-26 10:44阅读:68来源:国知局
1.本发明涉及数据库
技术领域
:,特别涉及基于对象关系映射(objectrelationmapping,缩写为orm)的数据处理方法和数据处理装置。
背景技术
::2.随着软件系统的复杂化,已经开发出多种软件生产技术以提高开发效率、质量和可靠性,这些软件生产技术包括组件技术、可视编程、模式和框架。框架是复杂软件系统的一部分子系统的设计和实现。在框架基础上进行二次开发,可以重用于类似应用场景的不同软件系统中。3.在数据库的应用中,对象关系映射(objectrelationmapping,缩写为orm)的作用是通过使用描述对象和数据库之间映射的元数据,将关系数据库中的数据转换成程序中的对象,或者,将程序中的对象自动持久化到关系数据库中。4.在主流的持久化框架中,例如,hibernate、mybatis、springdatajdbc,均实现了对象关系映射。5.hibernate是一个全表映射的框架,自动化程度较高,对于java对象到单个数据表的映射和转换非常方便,只需要定义java对象和映射关系(java对象的字段与数据表的列的映射关系),甚至无需编写查询用sql。但其对多表关联的支持比较差。也正是由于自动化程度较高,所以自定义的灵活性相对较弱。6.相对于hibernate而言,mybatis是一个半自动映射的框架,需要手动匹配java对象、sql和映射关系。因为需要手动编写sql,所以其灵活性较强。但是,其映射关系的配置都是需要手动配置xml文件来完成,这样不仅会增加操作复杂度,也会使配置变得很庞杂。7.springdatajdbc框架则提供了一个简单的转换机制,开发者只需要定义java对象和sql,结果集到java对象的转换由一个beanpropertyrowmapper的工具来完成,其实现将结果集中的一行转换为javabean。其靠的是推测数据库数据库结构中的列名与java对象类的属性中变量名的对应关系。例如:依据数据库结构中的列名biz_type,推测出java对象类的变量名为biztype。该框架在灵活性和操作复杂度方面,相比hibernate和mybatis较为适中,自定义sql无论是单表还是多表连接都可支持,无需定义大量的映射配置文件,简化操作,可以满足大多数转换场景。8.springdatajdbc框架的主要缺陷是对结果集中数据列的列名和java对象类的属性中,变量名的规范性(命名规范)依赖较强,一旦列名与对象类的变量名不按照规范,则匹配就会失败,导致转换失败。例如,对于列名“reverse_1”,java对象类的变量名为“reverse1”;对于列名is_force(是否强制),java对象类的变量名为“force”时(按照规范对于布尔字段,不能是isforce)。9.因此,期望开发出可以简化映射配置且适应性强的对象关系映射框架技术。技术实现要素:10.鉴于上述问题,本发明的目的在于提供一种基于对象关系映射的数据处理方法和数据处理装置,其中,根据类属性中的映射注解的类型执行多个映射方法中的至少一个,以简化映射配置以及提高映射的灵活性和成功率。11.根据本发明的第一方面,提供一种基于对象关系映射的数据处理方法,包括:定义java对象类;对所述java对象类进行解析以获取类属性;对数据库进行查询以获得结果集;对所述结果集的元数据进行解析以获取数据列属性;根据所述类属性建立映射关系;以及根据所述映射关系,将所述结果集映射为所述java对象类的实例列表,其中,在建立映射关系时,根据所述类属性中的映射注解的类型执行多个映射方法中的至少一个。12.优选地,所述多个映射方法包括第一映射方法和第二映射方法,在所述类属性包括映射注解的情形下,执行所述第一映射方法,所述第一映射方法根据所述映射注解获得所述类属性相对应数据列的列名,以及在所述类属性未包括映射注解的情形下,执行所述第二映射方法,所述第二映射方法根据所述类属性中的变量名获得所述类属性相对应数据列的列名。13.优选地,所述多个映射方法还包括第三映射方法,在采用所述第一映射方法和所述第二映射方法未能成功获得所述类属性相对应数据列的列名的情形下,执行所述第三映射方法,所述第三映射方法包括:根据所述数据列属性中的列名推测列别名;采用所述第一映射方法和所述第二映射方法获得所述类属性相对应的数据列别名;以及根据所述列别名与所述列名的对应关系获得所述类属性相对应的数据列名。14.优选地,所述推测的步骤包括:根据所述类属性中的变量名的命名规范,对所述数据列属性中的列名进行字符串替换以获得列别名。15.优选地,在程序运行时利用java系统的反射机制获得所述类属性,所述类属性包括:变量名、数据类型、和映射注解至少之一。16.优选地,所述映射注解包括保留字、注解名和多个注解成员,其中,所述多个注解成员至少包括列名。17.优选地,根据所述注解名执行相应的注解规范的映射方法。18.优选地,所述多个注解成员还包括变量注释。19.优选地,将所述结果集映射为所述java对象类的实例列表的步骤包括:建立列表;逐行读取所述结果集以获得行数据;将所述行数据转换成java对象类的实例;以及将所述java对象类的实例添加至列表。20.优选地,将所述行数据转换成java对象类的实例的步骤包括:构建java对象类的实例;将所述java对象类中的变量设置为默认值;根据映射关系,获得与所述变量对应的别名;采用列读取方法,从所述结果集的行数据读取列值;以及将所述java对象类的变量设置为相应的列值。21.优选地,在从所述结果集的行数据读取列值的步骤之前,还包括:获取所述java对象类中的变量数据类型、以及所述结果集中相应数据列的数据类型;以及根据所述数据类型选择所述列读取方法。22.优选地,在所述java对象类中的变量数据类型为字符型、数值型和时间型之一时,根据所述类属性数据类型选择相应的列读取方法,从所述结果集的行数据读取列值。23.优选地,在所述类属性数据类型为日期型时,根据所述数据列的数据类型选择相应的列读取方法。24.优选地,选择相应的列读取方法的步骤包括:如果所述数据列的数据类型为日期时间型,则选择时间戳型的列读取方法,如果所述数据列的数据类型为日期型,则选择按日期型的列读取方法,如果所述数据列的数据类型为时间戳型,则选择时间戳型的列读取方法,以及如果所述数据列的数据类型为时间型,则选择时间型的列读取方法。25.优选地,在所述类属性数据类型为布尔型时,根据所述数据列的数据类型选择相应的列读取方法和数据转换方法。26.优选地,选择相应的列读取方法和数据转换方法的步骤包括:如果所述数据列的数据类型为布尔型,则选择布尔型的列读取方法,如果所述数据列的数据类型为整型,则选择整型的列读取方法,以及将读取的列值转换成布尔量,以及如果所述数据列的数据类型为字符型,则选择字符型的列读取方法,以及将读取的列值转换成布尔量。27.根据本发明的第二方面,提供一种基于对象关系映射的数据处理装置,包括:调用模块,用于提供数据库查询接口和java对象类的实例列表接口,经由所述数据库查询接口执行数据库查询以获得结果集;java对象解析模块,用于对java对象类进行解析以获取类属性;结果集元数据解析模块,用于对所述结果集的元数据进行解析以获取数据列属性;结果集读取模块,用于逐行读取所述结果集以获得行数据;以及结果集映射模块,用于根据所述类属性建立映射关系,以及,将所述结果集映射为所述java对象类的实例列表,其中,在建立映射关系时,根据所述类属性中的映射注解的类型执行多个映射方法中的至少一个。28.根据本发明实施例的数据处理方法,在定义java对象类时,根据所述类属性建立映射关系,无需额外的映射配置步骤,因此可以简化映射配置过程。29.优选地,如果java对象类的变量名与数据列的列名相同,则在java对象类中无需添加任何映射注解,可以直接将变量名映射为数据列的列名,因此可以进一步简化映射配置过程。30.根据本发明实施例的数据处理方法,在java对象类中可以采用多个映射方法。例如,java对象类的一部分变量名可以采用变量名的直接映射,另一部分变量名采用映射注解映射。根据映射注解的注解名执行相应的注解规范的映射方法。即使java对象类的变量名与数据列的列名存在着差异,也可以在简化映射配置过程的同时提高映射的灵活性和成功率。31.优选地,采用列读取方法,从所述结果集的行数据读取列值。在读取列值之前,获取所述java对象类中的变量数据类型、以及所述结果集中相应数据列的数据类型,以及根据所述数据类型选择所述列读取方法。该选择的列读取方法可以保证数据的完整性和正确性。32.优选地,采用本发明提出的注解规范,在映射注解中还可以包括变量注释,因而可以在映射过程提供附加的变量信息,进一步地,提高映射的灵活性和成功率、以及数据完整性和准确性。附图说明33.通过以下参照附图对本发明实施例的描述,本发明的上述以及其他目的、特征和优点将更为清楚,在附图中:图1示出根据本发明第一实施例的数据处理方法的流程图。34.图2示出根据本发明第二实施例的数据处理装置的示意性框图。具体实施方式35.以下将结合附图所示的具体实施方式对本发明进行详细描述。但这些实施方式并不限制本发明,本领域的普通技术人员根据这些实施方式所做出的结构、方法、或功能上的变换均包含在本发明的保护范围内。36.图1示出根据本发明第一实施实施的数据处理方法的流程图。37.在步骤s01中,定义java对象类。38.该java对象类包括多个类属性,每个类属性包括:变量名、数据类型、和映射注解至少之一。java对象类中的映射注解利用了java对象类的注解语法。注解语法包括保留字@、注解名以及至少一个成员,每个成员表示为键值对。39.在本实施例中,映射注解用于描述至少一些类属性的映射关系。映射注解采用自定义规范,并且还兼容标准orm接口,即,jpa(javapersistenceapi)规范。40.在自定义规范中,映射注解定义元数据,该元数据包括保留字@、注解名vocolumn、以及多个注解成员。所述多个注解成员例如包括数据列的列名和变量注释。每个注解成员采用键值对表示,例如,数据列的列名的键名是col,变量注释的键名为comment。以下为布尔型类属性hassys的映射注解和变量定义。41.@vocolumn(col="has_sys",comment="是否有系统账号(1是0否)")privatebooleanhassys=false;在jpa规范中,映射注解定义元数据,该元数据包括保留字@、注解名column、以及多个注解成员。所述多个注解成员例如包括多个数据列属性。每个注解成员采用键值对表示。例如,数据列的列名的键名是name,是否允许为空的键名是nullable。以下为字符串型类属性name的映射注解和变量定义。42.@column(name="personname",unique=true,nullable=false,updatable=true)privatestringname;其中,数据列属性包括,name:列名,unique:是否唯一,nullable:是否允许为空,insertable:是否允许插入,updatable:是否允许更新,columndefinition:定义建表时创建此列的ddl,secondarytable:从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。43.在下文的java对象类patient中,分别定义了病人的姓名、系统账号、预留字段、和创建时间戳的变量名,分别为name、hassys、reserve1、createtsp。姓名name和创建时间戳createtsp为简单类属性,未包括映射注解,系统账号hassys和预留字段reserve1为复杂类属性,分别还包括各自的映射注解。44.publicclasspatient{ꢀꢀꢀꢀꢀꢀꢀ/**ꢀꢀ姓名*/ꢀꢀꢀꢀꢀꢀꢀprivatestringname=null;ꢀꢀꢀꢀꢀꢀꢀ@vocolumn(col="has_sys",comment="是否有系统账号(1是0否)")ꢀꢀꢀꢀꢀꢀꢀprivatebooleanhassys=false;ꢀꢀꢀꢀꢀꢀꢀ@vocolumn(col="reserve_1",comment="预留字段1")ꢀꢀꢀꢀꢀꢀꢀprivatestringreserve1="";ꢀꢀꢀꢀꢀꢀꢀ/**ꢀꢀ记录创建时间戳*/ꢀꢀꢀꢀꢀꢀꢀprivatedatecreatetsp=null;ꢀꢀꢀꢀꢀꢀꢀ……}在本实施例中,java对象类的简单类属性和复杂类属性是根据变量名与数据列的列名的映射关系定义的。如果java对象类的变量名与结果集中数据列的列名相同,则为简单类属性,如果java对象类的变量名与结果集中数据列的列名不同,则为复杂类属性。java对象类中的复杂类属性包括映射注解,从而定义变量名与列名的对应关系。45.在本实施例中,类属性中的映射注解采用自定义规范。与jpa规范相比,自定义规范修改了映射注解的映射名、以及注解成员中的键名。进一步地,注解成员不仅包括数据列属性的键值对,还包括变量注释的键值对,因而可以在映射过程提供附加的变量信息,提高映射的灵活性和成功率、以及数据完整性和准确性。46.在上述的java对象类patient中,还使用了java支持的注释语句。该注释语句以“/*”开始,以“*/”结束,用于指示编译器忽略从/*到*/的所有内容。与注释语句不同,映射注解定义了变量名与列名的对应关系,编译器根据对应关系实现二者之间的映射,因此,映射注解仍然是有效的执行语句。47.在步骤s02中,对java对象类进行解析以获取类属性。48.java系统的特点是在程序行前对java对象类进行编译,在程序运行时动态加载经过编译的java对象类。因此,在程序运行时,不能直接从java对象类的静态定义中获得类属性。java系统还提供了反射机制,可以在程序运行时利用反射机制获得类属性,包括:变量名、数据类型、映射注解等。49.例如,利用java系统的反射机制可以获得java对象类patient中的系统账号的类属性,包括:变量名hassys,数据类型boolean,以及映射注解的两个成员:col="has_sys",comment="是否有系统账号(1是0否)"。50.在步骤s03中,对数据库进行查询以获得结果集。51.对数据库进行查询包括生成sql语句和执行sql语句的步骤。sql语句可以是预先编写的完整语句。优选地,采用上下文参数(即,查询条件参数)填充sql模板中的占位符生成完整的sql语句。52.在本实施例中,采用标准的jdbcapi(即,java数据库连接接口)对数据库进行访问。在执行sql语句之前,建立数据库连接。然后数据库执行sql语句,从数据库返回结果集。在执行sql语句之后,关闭数据库连接。结果集至少包括一个数据行的行数据。每个行数据包括多个列值。53.在步骤s04中,对结果集的元数据进行解析以获取数据列属性。54.在jdbcapi中提供了元数据解析方法以获得结果集的元数据,该元数据表示成resultsetmetadata类,包括多个数据列属性,例如:列名、列备注、是否可为空、数据类型、显示大小、数值长度(类型为数值时)、小数位数(类型为数值时)等。55.在步骤s05中,根据类属性建立映射关系。56.根据映射注解的类型,java对象类中的映射方法分为三种类型:a)如果映射注解的注解名为vocolumn,则判断类属性为复杂类属性,并且采用了自定义规范的映射注解,将映射注解中的成员col的值作为列名;b)如果映射注解的注解名为column,则判断类属性为复杂类属性,并且采用了jpa规范的映射注解,将映射注解中的成员name的值作为列名;c)如果未使用映射注解,则判断类属性为简单类属性,以及将变量名作为默认的列名。57.上述java对象类patient的映射关系如下表所示。58.表1、变量名与列名的映射关系变量名列名映射方法namename方法c)hassyshas_sys方法a)reserve1reserve_1方法a)createtspcreatetsp方法c)在步骤s06中,根据所述映射关系,将结果集映射为java对象类的实例列表。59.该映射过程包括建立列表、逐行读取结果集以获得行数据、将行数据转换成java对象类实例、以及将java对象类实例添加至列表。60.在本实施例中,采用标准的jdbcapi(即,java数据库连接接口)访问结果集。jdbcapi提供了行游标和列读取方法。在读取结果集中与行游标对应的一行数据后,移动行游标至下一行。每个行数据包括多个列值。逐行读取结果集的行数据,可以遍历结果集读取全部行数据。61.在本实施例中,在读取查询结果的行数据之后,构建java对象类实例,以及将变量设置为默认值。进一步地,对于java对象类中的每个类属性,根据变量名与列名的对应关系,从查询结果的行数据中获取与奕量名相应数据列的列值,以及,将变量设置为相应数据列的列值。62.对象关系映射(objectrelationmapping,缩写为orm)是否成功的关键是行数据的多个列名是否匹配相对应的变量名。为了提高映射成功率,进一步补充了映射方法d):根据列名推测列别名,根据映射方法a)至c)获得变量名与列别名的映射关系,因而可以进一步提高变量名与列名匹配的成功率。63.根据列名推测列别名的方法包括:根据变量名的命名规范,对列名进行字符串替换以获得列别名。例如,在java对象类的变量名包括多个单词时,按照变量名的命名规范,多个单词直接拼接在一起,并且第二个单词开始首字母大写。对于结果集中数据列的列名中的多个单词以下划线分割的情形,例如,列名create_tsp,将下划线替换成空字符串,将第二个单词开始首字母替换成大写,可以获得列别名createtsp。64.在上述java对象类patient中,假设数据库查询获得的结果集中数据列的列名分别为:name、has_sys、reserve_1、create_tsp,采用上述映射方法a)至c),java对象类patient的变量名createtsp不能成功匹配结果集中数据列的列名create_tsp。然而,采用映射方法d)可以获得结果集中数据列的列名create_tsp的列别名createtsp,通过java对象类patient的变量名createtsp与列别名createtsp的匹配关系,实现java对象类patient的变量名createtsp与结果集中数据列的列名create_tsp的成功匹配。65.上述java对象类patient的映射关系如下表所示。66.表2、列名与变量名的映射关系列名变量名映射方法是否成功namename方法c)成功has_syshassys方法a)成功reserve_1reserve1方法a)成功create_tspcreatetsp方法d),推测列别名为createtsp成功结合表1和表2,根据该实施例的数据处理方法,可以适用于对象关系映射的大部分场景,例如:name、gender等单个单词组成的列名,或biz_type,create_time等多个单词组成的列名,也可以支持复杂场景,例如:数据库结构中的列名与java对象类中的变量名含义相去甚远的情况。67.在本实施例中,在获取据变量名与列名的对应关系之后,根据变量名与列名的对应关系,从查询结果的行数据中获取与变量名相应数据列的列值。68.jdbcapi提供了与数据类型相关的列读取方法。在从查询结果的行数据中获取java对象类相应的列值之前,还需要获取java对象类中的变量和数据库结构中的数据列的数据类型,以及,根据数据类型选择相应的列读取方法。该选择的列读取方法可以保证数据的完整性和正确性。69.如果变量的数据类型为第一组数据类型:字符型(char或varchar)、数值型(int或integer、long或long、double或double、float或float、bigdecimal)、时间型(time),直接按类属性中的数据类型对应的列读取方法获得列值即可。例如:数值型中的整型就采用jdbcapi中的getint方法读取,字符串就采用jdbcapi中的getstring读取。70.如果变量的数据类型为第二组数据类型:日期型(date),结合列的数据类型选择列读取方法,否则会产生精度丢失的问题。71.如果列的数据类型为日期时间型(datetime),则按时间戳型的列读取方法gettimestamp获得列值。72.如果列的数据类型为日期型(date),则按日期型的列读取方法getdate获得列值。73.如果列的数据类型为时间戳型(timestamp),则按时间戳型的列读取方法gettimestamp获得列值。74.如果列的数据类型为时间型(time),则按时间型的列读取方法gettime获得列值。75.如果变量的数据类型为第三组数据类型:布尔(boolean或boolean),结合列的数据类型选择列读取方法和数据转换方法,否则会产生数据错误的问题。76.如果列的数据类型为布尔型(boolean),则按布尔型的列读取方法getboolean获得列值,以及将所述变量设置为列值。77.如果列的数据类型为整型(int),则按整型的列读取方法getint获得列值,然后将列值的数值转换成布尔量。在列值的数值等于1时表示布尔量true,在列值的数值不等于1时表示布尔量false。78.如果列的数据类型为字符型(char或varchar),则按字符型的列读取方法getstring获得列值,然后将列值的字符串转换成布尔量。在列值的字符串等于“1”时表示布尔量true,在列值的字符串不等于“1”时表示布尔量false。79.图2示出根据本发明第二实施例的数据处理装置的示意性框图。80.数据处理装置100包括调用模块101、java对象类解析模块102、结果集元数据解析模块103、结果集读取模块104、结果集映射模块105。81.调用模块101提供数据库查询接口和java对象类的实例列表接口,经由数据库查询接口执行数据库查询以获得结果集。java对象解析模块102对java对象类进行解析以获取类属性。结果集元数据解析模块103对结果集的元数据进行解析以获取数据列属性。结果集读取模块104用于逐行读取结果集以获得行数据。结果集映射模块105根据类属性建立映射关系,以及,将结果集映射为java对象类的实例列表。82.在建立映射关系时,结果集映射模块105根据类属性中的映射注解的类型执行多个映射方法。83.在类属性包括映射注解的情形下,执行第一映射方法,第一映射方法根据映射注解获得类属性相对应数据列的列名。在类属性未包括映射注解的情形下,执行第二映射方法,第二映射方法根据类属性的变量名获得类属性相对应数据列的列名。在采用第一映射方法和第二映射方法未能成功获得类属性相对应数据列的列名的情形下,执行第三映射方法。第三映射方法包括:根据结果集的数据列属性中的列名推测列别名;采用第一映射方法和第二映射方法获得类属性相对应的数据列别名;以及根据列别名与列名的对应关系获得类属性相对应的数据列名。84.以上所描述的装置实施方式仅仅是示意性的,其中所述作为分离部件说明的模块可以是或者也可以不是物理上分开的,作为模块显示的部件可以是或者也可以不是物理模块,即可以位于一个地方,或者也可以分布到多个网络模块上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施方式方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。85.应当理解,虽然本说明书按照实施方式加以描述,但并非每个实施方式仅包含一个独立的技术方案,说明书的这种叙述方式仅仅是为清楚起见,本领域技术人员应当将说明书作为一个整体,各实施方式中的技术方案也可以经适当组合,形成本领域技术人员可以理解的其他实施方式。86.上文所列出的一系列的详细说明仅仅是针对本发明的可行性实施方式的具体说明,它们并非用以限制本发明的保护范围,凡未脱离本发明技艺精神所作的等效实施方式或变更均应包含在本发明的保护范围之内。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1