本发明涉及计算机技术领域,具体而言,涉及一种访问数据库的方法及装置。
背景技术:
目前,安卓开发过程中通常使用数据库管理数据,安卓系统默认自带的数据库是Sqlite(轻型数据库),安卓开发了一个用于访问数据库的工具类SqliteOpenHelper(数据库文件位置),用户可通过SqliteOpenHelper类对数据库进行增、删、改或差的操作。
当用户使用SqliteOpenHelper访问数据库时,接收用户的访问数据库请求,创建一个线程,将该线程分配给用户的访问数据库请求,通过该线程实现对数据库的访问。由于对每个访问数据库请求,都需要创建线程,线程会占用一定的系统资源,当访问数据库请求数量很大时,创建的线程数目过多,将占用大量的系统资源,降低系统运行速度。
技术实现要素:
有鉴于此,本发明实施例的目的在于提供一种访问数据库的方法及装置,通过AsyncTask来执行查询指令,通过线程池方式来执行除查询指令外的增、删或改指令,不需要为每个访问数据库请求创建线程,节省了系统资源,不会降低系统运行速度,且有效避免了访问数据库操作对主线程造成的阻塞。
第一方面,本发明实施例提供了一种访问数据库的方法,所述方法包括:
接收用户的访问数据库请求,所述访问数据库请求携带操作指令;
判断所述操作指令是否为查询指令;
如果是,则通过异步类AsyncTask执行所述操作指令对应的访问数据库操作;
如果否,则通过线程池方式执行所述操作指令对应的访问数据库操作。
结合第一方面,本发明实施例提供了上述第一方面的第一种可能的实现方式,其中,所述通过线程池方式执行所述操作指令对应的访问数据库操作,包括:
查看线程池中是否存在空闲线程,所述线程池中包括预设数目个线程;
如果是,则从所述线程池中获取一个所述空闲线程,通过获取的所述空闲线程执行所述操作指令对应的访问数据库操作;
如果否,则将所述访问数据库请求插入等待队列的队尾进行等待。
结合第一方面的第一种可能的实现方式,本发明实施例提供了上述第一方面的第二种可能的实现方式,其中,所述将所述访问数据库请求插入等待队列的队尾进行等待之后,还包括:
实时监测线程池中每个线程的状态,当监测到状态改变为空闲状态的线程时,从所述等待队列的队首出队一个访问数据库请求,通过状态改变的所述线程执行出队的所述访问数据库请求对应的访问数据库操作。
结合第一方面,本发明实施例提供了上述第一方面的第三种可能的实现方式,其中,所述方法还包括:
在执行所述操作指令对应的访问数据库操作的过程中,通过反馈接口向所述用户反馈执行进度及执行结果。
结合第一方面的第三种可能的实现方式,本发明实施例提供了上述第一方面的第四种可能的实现方式,其中,所述方法还包括:
对执行所述操作指令对应的访问数据库操作的执行过程进行异常监测;
当监测到执行过程出现异常时,捕获执行过程中的异常信息;
通过所述反馈接口将所述异常信息反馈给所述用户。
第二方面,本发明实施例提供了一种访问数据库的装置,所述装置包括:
接收模块,用于接收用户的访问数据库请求,所述访问数据库请求携带操作指令;
判断模块,用于判断所述操作指令是否为查询指令;
执行模块,用于当所述判断模块判断所述操作指令是查询指令时,通过异步类AsyncTask执行所述操作指令对应的访问数据库操作;当所述判断模块判断所述操作指令不是查询指令时,通过线程池方式执行所述操作指令对应的访问数据库操作。
结合第二方面,本发明实施例提供了上述第二方面的第一种可能的实现方式,其中,所述执行模块包括:
查看单元,用于查看线程池中是否存在空闲线程,所述线程池中包括预设数目个线程;
执行单元,用于当所述查看单元查看出线程池中存在空闲线程时,从所述线程池中获取一个所述空闲线程,通过获取的所述空闲线程执行所述操作指令对应的访问数据库操作;
插入单元,用于当所述查看单元查看出线程池中不存在空闲线程时,将所述访问数据库请求插入等待队列的队尾进行等待。
结合第二方面的第一种可能的实现方式,本发明实施例提供了上述第二方面的第二种可能的实现方式,其中,所述装置还包括:
监测模块,用于实时监测线程池中每个线程的状态,当监测到状态改变为空闲状态的线程时,从所述等待队列的队首出队一个访问数据库请求,通过状态改变的所述线程执行出队的所述访问数据库请求对应的访问数据库操作。
结合第二方面,本发明实施例提供了上述第二方面的第三种可能的实现方式,其中,所述装置还包括:
反馈模块,用于在执行所述操作指令对应的访问数据库操作的过程中,通过反馈接口向所述用户反馈执行进度及执行结果。
结合第二方面的第三种可能的实现方式,本发明实施例提供了上述第二方面的第四种可能的实现方式,其中,所述装置还包括:
异常捕获模块,用于对执行所述操作指令对应的访问数据库操作的执行过程进行异常监测;当监测到执行过程出现异常时,捕获执行过程中的异常信息;通过所述反馈接口将所述异常信息反馈给所述用户。
在本发明实施例提供的方法及装置中,接收用户的访问数据库请求,该访问数据库请求携带操作指令;判断该操作指令是否为查询指令;如果是,则通过异步类AsyncTask执行该操作指令对应的访问数据库操作;如果否,则通过线程池方式执行该操作指令对应的访问数据库操作。本发明通过AsyncTask来执行查询指令,通过线程池方式来执行除查询指令外的增、删或改指令,如此不需要为每个访问数据库请求创建线程,节省了系统资源,不会降低系统运行速度,且有效避免了访问数据库操作对主线程造成的阻塞。另外,还使用反馈接口对数据库的执行过程进行了很好的暴露,能够使外界实时获知数据库的执行情况,且对数据库操作出现异常时,还捕获异常信息,并通过反馈接口将异常信息传递给用户。
为使本发明的上述目的、特征和优点能更明显易懂,下文特举较佳实施例,并配合所附附图,作详细说明如下。
附图说明
为了更清楚地说明本发明实施例的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,应当理解,以下附图仅示出了本发明的某些实施例,因此不应被看作是对范围的限定,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他相关的附图。
图1示出了本发明实施例1所提供的一种访问数据库的方法流程图;
图2示出了本发明实施例2所提供的一种访问数据库的第一装置结构示意图;
图3示出了本发明实施例2所提供的一种访问数据库的第二装置结构示意图;
图4示出了本发明实施例2所提供的一种访问数据库的第三装置结构示意图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。通常在此处附图中描述和示出的本发明实施例的组件可以以各种不同的配置来布置和设计。因此,以下对在附图中提供的本发明的实施例的详细描述并非旨在限制要求保护的本发明的范围,而是仅仅表示本发明的选定实施例。基于本发明的实施例,本领域技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本发明保护的范围。
考虑到现有技术对每个访问数据库请求,都需要创建线程,线程会占用一定的系统资源,当访问数据库请求数量很大时,创建的线程数目过多,将占用大量的系统资源,降低系统运行速度。基于此,本发明实施例提供了一种访问数据库的方法及装置,下面通过实施例进行描述。
实施例1
参见图1,本发明实施例提供了一种访问数据库的方法,该方法具体包括以下步骤:
步骤101:接收用户的访问数据库请求,该访问数据库请求携带操作指令。
本发明实施例的执行主体可以为终端。用户在程序开发过程中,为了更好的管理数据,经常需要访问数据库。当用户需要访问数据库时,用户编写用于访问数据库的代码,该代码中包含用户想要对数据库进行操作的操作指令。程序运行该用于访问数据库的代码时,相当于提交了用户的访问数据库请求,此时终端接收用户的访问数据库请求。
上述访问数据库请求携带的操作指令可以为查询指令、增加指令、删除指令或修改指令。其中,增加指令、删除指令和修改指令为写入操作,查询指令为读取操作。写入操作耗时比读取操作耗时长很多,所以本发明实施例将访问数据库的操作划分为写入操作和读取操作两类,对这两类操作进行区分处理,因此在执行访问数据库的操作指令之前,首先通过如下步骤102的操作来区分用户的访问数据库请求属于哪一类操作。
步骤102:判断该操作指令是否为查询指令,如果是,则执行步骤103,如果否,则执行步骤104。
在数据库操作中增加指令的程序用语为insert,删除指令的程序用语为delete,修改指令的程序用语为update,查询指令的程序用语为select。接收到用户的访问数据库请求后,从该访问数据库请求中获取操作指令,识别该操作指令中的程序用语是否为select,如果是,则判断出该操作指令为查询指令,如果否,则判断出该操作指令不是查询指令。
步骤103:通过AsyncTask(异步类)执行操作指令对应的访问数据库操作。
AsyncTask是安卓系统提供的一个多线程处理工具类,AsyncTask使用起来比较简单,占用系统资源少。由于查询操作属于数据库读取操作,读取操作是轻量级的操作,所以本发明实施例使用轻量级的AsyncTask线程工具来执行读取操作。
通过AsyncTask执行访问数据库请求携带的查询指令时,需要重写以下两个函数:
(1)、后台执行函数doInBackground(),在执行查询指令时比较耗时的操作都可以放在该函数中进行,该函数在后台线程执行,完成查询操作任务的主要工作,通常需要较长的时间。在执行过程中可以调用进度展示函数publicProgress()来更新任务的进度。
(2)、后执行函数onPostExecute(),在该函数里面可以使用函数doInBackground()的结果处理操作UI(User Interface,用户界面)。函数onPostExecute()在主线程执行,执行查询操作的结果作为此函数的参数返回。
在通过AsyncTask执行访问数据库请求携带的查询指令时,除需要重写上述两个函数外,需要时还可以重写以下三个函数:
进度更新函数onProgressUpdate(),通过进度条增加用户体验度。此函数在主线程执行,用于显示任务执行的进度;
预执行函数onPreExecute(),该函数是最终用户调用执行时的接口,当任务执行之前开始调用此函数,可以在这里显示进度对话框;
取消函数onCancelled(),在用户取消对数据库的访问操作时,调用该函数。
在本步骤中通过AsyncTask执行查询数据库的操作时,为了能将数据库的状态反馈出来,使用户能够实时获知数据库当前所处的状态,本发明实施例提供了用于反馈数据库状态的反馈接口。在通过AsyncTask执行访问数据库请求中的查询指令过程中,还通过该反馈接口向用户反馈执行进度及执行结果。
为了便于理解通过反馈接口向用户反馈执行进度及执行结果的操作,下面以向数据库中增加数据过程中的状态反馈为例进行说明。在向数据库插入新增数据时反馈接口的接口定义具体如下:
其中,Void onStart(long startTime)是开始函数,用于增加数据开始时候的回调信息,表明数据库插入开始了。参数startTime表示插入的时间点,该时间点可以通过获取系统时间来得到。获取系统时间的方法是调用JDK(Java Development Kit)中的一个函数获取的。JDK汇总存在一个System(系统)的类,该类中有当前时间函数Currenttimemillis(),该函数用于获取系统当前的时间信息,并以毫秒的形式返回。参数startTime的值就是通过函数Currenttimemillis()获取的,获取后直接赋值给参数startTime,这样反馈接口外就能够拿到参数startTime的具体时间值了。
Void onSuccess(long successTime)是插入成功时间函数,如果数据库插入成功了,会通过反馈接口回调函数onSuccess(long successTime),其中,参数successTime表示插入成功时的时间信息。该时间信息的获取方式和函数onStart()中的时间信息获取方式相同,在此不再赘述。
Void onError(String errMsg)是错误反馈函数,主要用于回调当前数据库插入操作出现异常时的异常信息,并将具体的异常信息封装到参数errMsg中。
其中,在通过AsyncTask执行查询数据库操作的过程中,可能会出现执行逻辑出错的问题,因此本发明实施例中还对执行过程中出现的异常进行异常捕获,并将捕获到的异常信息赋给上述参数errMsg,通过反馈接口将捕获的异常信息反馈给用户。其中,对异常信息进行捕获的具体操作过程如下:
对执行操作指令对应的访问数据库操作的执行过程进行异常监测;当监测到执行过程出现异常时,捕获执行过程中的异常信息;通过反馈接口将异常信息反馈给用户。
本发明实施例中,捕获异常信息是通过try-catch代码块来进行捕获的。try-catch代码块是JAVA(脚本)语言所特有的,JAVA虚拟机首先对异常信息进行捕获,当JAVA虚拟机发现try-catch代码块内部执行逻辑出现异常时,JAVA虚拟机捕获异常信息,然后将该异常信息丢给try-catch代码块,这样try-catch代码块就拿到JAVA虚拟机抛上来的异常信息,也就捕获到执行访问数据库时的异常信息了。
本发明实施例提供的反馈接口中,函数onError()反馈的信息就是通过try-catch代码块捕获到的异常信息,try-catch一旦捕获到异常信息,就将异常信息通过反馈接口中的函数onError()传递给用户。
步骤104:通过线程池方式执行操作指令对应的访问数据库操作。
线程池是一种多线程处理形式,是一个用于控制线程的工具。通过线程池能够更好的对线程进行管理,非常适合处理一些业务逻辑比较重,同时又不影响到UI界面的任务。
线程池在使用的过程中有多种模式可以选择,例如线程池的模式可以为以下4种中的任一种:
1、newCachedThreadPool(可缓存线程池):创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无空闲线程可回收,则创建新的线程。
2、newFixedThreadPool(定长线程池):创建一个定长线程池,该线程池可控制线程最大并发数,超出最大并发数的线程会在队列中等待。
3、newScheduledThreadPool(定时线程池):该线程池支持定时及周期性任务的执行。
4、newSingleThreadExecutor(单线程化线程池):创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
由于对数据库的增、删和改过程在系统执行期间是比较频繁的过程,如果频繁申请线程来处理增、删和改操作,会对系统产生比较重的负担,所以对于这三种操作,为了复用相应的线程资源,减少系统开支,本发明实施例采用的线程池的模式是newCachedThreadPool模式,该模式的线程池是具有缓存功能的。即对于数据库的增、删或改操作使用后的线程,线程池会将使用过的线程缓存起来,下次再使用的时候就可以直接使用线程池中缓存的线程,不需要再创建新的线程,避免了频繁申请线程的问题,以及避免了线程太多而占用太多的系统资源,能够有效减少数据库增删改过程对系统资源的开销。
本发明实施例中,线程池中包括预设数目个线程,这些线程都是后台线程,每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
当确定访问数据库请求携带的操作指令不是查询指令时,终端查看线程池中是否存在空闲线程。如果是,则从线程池中获取一个空闲线程,通过获取的空闲线程执行操作指令对应的访问数据库操作。如果否,则将访问数据库请求插入等待队列的队尾进行等待。
将访问数据库请求插入等待队列的队尾之后,还需要实时监测线程池中每个线程的状态,当监测到状态改变为空闲状态的线程时,从等待队列的队首出队一个访问数据库请求,通过状态改变的线程执行出队的访问数据库请求对应的访问数据库操作。
通过线程池方式执行访问数据库请求包括的操作指令后,还通过反馈接口向用户反馈执行进度及执行结果,使用用户能够实时获知数据库当前所处的状态。
在通过线程池方式执行增、删或改操作的过程中,也可能会出现逻辑错误,因此本步骤中也需要在执行过程中进行异常监测,并在出现异常时进行异常捕获,本步骤中同样是通过try-catch代码块来进行异常捕获的,try-catch代码块捕获异常信息的操作与步骤103中相同,在此不再赘述。当捕获到异常信息时,也通过反馈接口将捕获的异常信息反馈给用户。
本发明实施例能实时的将数据库正在处理的状态通过反馈接口对外公开,调用者能够非常清晰的知道当前数据库所处状态,对于需要结果返回的,也可通过反馈接口直接返回数据。开发者可以直接在定义的接口中获取数据并对数据进行处理,很大程度上降低开发者的开发难度,同时借助反馈接口来实时反馈数据库状态和最终结果。并且在数据库内部也做了大量的异常捕获操作,当数据库操作出现异常情况时会对异常信息进行捕获,然后通知外界异常信息,极大程度的暴露数据库的状态,同时操作和使用简单,让开发者有更多的时间关注到具体的业务逻辑实现上。
在本发明实施例中,接收用户的访问数据库请求,该访问数据库请求携带操作指令;判断该操作指令是否为查询指令;如果是,则通过异步类AsyncTask执行该操作指令对应的访问数据库操作;如果否,则通过线程池方式执行该操作指令对应的访问数据库操作。本发明通过AsyncTask来执行查询指令,通过线程池方式来执行除查询指令外的增、删或改指令,如此不需要为每个访问数据库请求创建线程,节省了系统资源,不会降低系统运行速度,且有效避免了访问数据库操作对主线程造成的阻塞。另外,还使用反馈接口对数据库的执行过程进行了很好的暴露,能够使外界实时获知数据库的执行情况,且对数据库操作出现异常时,还捕获异常信息,并通过反馈接口将异常信息传递给用户。
实施例2
参见图2,本发明实施例提供了一种访问数据库的装置,该装置用于执行上述实施例1所提供的访问数据库的方法。该装置具体包括:
接收模块201,用于接收用户的访问数据库请求,访问数据库请求携带操作指令;
判断模块202,用于判断操作指令是否为查询指令;
执行模块203,用于当判断模块202判断操作指令是查询指令时,通过异步类AsyncTask执行操作指令对应的访问数据库操作;当判断模块202判断操作指令不是查询指令时,通过线程池方式执行操作指令对应的访问数据库操作。
如图3所示,当判断模块202判断操作指令不是查询指令,即当操作指令为增加指令、删除指令或修改指令时,执行模块203通过如下查看单元2031、执行单元2032和插入单元2033来执行该操作指令。
查看单元2031,用于查看线程池中是否存在空闲线程,该线程池中包括预设数目个线程;
执行单元2032,用于当查看单元2031查看出线程池中存在空闲线程时,从线程池中获取一个空闲线程,通过获取的空闲线程执行操作指令对应的访问数据库操作;
插入单元2033,用于当查看单元2031查看出线程池中不存在空闲线程时,将访问数据库请求插入等待队列的队尾进行等待。
如图4所示,上述插入单元将访问数据库请求插入等待队列的队尾后,该装置还需要通过如下监测模块204对线程池进行监测,并在线程池中出现空闲线程时,通过空闲线程执行等待队列中的访问数据库请求。
监测模块204,用于实时监测线程池中每个线程的状态,当监测到状态改变为空闲状态的线程时,从等待队列的队首出队一个访问数据库请求,通过状态改变的线程执行出队的访问数据库请求对应的访问数据库操作。
本发明实施例中,该装置还提供了反馈接口,通过该反馈接口实时向外界反馈数据库的状态。如图4所示,在执行模块203执行操作指令的过程中,还通过如下反馈模块205从上述反馈接口向用户反馈操作指令的执行情况。
反馈模块205,用于在执行模块203执行操作指令对应的访问数据库操作的过程中,通过反馈接口向用户反馈执行进度及执行结果。
如图4所示,执行模块203在执行访问数据库请求携带的操作指令过程中,可能会出现逻辑错误,因此在出现异常时本装置还通过如下异常捕获模块206来捕获异常信息。
异常捕获模块206,用于对执行模块203执行操作指令对应的访问数据库操作的执行过程进行异常监测;当监测到执行过程出现异常时,捕获执行过程中的异常信息;通过反馈接口将异常信息反馈给用户。
在本发明实施例中,接收用户的访问数据库请求,该访问数据库请求携带操作指令;判断该操作指令是否为查询指令;如果是,则通过异步类AsyncTask执行该操作指令对应的访问数据库操作;如果否,则通过线程池方式执行该操作指令对应的访问数据库操作。本发明通过AsyncTask来执行查询指令,通过线程池方式来执行除查询指令外的增、删或改指令,如此不需要为每个访问数据库请求创建线程,节省了系统资源,不会降低系统运行速度,且有效避免了访问数据库操作对主线程造成的阻塞。另外,还使用反馈接口对数据库的执行过程进行了很好的暴露,能够使外界实时获知数据库的执行情况,且对数据库操作出现异常时,还捕获异常信息,并通过反馈接口将异常信息传递给用户。
本发明实施例所提供的访问数据库的装置可以为设备上的特定硬件或者安装于设备上的软件或固件等。本发明实施例所提供的装置,其实现原理及产生的技术效果和前述方法实施例相同,为简要描述,装置实施例部分未提及之处,可参考前述方法实施例中相应内容。所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,前述描述的系统、装置和单元的具体工作过程,均可以参考上述方法实施例中的对应过程,在此不再赘述。
在本发明所提供的实施例中,应该理解到,所揭露装置和方法,可以通过其它的方式实现。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,又例如,多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些通信接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本发明提供的实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。
所述功能如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本发明的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本发明各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,Random Access Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
应注意到:相似的标号和字母在下面的附图中表示类似项,因此,一旦某一项在一个附图中被定义,则在随后的附图中不需要对其进行进一步定义和解释,此外,术语“第一”、“第二”、“第三”等仅用于区分描述,而不能理解为指示或暗示相对重要性。
最后应说明的是:以上所述实施例,仅为本发明的具体实施方式,用以说明本发明的技术方案,而非对其限制,本发明的保护范围并不局限于此,尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,其依然可以对前述实施例所记载的技术方案进行修改或可轻易想到变化,或者对其中部分技术特征进行等同替换;而这些修改、变化或者替换,并不使相应技术方案的本质脱离本发明实施例技术方案的精神和范围。都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以所述权利要求的保护范围为准。