一种数据导出方法及装置
技术领域
本说明书一个或多个涉及计算机领域,尤其涉及一种数据导出方法及装置。
背景技术
目前,随着互联网技术的快速发展,在业务处理过程产生的数据量越来越多,因此,存入数据库的数据量也越来越多,并且在各业务***中,均会存在从数据库中导出数据至Excel文件中的诉求。
当前,现有技术中提供的数据导出并生成Excel报表的过程具体为:首先,采用将全部数据批量查询到JVM堆区内存中,然后,再将其保存并生成Excel文件。在此过程中,由于会在内存中保存全部的数据,当需要导出的数据量比价大时,JVM内存无法存放下如此多的数据量,将会导致OOM内存溢出问题,且会导致频繁的GC回收,势必将严重影响***的性能和可用性。
针对上述问题,现有技术中还提供了采用分页导出的方式实现数据导出并生成Excel报表,具体的,通过SQL语句对数据进行物理查询分页,控制每一次查询的数据量,当处理完当前分页数据之后,再将其删除回收内存,然后再进行下一个分页数据的处理。在此过程中,需要多次查询数据,且必须要SQL语句存在唯一键排序;因此,在多次查询及排序分页的操作,当导出期间数据发生新增、修改、删除等数据变更的情况时,将导致导出的数据出现重复、缺失的情况。
由此可知,需要提供一种能够保证数据完整性和准确性的数据导出方法。
发明内容
本说明书一个或多个实施例的目的是提供一种数据导出方法及装置,不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
为解决上述技术问题,本说明书一个或多个实施例是这样实现的:
本说明书一个或多个实施例提供了一种数据导出方法,包括:
利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;
针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
依次将所述目标数据写入预设数据队列中,以使利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据,基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例提供了一种数据导出装置,包括:
数据获取模块,用于利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;并针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
数据写入模块,用于利用所述第一线程依次将所述目标数据写入预设数据队列中;
数据读取模块,用于利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据;
文件生成模块,用于利用所述第二线程基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例提供了一种数据导出设备,包括:处理器;以及
被安排成存储计算机可执行指令的存储器,所述可执行指令在被执行时使所述处理器:
利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;
针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
依次将所述目标数据写入预设数据队列中,以使利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据,基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例提供了一种存储介质,用于存储计算机可执行指令,所述可执行指令在被执行时实现以下流程:
利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;
针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
依次将所述目标数据写入预设数据队列中,以使利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据,基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例中的数据导出方法及装置,首先,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
附图说明
为了更清楚地说明本说明书一个或多个实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本说明书一个或多个中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1为本说明书一个或多个实施例提供的数据导出方法的流程示意图;
图2为本说明书一个或多个实施例提供的数据导出方法的第一种实现原理示意图;
图3为本说明书一个或多个实施例提供的数据导出方法的第二种实现原理示意图;
图4为本说明书一个或多个实施例提供的数据导出方法的第三种实现原理示意图;
图5为本说明书一个或多个实施例提供的数据导出方法的第四种实现原理示意图;
图6为本说明书一个或多个实施例提供的数据导出方法的第五种实现原理示意图;
图7为本说明书一个或多个实施例提供的数据导出装置的模块组成示意图;
图8为本说明书一个或多个实施例提供的数据导出设备的结构示意图。
具体实施方式
为了使本技术领域的人员更好地理解本说明书一个或多个中的技术方案,下面将结合本说明书一个或多个实施例中的附图,对本说明书一个或多个实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本说明书一个或多个一部分实施例,而不是全部的实施例。基于本说明书一个或多个中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书一个或多个保护的范围。
本说明书一个或多个实施例提供了一种数据导出方法及装置,不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
图1为本说明书一个或多个实施例提供的数据导出方法的流程示意图,图1中的方法的执行主体为计算机设备,如图1所示,该方法至少包括以下步骤:
S101,利用第一线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
具体的,上述静态游标数据集是指基于静态游标的方式获取到的数据库快照,其中,静态游标是以游标打开时刻的当时状态显示结果集的游标,静态游标在游标打开时不反映对基础数据进行的更新、删除或***;静态游标在打开时会将数据集存储在tempdb中,因此显示的数据与游标打开时的数据集保持一致,在游标打开以后对数据库的更新不会显示在游标中,例如,JDBC游标,JDBC游标是指JDBC查询操作返回的一种可以处理一行或一部分行的数据结果集;
另外,上述指定时刻可以是查询时刻,该数据库快照记载查询时刻数据库存储的行集数据的标识信息(即数据标识),数据库快照不会随着数据库存储的数据的变更而变化,因此,基于数据库快照中的多个数据标识,从数据库中获取到的数据不会出现数据重复、数据缺失的情况;
S102,针对数据库快照中的每个数据标识,利用第一线程从数据库中依次获取与该数据标识对应的目标数据;
其中,上述数据库快照记载查询时刻数据库存储的多个行集数据分别对应的数据标识,在数据库中依次查询与每个数据标识对应的目标数据;具体的,采用JDBC游标的方式,获取到游标数据集,使用游标数据集的方式进行数据读取,不需要一次性返回全部的行集对象,不需要将大量数据堆积于JVM内存中,可以实现以流式导出的方式导出数据;
S103,利用第一线程依次将获取到的目标数据写入预设数据队列中,以使利用第二线程从预设数据队列中按照先进先出顺序依次读取目标数据,基于读取到的目标数据生成数据导出文件;
其中,第一线程可以称为生产者线程,第二线程可以称为消费者线程,第一线程和第二线程是并行执行的两个相互独立的线程;具体的,第一线程在从数据库中获取到对应的目标数据后,将该目标数据按序入队,即存入预设数据队列中,以便第二线程能够从该预设数据队列中按序读取目标数据;
其中,通过独立的生产者线程执行SQL语句,从数据库中采用JDBC只进只读静态游标的方式,读取查询时刻时的数据库快照,其中,数据读取期间不能中断session会话链接。再基于数据库快照逐一从数据库中获取目标数据,将该目标数据依次存放在预设数据队列中;同时,消费者线程从该预设数据队列中读取目标数据;
具体的,生产者线程基于数据库快照中记载的数据标识,从数据库中逐个获取与数据标识对应的目标数据,并逐个将目标数据入队,消费者线程再逐个从预设数据队列中读取目标数据,即逐个将目标数据出队,消费者线程还基于读取到的目标数据生成数据导出文件(例如excel文件),由于目标数据是以流式导出方式读取的,因此,可以将读取到的目标数据转存到硬盘中,这样能够保证在生成excel文件时避免内存溢出现象。
本说明书一个或多个实施例中,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列进行数据传递,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
其中,上述预设数据队列可以是有界队列、还可以是阻塞队列、也可以是有界阻塞队列,由于有界阻塞队列既能够限定存入队列的数据的数量最大上限,又能够自动实现数据读写阻塞,优选地,将有界阻塞队列作为预设数据队列。
其中,有界阻塞队列是一个先入先出(FIFO)的数据结构且可容纳数据量存在上限的队列;并且有界阻塞队列是一个支持两个附加操作的队列,一个附加的操作是:读取阻塞操作,即在队列为空时,获取元素的消费者线程会等待队列变为非空;另一个附加操作是:写入阻塞操作,即当队列满时,存储元素的生产者线程会等待队列可用,即有界阻塞队列为生产者线程存放元素以及消费者线程读取元素的容器。
在具体实施时,如图2所示,给出了数据导出方法的第一种实现原理示意图,其中,从数据库中将目标数据导出生成数据导出文件的过程,具体包括:
S201,生产者线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
S202,生产者线程基于静态游标数据集从数据库中依次获取对应的目标数据;
S203,生产者线程按序依次将获取到的目标数据写入有界阻塞队列中;
S204,消费者线程从有界阻塞队列中按照先进先出顺序依次读取目标数据;
S205,消费者线程基于读取到的目标数据生成数据导出文件,例如,对目标数据进行转译并将转译后的目标数据存入excel文件中的sheet中。
其中,为了在生产者线程完成数据写入操作后,通知消费者线程,以避免消费者线程持续等待读取数据,基于此,在上述S103利用第一线程依次将获取到的目标数据写入预设数据队列中之后,还包括:
判断是否已获取到数据库快照中各数据标识对应的目标数据,具体的,若第一线程逐一获取到数据库快照中所有的数据标识分别对应的目标数据,并按序将获取到的目标数据写入预设数据队列后,说明生产者线程数据操作结束;
若是,则生成针对数据库快照的结束指示信息,并将该结束指示信息写入预设数据队列中,以便向消费者线程传递数据导出结束信号;
若否,则继续执行上述S102针对数据库快照中的每个数据标识,利用第一线程从数据库中依次获取与该数据标识对应的目标数据的步骤。
对应的,在第一线程将结束指示信息写入预设数据队列之后,第二线程将会读取到该结束指示信息,从而实现当第一线程结束数据入队时告知第二线程,避免第二线程持续等待数据读取操作,基于此,若第二线程的读取结果为结束指示信息,则控制第二线程停止执行目标数据读取操作,并确定已完成本次数据导出操作。
在具体实施时,如图3所示,给出了数据导出方法的第二种实现原理示意图,其中,从数据库中将目标数据导出生成数据导出文件的过程,具体包括:
S301,生产者线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
S302,生产者线程基于静态游标数据集从数据库中依次获取对应的目标数据;
S303,生产者线程按序依次将获取到的目标数据写入有界阻塞队列中;
S304,生产者线程在处理完静态游标数据集中最后一行数据后,向有界阻塞队列中写入一结束指示信息;即当获取到数据库快照中各数据标识对应的目标数据后,生成结束指示信息,并将该结束指示信息写入预设数据队列中,以便告知消费者线程,数据入队操作已结束,无需持续等待读取数据;
S305,消费者线程从有界阻塞队列中按照先进先出顺序依次读取目标数据;
S306,消费者线程将读取到的目标数据转译并保存至对应存储位置,例如,对目标数据进行转译并将转译后的目标数据存入excel文件中的sheet中;
S307,消费者线程当读取到结束指示信息后,获知生产者线程已将所有数据写入队列,基于读取到的目标数据生成数据导出文件。
其中,对于第一线程写入有界阻塞队列的目标数据而言,在第二线程从有界阻塞队列中读取该目标数据之前,该目标数据处于非游离状态,而当第二线程对该目标数据执行读取操作后,该目标数据变为游离状态,Java虚拟机JVM会自动对处于游离状态的目标数据进行GC回收处理,从而实现及时解除其对内存的占用,基于此,在利用第二线程从预设数据队列中按照先进先出顺序依次读取目标数据之后,还包括:
基于java的自动垃圾回收机制对预设数据队列中处于游离状态的目标数据进行GC回收处理;具体的,在从数据库中读取数据存入内存的过程中,由于Java虚拟机JVM实时进行GC垃圾回收,能够避免数据读取过程中内存溢出。
其中,针对预设数据队列为有界阻塞队列的情况,只有有界阻塞队列存储的数据的数量小于最大存储数量时,才允许第一线程向有界阻塞队列中写入数据,否则,第一线程会阻塞等待写入操作,基于此,上述S103利用第一线程依次将获取到的目标数据写入预设数据队列中,具体包括:
判断有界阻塞队列中存储的目标数据的数量是否达到预设数量上限,具体的,基于有界阻塞队列中存储的目标数据的数量,确定有界阻塞队列是否处于已满状态,进而确定是否允许第一线程向有界阻塞队列中写入数据;
若判断结果为否,则利用第一线程依次将获取到的目标数据写入有界阻塞队列中,具体的,当有界阻塞队列中存储的目标数据的数量未达到预设数量上限时,说明有界阻塞队列未满,此时允许第一线程将目标数据入队。
若判断结果为是,则对第一线程执行写入阻塞操作,以使第一线程阻塞等待向有界阻塞队列中写入目标数据,直到有界阻塞队列中存储的目标数据的数量小于预设数量上限;
具体的,当有界阻塞队列中存储的目标数据的数量达到预设数量上限时,说明有界阻塞队列已满,暂停第一线程向有界阻塞队列中写入数据;
其中,即使Java虚拟机JVM会自动对处于游离状态的目标数据进行GC回收处理,但当第一线程写入速度大于第二线程读取速度时,可能出现有界阻塞队列中存储的目标数据的数量达到预设数量上限的情况,此时自动阻塞新的写入操作,即第一线程进入写入阻塞等待状态;
具体的,第一线程持续在队列尾部添加元素(即目标数据),如果队列已满则第一线程会写入阻塞,直到有元素出队操作才激活该第一线程,即如果队列已满则等待队列有空位置再激活第一线程向队列写入元素,也就是说,如果队列为满则写入等待,直到有元素出队操作时发送信号激活阻塞等待线程(即生产者线程)。
在具体实施时,如图4所示,给出了数据导出方法的第三种实现原理示意图,其中,从数据库中将目标数据导出生成数据导出文件的过程,具体包括:
S401,生产者线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
S402,生产者线程基于静态游标数据集从数据库中依次获取对应的目标数据;
S403,生产者线程按序依次将获取到的目标数据写入有界阻塞队列中;
S404,当队列已满时,生产者线程进入写入阻塞等待状态,直到有新的目标数据出队则继续执行S403;
S405,生产者线程在处理完静态游标数据集中最后一行数据后,向有界阻塞队列中写入一结束指示信息;即当获取到数据库快照中各数据标识对应的目标数据后,生成结束指示信息,并将该结束指示信息写入预设数据队列中,以便告知消费者线程,数据入队操作已结束,无需持续等待读取数据;
S406,消费者线程从有界阻塞队列中按照先进先出顺序依次读取目标数据;
S407,消费者线程将读取到的目标数据转译并保存至对应存储位置,例如,对目标数据进行转译并将转译后的目标数据存入excel文件中的sheet中;
S408,消费者线程当读取到结束指示信息后,获知生产者线程已将所有数据写入队列,基于读取到的目标数据生成数据导出文件。
进一步的,考虑到当第二线程读取速度大于第一线程写入速度时,可能出现有界阻塞队列变为空的情况,即有界阻塞队列中不存在供第二线程读取的目标数据,基于此,若第二线程的读取结果为空,则对第二线程执行读取阻塞操作,以使该第二线程阻塞等待从有界阻塞队列中读取目标数据,直到有界阻塞队列中存在处于非游离状态的目标数据。
具体的,当有界阻塞队列已空时,暂停第二线程从有界阻塞队列中读取数据;其中,由于Java虚拟机JVM会自动对处于游离状态的目标数据进行GC回收处理,这样当第二线程读取速度大于第一线程写入速度时,可能出现有界阻塞队列变为空的情况,此时自动阻塞新的读取操作,即第二线程进入读取阻塞等待状态;
具体的,第二线程持续从队列头部读取元素(即目标数据),如果队列已空则第二线程会读取阻塞,直到有元素入队操作才激活该第二线程,即如果队列已空则等待队列存入新的元素再激活第二线程从队列中读取元素,也就是说,如果队列为空则读取等待,直到有元素入队操作时发送信号激活阻塞等待线程(即消费者线程)。
在具体实施时,如图5所示,给出了数据导出方法的第四种实现原理示意图,其中,从数据库中将目标数据导出生成数据导出文件的过程,具体包括:
S501,生产者线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
S502,生产者线程基于静态游标数据集从数据库中依次获取对应的目标数据;
S503,生产者线程按序依次将获取到的目标数据写入有界阻塞队列中;
S504,当队列已满时,生产者线程进入写入阻塞等待状态,直到有新的目标数据出队则继续执行S503;
S505,生产者线程在处理完静态游标数据集中最后一行数据后,向有界阻塞队列中写入一结束指示信息;即当获取到数据库快照中各数据标识对应的目标数据后,生成结束指示信息,并将该结束指示信息写入预设数据队列中,以便告知消费者线程,数据入队操作已结束,无需持续等待读取数据;
S506,消费者线程从有界阻塞队列中按照先进先出顺序依次读取目标数据;
S507,当队列已空时,消费者线程进入读取阻塞等待状态,直到有新的目标数据入队则继续执行S506;
S508,消费者线程将读取到的目标数据转译并保存至对应存储位置,例如,对目标数据进行转译并将转译后的目标数据存入excel文件中的sheet中;
S509,消费者线程当读取到结束指示信息后,获知生产者线程已将所有数据写入队列,基于读取到的目标数据生成数据导出文件。
其中,考虑到SXSSF对象具有自动转存数据的特性,为了避免在生成数据导出文件过程中出现内存溢出的问题,以及达到简化转存数据的目的,引入SXSSF对象作为内存中用于存储数据的存储单元,基于此,上述利用第二线程基于读取到的目标数据生成数据导出文件,具体包括:
步骤一,利用第二线程将读取到的目标数据存入预先创建的SXSSF对象中,以使通过该SXSSF对象将目标数据转存至预设硬盘上的临时文件中;
具体的,可以预先基于Apachea POI在JVM内存中创建预设数量个SXSSF对象,即构建预设数量个SXSSFWorkbook实现类,在大数据量导出时,第二线程将读取到的目标数据存入SXSSF对象,当预设数量个SXSSF对象中均存入目标数据时,SXSSF对象能够自动将目标数据由JVM内存转存到硬盘中,即直接POI写到硬盘上的xml临时文件中,以便后续第二线程继续将从有界阻塞队列中读取到的目标数据存入SXSSF对象;
其中,生产者线程将从数据库中获取的目标数据放入有界阻塞队列中,消费者线程将该目标数据从有界阻塞队列中取出,并将其保存在SXSSF对象中,SXSSF能够在内存不足时将一部分目标数据转存到硬盘中;
步骤二,当确定已完成本次数据导出操作时,利用第二线程从预设硬盘上的临时文件中加载目标数据并生成数据导出文件;
其中,当第二线程从有界阻塞队列中读取到结束指示信息时,则确定已完成本次数据导出操作,接下来,第二线程基于读取出的目标数据生成数据导出文件,由于在第二线程从有界阻塞队列中读取目标数据的过程,已将一部分目标数据自动转存到硬盘上的临时文件中,因此,当真正写excel文件时,运行在JVM内存上的第二线程再从临时文件中加载目标数据,且该目标数据以临时文件的方式存储在硬盘上,从而避免在excel文件生成期间出现内存溢出的情况。
具体的,当预设数量个SXSSF对象中均存入目标数据时,SXSSF对象能够自动将目标数据由JVM内存转存到硬盘中,以便后续第二线程继续将从有界阻塞队列中读取到的目标数据存入SXSSF对象;其中,最终可能有一部分目标数据未被转存到硬盘中,而是存储在JVM内存上的SXSSF对象中;因此,针对数据导出文件的生成过程,利用第二线程基于存储在JVM内存上的目标数据和转存到预设硬盘上的临时文件中的目标数据,生成数据导出文件,这样由于一部分目标数据已转存到硬盘上,不占用内存空间,从而能够避免在生成数据导出文件过程中,由于导出数据量过大而出现内存溢出的问题,同时,SXSSF对象具有自动转存数据的特性,能够达到简化转存数据的目的。
需要说明的是,由于SXSSF对象具有自动转存的特性,优选地,利用第二线程将读取到的目标数据存入SXSSF对象中,这样具有简化转存过程的效果,另外,也可以采用其他方式实现数据转存。
在具体实施时,如图6所示,给出了数据导出方法的第五种实现原理示意图,其中,从数据库中将目标数据导出生成数据导出文件的过程,具体包括:
S601,生产者线程获取数据库的静态游标数据集,其中,该静态游标数据集包括:指定时刻的数据库快照;
S602,生产者线程基于静态游标数据集从数据库中依次获取对应的目标数据;
S603,生产者线程按序依次将获取到的目标数据写入有界阻塞队列中;
S604,当队列已满时,生产者线程进入写入阻塞等待状态,直到有新的目标数据出队则继续执行S603;
S605,生产者线程在处理完静态游标数据集中最后一行数据后,向有界阻塞队列中写入一结束指示信息;即当获取到数据库快照中各数据标识对应的目标数据后,生成结束指示信息,并将该结束指示信息写入预设数据队列中,以便告知消费者线程,数据入队操作已结束,无需持续等待读取数据;
S606,消费者线程从有界阻塞队列中按照先进先出顺序依次读取目标数据;
S607,当队列已空时,消费者线程进入读取阻塞等待状态,直到有新的目标数据入队则继续执行S606;
S608,消费者线程将读取到的目标数据存入SXSSF对象中,以使通过该SXSSF对象将目标数据转存至硬盘上的临时文件中;
S609,消费者线程当读取到结束指示信息后,获知生产者线程已将所有数据写入队列,从硬盘上的临时文件中加载目标数据并生成数据导出文件。
本说明书一个或多个实施例中的数据导出方法,首先,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
对应上述图1至图6描述的数据导出方法,基于相同的技术构思,本说明书一个或多个实施例还提供了一种数据导出装置,图7为本说明书一个或多个实施例提供的数据导出装置的模块组成示意图,该装置用于执行图1至图6描述的数据导出方法,如图7所示,该装置包括:
数据获取模块701,用于利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;并针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
数据写入模块702,用于利用所述第一线程依次将所述目标数据写入预设数据队列中;
数据读取模块703,用于利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据;
文件生成模块704,用于利用所述第二线程基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例中,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列进行数据传递,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
可选地,所述预设数据队列包括:有界队列、阻塞队列、或者有界阻塞队列中任一种。
可选地,所述装置还包括:结束指示写入模块,用于:
在依次将所述目标数据写入预设数据队列中之后,判断是否已获取到所述数据库快照中各数据标识对应的目标数据;
若是,则生成针对所述数据库快照的结束指示信息,并将所述结束指示信息写入所述预设数据队列中。
可选地,所述装置还包括:第一读取操作控制模块,用于:
若所述第二线程的读取结果为所述结束指示信息,则控制所述第二线程停止执行目标数据读取操作,并确定已完成本次数据导出操作。
可选地,若所述预设数据队列为有界阻塞队列;所述数据写入模块702,具体用于:
判断所述有界阻塞队列中存储的目标数据的数量是否达到预设数量上限;
若判断结果为否,则依次将所述目标数据写入所述有界阻塞队列中。
可选地,所述数据写入模块702,还具体用于:
若判断结果为是,则对所述第一线程执行写入阻塞操作,以使所述第一线程阻塞等待向所述有界阻塞队列中写入目标数据,直到所述有界阻塞队列中存储的目标数据的数量小于预设数量上限。
可选地,所述装置还包括:第二读取操作控制模块,用于:
若所述第二线程的读取结果为空,则对所述第二线程执行读取阻塞操作,以使所述第二线程阻塞等待从所述有界阻塞队列中读取目标数据,直到所述有界阻塞队列存在处于非游离状态的目标数据。
可选地,所述装置还包括:数据回收处理模块,用于:
在依次将所述目标数据写入预设数据队列中之后,基于java的自动垃圾回收机制对所述预设数据队列中处于游离状态的目标数据进行GC回收处理。
可选地,所述文件生成模块704,具体用于:
利用所述第二线程将所述目标数据存入预先创建的SXSSF对象,以使通过所述SXSSF对象将所述目标数据转存至预设硬盘上的临时文件中;
当确定已完成本次数据导出操作时,从所述临时文件中加载所述目标数据并生成数据导出文件。
本说明书一个或多个实施例中的数据导出装置,首先,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
需要说明的是,本说明书中关于数据导出装置的实施例与本说明书中关于数据导出方法的实施例基于同一发明构思,因此该实施例的具体实施可以参见前述对应的数据导出方法的实施,重复之处不再赘述。
进一步地,对应上述图1至图6所示的方法,基于相同的技术构思,本说明书一个或多个实施例还提供了一种数据导出设备,该设备用于执行上述的数据导出方法,如图8所示。
数据导出设备可因配置或性能不同而产生比较大的差异,可以包括一个或一个以上的处理器801和存储器802,存储器802中可以存储有一个或一个以上存储应用程序或数据。其中,存储器802可以是短暂存储或持久存储。存储在存储器802的应用程序可以包括一个或一个以上模块(图示未示出),每个模块可以包括对数据导出设备中的一系列计算机可执行指令。更进一步地,处理器801可以设置为与存储器802通信,在数据导出设备上执行存储器802中的一系列计算机可执行指令。数据导出设备还可以包括一个或一个以上电源803,一个或一个以上有线或无线网络接口804,一个或一个以上输入输出接口805,一个或一个以上键盘806等。
在一个具体的实施例中,数据导出设备包括有存储器,以及一个或一个以上的程序,其中一个或者一个以上程序存储于存储器中,且一个或者一个以上程序可以包括一个或一个以上模块,且每个模块可以包括对数据导出设备中的一系列计算机可执行指令,且经配置以由一个或者一个以上处理器执行该一个或者一个以上程序包含用于进行以下计算机可执行指令:
利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;
针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
依次将所述目标数据写入预设数据队列中,以使利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据,基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例中,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列进行数据传递,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
可选地,计算机可执行指令在被执行时,所述预设数据队列包括:有界队列、阻塞队列、或者有界阻塞队列中任一种。
可选地,计算机可执行指令在被执行时,在依次将所述目标数据写入预设数据队列中之后,还包括:
判断是否已获取到所述数据库快照中各数据标识对应的目标数据;
若是,则生成针对所述数据库快照的结束指示信息,并将所述结束指示信息写入所述预设数据队列中。
可选地,计算机可执行指令在被执行时,若所述第二线程的读取结果为所述结束指示信息,则控制所述第二线程停止执行目标数据读取操作,并确定已完成本次数据导出操作。
可选地,计算机可执行指令在被执行时,若所述预设数据队列为有界阻塞队列;所述依次将所述目标数据写入预设数据队列中,包括:
判断所述有界阻塞队列中存储的目标数据的数量是否达到预设数量上限;
若判断结果为否,则依次将所述目标数据写入所述有界阻塞队列中。
可选地,计算机可执行指令在被执行时,若判断结果为是,则对所述第一线程执行写入阻塞操作,以使所述第一线程阻塞等待向所述有界阻塞队列中写入目标数据,直到所述有界阻塞队列中存储的目标数据的数量小于预设数量上限。
可选地,计算机可执行指令在被执行时,若所述第二线程的读取结果为空,则对所述第二线程执行读取阻塞操作,以使所述第二线程阻塞等待从所述有界阻塞队列中读取目标数据,直到所述有界阻塞队列存在处于非游离状态的目标数据。
可选地,计算机可执行指令在被执行时,在依次将所述目标数据写入预设数据队列中之后,还包括:
基于java的自动垃圾回收机制对所述预设数据队列中处于游离状态的目标数据进行GC回收处理。
可选地,计算机可执行指令在被执行时,所述基于读取到的所述目标数据生成数据导出文件,包括:
利用所述第二线程将所述目标数据存入预先创建的SXSSF对象,以使通过所述SXSSF对象将所述目标数据转存至预设硬盘上的临时文件中;
当确定已完成本次数据导出操作时,从所述临时文件中加载所述目标数据并生成数据导出文件。
本说明书一个或多个实施例中的数据导出设备,首先,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
需要说明的是,本说明书中关于数据导出设备的实施例与本说明书中关于数据导出方法的实施例基于同一发明构思,因此该实施例的具体实施可以参见前述对应的数据导出方法的实施,重复之处不再赘述。
进一步地,对应上述图1至图6所示的方法,基于相同的技术构思,本说明书一个或多个实施例还提供了一种存储介质,用于存储计算机可执行指令,一种具体的实施例中,该存储介质可以为U盘、光盘、硬盘等,该存储介质存储的计算机可执行指令在被处理器执行时,能实现以下流程:
利用第一线程获取数据库的静态游标数据集,其中,所述静态游标数据集包括:指定时刻的数据库快照;
针对所述数据库快照中的每个数据标识,从所述数据库中依次获取与该数据标识对应的目标数据;
依次将所述目标数据写入预设数据队列中,以使利用第二线程从所述预设数据队列中按照先进先出顺序依次读取所述目标数据,基于读取到的所述目标数据生成数据导出文件。
本说明书一个或多个实施例中,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列进行数据传递,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,所述预设数据队列包括:有界队列、阻塞队列、或者有界阻塞队列中任一种。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,在依次将所述目标数据写入预设数据队列中之后,还包括:
判断是否已获取到所述数据库快照中各数据标识对应的目标数据;
若是,则生成针对所述数据库快照的结束指示信息,并将所述结束指示信息写入所述预设数据队列中。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,若所述第二线程的读取结果为所述结束指示信息,则控制所述第二线程停止执行目标数据读取操作,并确定已完成本次数据导出操作。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,若所述预设数据队列为有界阻塞队列;所述依次将所述目标数据写入预设数据队列中,包括:
判断所述有界阻塞队列中存储的目标数据的数量是否达到预设数量上限;
若判断结果为否,则依次将所述目标数据写入所述有界阻塞队列中。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,若判断结果为是,则对所述第一线程执行写入阻塞操作,以使所述第一线程阻塞等待向所述有界阻塞队列中写入目标数据,直到所述有界阻塞队列中存储的目标数据的数量小于预设数量上限。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,若所述第二线程的读取结果为空,则对所述第二线程执行读取阻塞操作,以使所述第二线程阻塞等待从所述有界阻塞队列中读取目标数据,直到所述有界阻塞队列存在处于非游离状态的目标数据。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,在依次将所述目标数据写入预设数据队列中之后,还包括:
基于java的自动垃圾回收机制对所述预设数据队列中处于游离状态的目标数据进行GC回收处理。
可选地,该存储介质存储的计算机可执行指令在被处理器执行时,所述基于读取到的所述目标数据生成数据导出文件,包括:
利用所述第二线程将所述目标数据存入预先创建的SXSSF对象,以使通过所述SXSSF对象将所述目标数据转存至预设硬盘上的临时文件中;
当确定已完成本次数据导出操作时,从所述临时文件中加载所述目标数据并生成数据导出文件。
本说明书一个或多个实施例中的存储介质存储的计算机可执行指令在被处理器执行时,首先,利用第一线程基于静态游标的方式获取查询时刻的数据库快照,再从数据库中逐一获取与数据库快照中记载的各数据标识分别对应的目标数据;并且引入作为数据缓存池的数据队列,利用第一线程将获取到的目标数据存入数据队列中;然后,利用第二线程从该数据队列中逐一读取目标数据,并基于读取到的目标数据生成相应的数据导出文件,这样不仅能够实现对目标数据的流式导出,避免因一次性导出数据导致内存溢出的问题,还能够避免采用分页导出方式因数据发生变更导致数据重复、缺失的问题,提高了针对海量数据导出过程的数据完整性和准确性。
需要说明的是,本说明书中关于存储介质的实施例与本说明书中关于数据导出方法的实施例基于同一发明构思,因此该实施例的具体实施可以参见前述对应的数据导出方法的实施,重复之处不再赘述。
在20世纪90年代,对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device,PLD)(例如现场可编程门阵列(Field Programmable GateArray,FPGA))就是这样一种集成电路,其逻辑功能由用户对器件编程来确定。由设计人员自行编程来把一个数字***“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware DescriptionLanguage)、Confluence、CUPL(Cornell University Programming Language)、HD Cal、JHDL(Java Hardware Description Language)、Lava、Lola、My HDL、PALASM、RHDL(RubyHardware Description Language)等,目前最普遍使用的是VHDL(Very-High-SpeedIntegrated Circuit Hardware Description Language)与Verilog。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、Atmel AT91SAM、Microchip PIC18F26K20以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
上述实施例阐明的***、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。一种典型的实现设备为计算机。具体的,计算机例如可以为个人计算机、膝上型计算机、蜂窝电话、相机电话、智能电话、个人数字助理、媒体播放器、导航设备、电子邮件设备、游戏控制台、平板计算机、可穿戴设备或者这些设备中的任何设备的组合。
为了描述的方便,描述以上装置时以功能分为各种单元分别描述。当然,在实施本说明书一个或多个时可以把各单元的功能在同一个或多个软件和/或硬件中实现。
本领域内的技术人员应明白,本说明书一个或多个的实施例可提供为方法、***、或计算机程序产品。因此,本说明书一个或多个可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本说明书一个或多个可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本说明书一个或多个是参照根据本说明书一个或多个实施例的方法、设备(***)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
还需要说明的是,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、商品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、商品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、商品或者设备中还存在另外的相同要素。
本领域技术人员应明白,本说明书一个或多个的实施例可提供为方法、***或计算机程序产品。因此,本说明书一个或多个可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本说明书一个或多个可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本说明书一个或多个可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本说明书一个或多个,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于***实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
以上所述仅为本说明书一个或多个的实施例而已,并不用于限制本说明书一个或多个。对于本领域技术人员来说,本说明书一个或多个可以有各种更改和变化。凡在本说明书一个或多个的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本说明书一个或多个的权利要求范围之内。