数据持久化层

2024-05-11

数据持久化层(精选九篇)

数据持久化层 篇1

JDBC[1]是SUN公司为Java语言提供的用于执行SQL语句的一组API,Java EE核心标准之一。在Java EE应用的分层开发模型中,数据持久层用来在业务逻辑层和数据库层之间传递数据,所以其性能是Java EE应用的研究热点问题。与其他的数据持久层解决方案[2,3,4](例如Hibernate、Mybatis、EJB等)相比,JDBC具有使用成本低、执行速度快、不依赖于业务容器、擅长多表联合查询等优点,所以在持久层开发中有着广泛的应用。但是JDBC也存在着代码冗余度高、编写繁琐、复用率低等缺点。因此,在以JDBC作为持久化技术的Java应用中,如何进一步提高JDBC的性能,是开发人员需要解决的首要问题。本文从JDBC API应用方面入手,提出了若干优化方法。通过性能测试,证明了相关优化方法的有效性,对于在实际项目开发中使用JDBC有良好的理论指导和价值参考。

2 JDBC体系结构与核心接口

JDBC的体系结构如图1所示,主要包括:JDBC API、驱动管理器、JDBC驱动程序以及允许驱动程序向驱动管理器进行注册的机制[5]。其中,开发人员使用JDBC API编写应用程序;数据库供应商开发JDBC驱动程序;驱动管理器负责将两者“连接”起来。即应用程序通过JDBC API与驱动管理器通信,而驱动管理器则通过驱动程序与某个具体的数据库通信。在实际开发中,驱动程序都是由第三方提供,开发人员一般不会对其进行修改。所以本文主要从JD-BC API的应用方面展开优化研究。

JDBC API的关系如图2所示,在开发中主要使用以下5个核心接口[6]:

(1) Connection:代表应用程序与数据库之间的一条连接,由驱动管理者创建。该对象在上下文中创建其他的JDBC对象,并管理数据库事务。

(2) Statement:由Connection的createStatement方法创建,用于执行不带参数的SQL语句并返回处理的结果。

(3) PreparedStatement:Statement的子接口,通过它执行SQL语句具有三个优点:①代码更具可读性和维护性;②能够对SQL预编译,提高执行效率;③屏蔽恶意SQL语句,提高安全性。

(4) CallableStatement:由Connection的prepareCall方法创建,该对象在存储过程SQL转译语法的协助下,以统一标准方式调用RDBMS中的存储过程。

(5) ResultSet:由SQL查询语句生成的结果集对象,并提供了遍历数据记录的方法。

3 JDBC性能的优化方法

3.1 选取合适的驱动类型

由图1可知驱动程序是Java应用与数据库之间的中介,能够将Java语言映射为具体的数据库“方言”。所以性能优化的首要问题是依据实际应用的需求选取合适的驱动程序。目前共有以下四种类型的JDBC驱动程序[7]。

(1)JDBC-ODBC桥驱动:该类型驱动将JDBC调用转换为ODBC调用,要求客户端安装ODBC数据源,因此执行效率低,适合于单用户、规模小的应用。

(2) Native API+Java驱动:本地驱动,该类型驱动将JDBC调用转换为本地C/C++API访问特定数据库,因此客户端需要具有特定的本地库。

(3)JDBC-Net驱动:该类型驱动需要代理服务器,客户端的JDBC调用通过代理服务器转化为对数据库的调用,客户端不需要任何特定的本地库。

(4)纯Java驱动:该类型驱动本身由Java语言编写,可以直接访问数据库,客户端不需要任何特定的本地库。

其中(1)、(2)和(4)这三种类型的驱动适合于两层架构(客户端和数据库)的应用程序,访问速度由快到慢顺序是(4)>(2)>(1),而且(1)和(2)这两种驱动目前在应用中已经不使用了,仅用于测试和实验目的。(3)型驱动适合于三层架构(客户端、代理服务器和数据库)的应用程序,可以借助代理服务器(例如Weblogic,WebSphere等)的性能优化方案提高运算速度,但代理服务器的费用较高会增加系统成本。由于JDK版本的不断提高和JVM性能的不断优化,而且在考虑成本的情况下,(4)类型的驱动是最好的选择,因为其可以直接访问数据库,易于控制、部属和移植,不需要特定的本地库。

3.2 Connection对象的复用

Connection对象代表客户端与数据库之间的一条连接,在系统底层维护了一个TCP链接,所以它的创建是一项非常耗时且IO开销很大的操作。频繁创建、释放Connection对象的做法在并发量较大的应用中是不可取的。目前普遍采用连接池的方式实现Connection的复用。连接池的核心思想[8,9]是:服务器启动时创建连接池对象,根据相关参数创建一定数量的Connection对象(空闲连接)并缓存起来;当客户端请求到来时,连接池对象取一个空闲连接分配给该客户端,并将该连接标记为忙碌;如果没有空闲连接且忙碌连接数没有达到最大值,就创建一个新的Connection对象给客户端,否则客户端就处于等待状态,在最大等待时间内还没有得到连接,就会得到一个异常标志这次获取操作失败;连接使用完后,由客户端交还给连接池并标记为空闲,以供其他客户端使用,从而达到复用的目的,如图3所示。

要自行创建一个数据库连接池,需要考虑最小连接数、最大连接数、调用者异常的处理及恢复、服务端异常的处理及恢复、设备的性能极限、网络吞吐量等各种复杂因素,所以实现较为困难。目前已有一些优秀的、开源的第三方数据库连接池,例如C3P0、Proxoo、DBCP等,它们在稳定性、效率等方面的性能已在实际项目中得到了验证,所以使用上述开源的连接池管理Connection是提高性能的一个重要手段。

3.3 合理选取Statement

从图2可知Statement接口共有3种:①Statement:用于执行静态SQL语句并返回处理结果,SQL语句执行一次编译一次。②PreparedStatement:能够对SQL语句进行预编译并存储,然后可以重复性的多次执行该语句。③CallableStatement:用于执行SQL存储过程。由于PreparedStatement对一条SQL语句可以进行预编译处理,而且允许这条语句多次执行,所以在批量执行的情况下要优于Statement;而且PreparedStatement允许SQL语句在编译时使用占位符(?),在执行时通过实参进行替换,适合于带有约束条件的SQL语句,从而避免字符串拼接带来的SQL注入问题。通过上述分析可知,如果某个SQL语句只执行一次,选择Statement;如果执行多次并且带有约束条件,则选择PreparedStatement。如果要调用数据库端的存储过程,只能选择CallableStatement。

假如要更新大量数据时,考虑使用PreparedStatement的批处理操作。该操作将更新用到的参数缓存到客户端,当积累到一定数量后,再执行executeBatch()方法提交给数据库执行。

3.4 ResultSet的优化

ResultSet用来存储查询语句所得到的结果集。主要从两个方面进行优化:①设置合适的处理数据行的方向;②选取合适的getXXX()方法。ResultSet有3个设置数据读取方向的常量:FETCH_FORWAR,FETCH_REVERSE和FETCH_UNKNOWN。FETCH_FORWARD是默认的正向读取数据。FETCH_REVERSE是反向读取,而FETCH_UNKNOWN是未知的读取方向,一般不使用。在实际的开发过程中通过Resulet对象的setFetchDirection()方法指定合适的数据读取方向,减少因定位数据而耗费的时间[10]。

ResuleSet提供了一系列的getXXX()方法获取当前记录行的某个特定字段的值。如果实际使用的方法与数据字段的类型不匹配,系统需要将字段值做类型转换,在查询返回大量数据的情况下,数据类型转换会造成时间消耗,从而导致性能低下。因此getXXX()方法要和字段类型的值相符。

3.5 在客户端缓冲数据行

默认情况下当执行查询操作时,每次都会将符合该SQL语句的所有记录返回给客户端。这样会带来两个问题:①如果数据量很大,会给客户端带来内存溢出风险;②如果再执行相同的查询时造成不必要的数据浪费,尤其是在客户端和数据库服务器位于网络环境中的情况下,会带来较大的网络开销。对于这种情况,可以调用Statement对象的setFetchSize(int counts)方法给客户端设置一个合适大小的数据缓冲行,这样由该Statement所创建的ResultSet对象在读取完缓冲的数据后就会以增量的方式从数据库获取下一次要缓冲的结果集,这样不但可以避免客户端内存溢出风险并且降低了网络开销,从而提高性能。

4 JDBC代码复用的优化方法

利用JDBC访问数据库通常需要经过5个操作:①加载JDBC驱动;②创建Connection对象;③创建相应的Statement对象;④执行SQL语句;⑤释放资源。根据分析得知:①②③⑤属于固定不变的操作;④属于可变的操作。根据模板设计模式的原理[11]:允许子类在不改变算法结构的前提下重新定义算法的某些特定步骤。所以,将上述不变的操作封装到一个抽象类中,将可变部分延迟到子类完成。由于数据库操作都是针对业务逻辑中的实体对象的,业界普遍使用Java EE规范所推荐的DAO模式,其中由DAO接口向上层调用者提供访问持久化层的入口,DAO实现类封装数据访问细节,目的是为了在业务逻辑层和数据持久化层之间解耦。考虑到数据库的移植性,将JDBC驱动类名称、数据库URL、用户名和密码、以及SQL语句等信息封装到配置文件中。综合上述分析,本文提出模板模式+DAO+配置文件的JDBC代码复用方法,该方法的类图关系如图4所示。

其中JDBCUtil类完成①②⑤的操作。对于整个应用而言JDBC驱动只需加载一次,所以JDBCUtil采用单例模式[12]设计,由该类自行实例化唯一的对象作为数据库访问的入口。dataSource是数据源,通过连接池创建,连接池的相关参数从配置文件获取,配置了连接池之后就可以通过dataSource代替DriverManager获取Connection对象;free方法关闭相关资源,对于Connection对象而言,close()方法会将其重新放回到连接池中而非销毁,这样可以达到重用的目的。

JDBCTemplate作为模板模式中的抽象类角色定义了通用的CRUD方法,通过RowMapper接口将可变操作延迟到了Daolmp类中。具体实体对象属性与表字段的映射关系由RowMapper接口中的mapRow()方法完成。鉴于篇幅限制,以查询操作为例给出对应的模板语句,如下代码所示。

DAO通常与实体对象是一一对应的,DAO接口定义相关实体对象的数据库操作方法,DAOImp实现DAO与RowMapper接口,通过关联的JDBCTemplate完成真正的数据库访问。这样开发人员只用专注于DAO的开发(操作④)即可,①②③⑤由JDBCUtil、JDBCTemplate和RowMapper已经完成,从而达到复用的目的。假定当前系统中有个用户实体,那么它对应的DAOImp的部分代码如下:

5 性能测试

硬件方面的参数:数据库为Oracle 11g,服务器操作系统为Window Server 2008,CPU为Pentium 3.0GHz,内存4 G;客户端操作系统为Windows XP,CPU为Pentium3.0 GHz,内存1G;10 M以太网。软件方面的参数:JDK版本为1.6,数据库连接池所需要的三个jar包是:commons-pool-1.6.jar、commons-collections-3.2.1.jar和commons-dbcp-1.4.jar。

5.1 设置预取行测试

为了表示预取行访问数据库的效率,分别进行两组实验。一组实验设置预取行的大小,并不断改变此数目的值,每改变一次值取10次测试的平均值;另一组实验不设置预取行。实验内容是遍历数据库表中的10万条记录,每条记录20个字节,不设置预取行时遍历结果大约在7000ms左右,预取行大小与响应时间数据如图5所示。

从图5可以看出,设置了预取行后能够明显提高数据库的访问效率,随着预取行值的增大响应时间也在不断缩短。在本实验条件下,预取值为3000~5000之间时,响应时间为最小;当超过5000后,响应时间基本不会产生变化了。fetchsize取值与读取的数据集大小、硬件平台和网络环境有关。fetchSize取值过小,响应时间过长;若fetchsize取值过大,则有可能会导致JVM内存溢出。

5.2 数据库连接池测试

以DBCP作为连接池技术的代表与传统的JDBC连接技术进行对比,版本为DBCP1.4。连接池的配置参数如表1所示。在服务器上分别进行两组数据库访问测试:一组进行连接池连接;另一组进行传统JDBC连接。测试的内容是客户端模拟一定的并发量进行连接的获取与释放,不涉及具体的数据操作。每次更改并发量进行5次测试取平均值。由表2可以看出,使用数据库连接池,对数据库的访问速度有了大幅度提高。

5.3 批处理测试

以插入1000条记录为例,以批处理操作与非批处理操作进行对比,批处理操作执行下列代码:

运行结果如表3所示。经过测试得出,批处理操作在大量数据处理时能够明显提高速度。因为在非批处理操作中共进行了1001次网络返回。其中第1次是预编译Statement,另外1000次往返执行每个循环。在批处理操作中,执行1000次addBatrh()操作,只有两次网络通信。第1次是预编译Statement,另一次是执行batch命令。虽然batch命令会占用更多数据库的CPU周期,但是通过减少网络通信提高了执行效率。

5.4 代码复用测试

将本文第4节的复用代码方式与传统方式的JDBC代码进行测试比较,完成一个普通数据表的CRUD操作。数据表包含三个字段:id int、name varchar(10)、password varchar(20),两种操作执行相同的SQL语句,其中查询、删除和更新操作都是按id进行的。通过JUnit单元测试工具对每个操作执行5次取平均值,如表4所示。经过测试发现,代码复用的方式比传统方式在JDBC的操作方面大约提高1.5~3倍左右的时间。

6 结束语

JDBC作为数据持久化层的一种解决方案,在Java EE开发中占据了非常重要的地位。为了提高数据持久化层的性能,本文从JDBC API的应用和代码复用两个方面研究了JDBC优化的若干方法,并通过实际测试证明了相关方法的有效性,能够为开发人员提供一定的借鉴意义。数据持久层的优化是一项涉及较多方面的系统工程,与它的相邻两层(业务逻辑层和数据库层)都有着密切的关系。例如在数据库层可以优化表结构、合理配置索引与视图等;在业务逻辑层尽量减少对数据持久层的调用,较少不必要的DTO对象和VO对象的创建等。总之,数据持久化层的性能优化,必须充分考虑系统的各个方面,进行周全的分析。

参考文献

[1]方兰英,陈兵辉,唐苗.基于JDBC的异构数据库迁移系统的设计与实现[J].北方工业大学学报,2013,25(1):5-10

[2]HONG Wen-qiang.CHE Chao,ZHANG Qiang.WEI Xiao-peng.Hibernate Combined TableViewer in the Application of Medicines Inventory Management SystemfJ].Computer Aided Drafting,Design and Manufacturing,2014,24(2);48-53

[3]欧阳宏基,葛萌.基于S2SH框架的煤炭企业生产统计管理系统[J].计算技术与自动化,2015,34(3):118-122

[4]张俐.基于ibatis和设计模式的数据持久层的应用[J].安徽大学学报:自然科学版,2010,34(3):43-48

[5]Cay S.Horstmann.Gary Cornell.Core Java.Volumn II:Advanced Features[M].China Machine Press,2012,190-193

[6]刘云玉,段中兴,原晋鹏.JDBC数据库重连机制的研究与实现[J].计算机应用与软件,2011,28(7):38-40

[7]Best practices to improve performance in JDBC[EB/OL].(2011-12-06).http://www.precisejava.com/javaperf/j2ee/JDBC.htm.

[8]霍占强,张锦程,王志衡.数据库连接池的数学建模与性能分析[J],计算机工程,2014,40(10):32-36

[9]和密密,孙忠林,张煜.J2EE架构下的海量数据访问技术研究[J].计算机与现代化,2011,12,89-92

[10]郝阳.高校教务管理网上选课系统优化研究[D].山东科技大学硕士学位论文,2011.

[11]刘伟.设计模式[M].北京:清华大学出版社,2011,401-402

用第三层交换保证数据安全 篇2

公司计算机网络配置为:服务器端是Windows NT Server ,客户端为Windows NT Workstation或Windows95/98;应用系统包括两个部分,第一部分是CAD/CAM/CAPP/PDM系统,另一个是企业资源计划管理(ERP)系统。中心机房有一台HP 6000作为Windows NT 主域控制器,同时也是ERP服务器,HP LH3作为一 立CAD Server,另外还有一台邮件服务器,一台网管服务器,一台用作出图的PC 机,所有的产品图纸集中在计算机中心出图。

安全要求

1. 为了防止CAD设计的产品图纸通过管理部门的计算机外泄,必须将两个应用系统划分到不同的网段分隔开来;

2. 整个系统只设一个主域控制器,中心机房的所有计算机属于CAD 网段,但又要求使用ERP服务器中的资源;

3. 公司级的主要领导属于ERP管理网段,但同时又要求管理和使用CAD网段中的资源。

用VLAN解决

以太网是基于CSMA/CD机制的网络,不可避免地会产生包的广播和冲突,由于数据广播会占用带宽,也影响安全,尤其在基于Windows的网络中,所以有必要减少网络中的广播,需要使用VLAN,

VLAN能将一个广播域划分为多个广播域,它的划分有三种方式,基于端口、基于MAC地址和基于网络协议。Cisco的解决方案是建议一个VLAN对应一个IP网段(TCP/IP网络),宜工目前采用的就是这种方式,并采用Trunk技术维持VLAN配置的一致性。Trunk是在交换机间或与路由间的点对点链路可同时传输多个VLAN数据,帮助把实现VLAN从一台交换机到另一台交换机的扩展。

在网络七层协议里,Hub是第一层设备,所连接的设备在同一冲突域和广播域内;交换机和网桥是第二层设备,所连接的设备在同一广播域内,每个端口是一个冲突域,所以交换机可以帮助减少冲突,并可实现双工通信,但不能减少广播流量;路由器是第三层设备,连接的设备在不同的广播域和冲突域内,可以通过路由功能控制广播和冲突。

三层交换简化设置

划分了VLAN后,不同VLAN间就不能通讯了,所以需要路由器来连接不同的VLAN,但有了第三层交换机后就不必再那么麻烦。Catalyst 4006是Cisco公司推出的一款较先进的企业主干网交换机,拥有第三层交换能力,既解决了VLAN通讯问题,又消除了路由器带宽低的痼疾。4006的三层交换功能在4232-L3模块上实现,与5000系列和6000系列不同,4000系列交换机的三层交换是采用内部的两个虚拟千兆连接完成的。

中心交换机上共设计了两个VLAN,分别为CAD和普通用户使用,网段为192.168.66.0和192.168.67.0。交换机为两个VLAN提供了第三层交换功能,同时利用静态路由列表将某些特殊地址加入,实施一定的安全策略。

在实际网络中,管理模块上的两个和4306-GB模块上的五个通过光纤连接二级交换机,提供主干千兆。从4006角度看6/1和6/2是两条实现路由功能的接口(我们的三层模块插在交换机第六个槽),而对于三层交换模块来说,这两个端口是连接4006的接口。

数据持久化层 篇3

摘要:宁夏固原地区为厚层黄土覆盖的山区,黄土层厚度达270m左右,其浅部干燥的黄土层速度低、厚度大,对地震波的激发和接收极为不利。根据该地区特点,通过大量的试验工作,确定了最佳的地震数据采集方法和参数,取得了较好的地震原始资料,最终查明了主要可采煤层的赋存情况和构造发育情况。为矿井建设、生产提供了可靠的地质资料。

关键词:厚层黄土;地震波;数据采集

在煤田地质勘探中,采用钻探、测井、地震等多种手段进行综合勘探,可以降低勘探费用、提高勘探精度和可靠性。然而,在厚层黄土覆盖区地震原始资料较差,勘探效果还不尽理想。针对这一状况,我们在宁夏固原地区对厚层黄土覆盖区地震数据采集方法进行了专题研究,以期解决这一难题。

1. 概况

宁夏固原地区某煤矿为黄土剥蚀丘陵地形,海拔标高+1720~+1860m之间,相对高差140m左右。由于区内黄土垂直节理发育,往往于沟谷两岸形成直立陡壁,加上水流的冲刷,沟谷纵横切割,形成黄土梁、塬、峁、谷、脊、柱等各种黄土地区的微地貌景观。地表条件极为复杂,因此表层地震地质条件较差。

区内全部被第四系黄土掩盖,地表无基岩出露,经钻孔揭露,其地层由老至新依次为:奥陶系中统平凉群、三叠系上统延长群、侏罗系、白垩系下统六盘山群、第三系和第四系。第四系黄土层厚度270m左右,其浅部干燥的黄土层速度低、厚度大,低速带速度平均400m/s、厚度在6.52~17.6m之间变化较大;降速带的速度平均为570m/s、厚度在0~65.1m之间变化很大;第四系高速层的速度平均为1860m/s,对地震波的激发和接收极为不利。所以浅层地震地质条件很差。

区内含煤地层为侏罗系中统延安组,为一套内陆湖泊三角洲沉积,全区发育。主要可采煤层5号煤层厚度为6.7m~14.43m,埋藏深度为300m~1100m;8号煤层厚度为2.66m~14.02m,埋藏深度为300m~1150m。煤层倾角一般在9°~30°。煤层与围岩密度和速度差异较大,有明显的波阻抗界面,能够产生能量较强的反射波。因此,深层地震地质条件较好。

2. 地震波激发、接收因素的试验

针对该区不同的表、浅层地震地质条件及深层地震地质条件,选择8个有代表性的点位进行了试验。

2.1 试验工作的基本参数

仪器型号:Aram-Aries多道遥测地震数据采集系统。

记录格式:SEG-Y。

采样间隔:1ms。

记录频带:全频带。

记录长度:2s。

前放增益:30 db。

震源:高爆速成型炸药柱,瞬发电雷管引爆,井中激发。

接收道数:240道。

道距:10m。

偏移距:0m。

发炮方式:中点激发。

2.2 试验内容

2.2.1 激发因素试验

井深:8m~85m。

药量:1kg~6kg。

组合井数:2~12。

组合药量:每口井1kg、2kg。

2.2.2 接收因素试验

前放增益:24、30db。

回放滤波:20、25Hz。

检波器:TZBS-60型高频检波器、TZBS-28型低频检波器。

检波器埋置:地表、0.5m深坑。

试验遵循单因素变化的原则。

2.3 试验结果

目的层反射波有:第四系底界反射波—TQ波,时间在130ms~360ms,其能量较强、连续性较好、视频为60Hz左右;5号煤层反射波—T5波,时间在310ms~860ms,其能量较强、连续性较好、视频为40Hz左右;8号煤层反射波—T8波,时间在340ms~890ms,其能量较强、连续性较好、视频为40Hz左右。

主要干扰有:面波能量较弱,速度为380m/s左右,视频20Hz左右,对近道目的层反射波有一定影响,它与目的层反射波有明显的速度、频率差异;直达波能量较强,速度为1700m/s左右,视频90Hz左右,对远道目的层反射波干扰较大;浅层多次反射——折射波能量较强,速度为1900m/s左右,视频50Hz左右,对远道目的层反射波干扰较大;以及微弱的高频微震随机干扰。

图1为在低洼的沟谷中试验获得的地震原始记录,激发、接收因素为井深12m,药量1kg,5井组合激发,TZBS-60型高频检波器接收。图中可以明显看出:TQ波在160ms左右,T5波在320ms左右,T8波在380ms左右,目的层反射波能量较强、连续性较好,易于辨认。

图2为在较高的山顶上试验获得的地震记录,激发、接收因素为井深90m,药量2kg,单井激发,TZBS-60型高频检波器接收。从图中可以看出:TQ波在180ms左右,其能量强、连续性好;T5波在420ms左右,其能量较强、连续性较好;T8波在460ms左右,其能量较弱、连续性较差。目的层反射波较明显,易于辨认。

综上所述,该区只要打穿第四系低速层和降速层,在高速层中激发,既能有效地压制各种干扰波,增强目的层反射波。沟底低洼处5井组合激发,井深12m、每口井药量1kg;山上较高处单井激发,井深90m、药量2kg;偏移距0m、前放增益30db、TZBS-60型高频检波器0m组内距三个串联线性组合接收可以获得较好的地震记录。

3. 弯曲测线的施工方法可行性分析

当直测线穿过黄土覆盖较厚的山区,不能取得较好的地震资料时,可考虑沿着低洼的沟底采用弯曲测线的施工方法。弯曲测线的施工方法应用前提是沟谷较多、能够相互连接成网,并且沟谷内黄土覆盖较薄、浅井激发能够获得较好的地震资料。

该区中部为东西分水岭,地势较高,黄土覆盖较厚,虽然冲沟较多,但不能相互连接成网。并且大多冲沟内黄土覆盖较厚、浅井激发不能能够获得较好的地震资料。浅井激发能够获得较好地震资料的沟谷仅有三座水库附近的三条沟谷,它们延伸较短,长度均不到2km,并且相互独立,不能相互连接成网。因此,采用弯曲测线的施工方法不能完成该区地质勘探任务。

4. 段试验工作及地震资料处理

经过以上点试验和综合分析,该区采用二维直测线的施工方法较合理。为了进一步验证点试验所确定的工作方法的合理性,研究论证地震勘探在该区能否完成地质任务,在D19线(10线)15号钻孔至1001号钻孔,长度800m,采用点试验确定的最佳激发、接收因素,道距10m,炮距40m,中点激发,偏移距0m,两条平行线160×2=320(下转137页)(上接118页)道宽线接收,线距10m,叠加次数20×2=40次,进行了段试验工作。

在资料处理时,采用常规处理流程,不加任何修饰性手段,分别做了不同接收道数、不同激发方向、不同偏移距的单线、宽线处理,用以确定合理、经济的地震数据采集方法。

图3为经过资料处理获得的地震时间剖面,从图中可以看出:TQ波在200ms左右,T5波在360ms~440ms左右,T8波在400ms~480ms左右。各目的层反射波能量强、连续性好、易于辨认。

5. 结语

通过上述的试验和分析,可以得到以下几点结论:

(1)在厚黄土山区,地形低洼处采用浅井5井组合激发,井深12m、每口井药量1kg;山上较高处采用深井单井激发,井深90m、药量2kg;可以获得较好的地震资料。

(2)该区煤系地层以向、背斜相间出现为主要构造形态,因此,在观测系统的设计方面应该以中间发炮较为适宜。

(3)40m炮间距双线接收和20m炮间距单线接收获得的时间剖面煤层反射波的信噪比和连续性均较好,能够可靠地反映出煤层构造形态。为了降低勘探费用和提高工作效率,该区采用40m炮间距双线接收的宽线施工方法较为合理。

(4)该区采用0.5m深坑埋置TZBS-60型高频检波器,0m组内距三个串联线性组合接收,偏移距0m、前放增益30db可以获得较好的地震资料。

数据持久化层 篇4

1 DAO设计模式

设计模式这一概念源于建筑学领域, 目的是为重复出现的问题提供一种最佳解决方案。在软件开发领域, 设计模式表现为一组精心安排的通用的类和对象, 再经过定制和实现就可用来解决特定上下文中的问题。

DAO (DataAccessObject) 模式称为数据访问对象模式, 通常应用于数据库操作的业务逻辑代码中。该模式的本质是向外部提供一个访问数据源的统一接口, 对外隐藏操作数据源的实现细节。这是因为在实际的应用过程中, 应用程序所面对的数据源往往是多种多样的。不同数据源的连接方式、数据访问方式会有明显的差异。这就导致了需要访问数据源的组件的代码实现方式与数据源的类型有着密切的关系。组件和数据源之间的这种紧耦合关系也就导致了整个应用系统难以在不同数据源之间进行迁移。使用了DAO模式后, 即使系统需要进行数据源的迁移, 也只需在DAO模式内部进行数据源访问代码的修改, 而不会涉及上层调用代码, 这样就提高了软件的可维护性。

在图1所示的DAO模式类图中, BusinessObject代表的是一个需用访问数据源的业务对象, 这个对象可以由EJB或JavaBean组件来实现。业务对象使用DAO模式来访问数据源。DataAccessObject包括接口和接口的实现类。接口中定义要访问数据源的抽象方法, 实现类中应用一种具体的数据源访问API来实现抽象方法。

TransferObject类代表了一个数据传输对象, 它负责在数据源和业务对象之间进行数据的封装和传输, 一般使用DTO (DataTransferObject) 模式实现。因为, 在大型分布式多层应用系统中强调层与层之间的松散耦合, 并不建议直接将从数据源获得的数据传给业务对象或将需要保存的数据交由DataAccessObject进行持久化。TransferObject相当于业务逻辑层与数据持久化层之间的一个隔离, 合理地使用可以达到减少网络传输流量、提高系统性能的目的。但是在并发用户量少、业务逻辑简单的应用中, TransferObject可以省略。

2 Hibernate框架

2.1 Hibernate原理

Hibernate对JDBC进行了轻量级的对象封装, 使得Java程序员可以使用面向对象的思维来操作关系数据库[2]。它不仅管理Java类到数据库表的映射, 还提供数据查询和获取的方法, 可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。它还拥有一种功能强大的查询语言HQL, 这种语言与SQL非常相似, 便于开发人员掌握, 它是完全面向对象的, 查询的是持久化对象。更重要的是, Hibernate支持大部分主流关系型数据库, 支持父/子关系、事务处理、继承等。

2.2 Hibernate核心接口

利用Hibernate进行数据持久化操作, 至少会用到如图2所示的核心接口[3,4]。

Configuration接口用来配置和引导Hibernate。Hibernate应用程序通过Configuration实例来指定对象-关系映射文件的位置与Hibernate的特定属性, 然后创建SessionFactory实例。

SessionFactory基于工厂模式而建立, 它是产生Session实例的工厂类。SessionFactory在初始化过程中将从Hibernate的配置文件中读取对当前数据库所定义的所有映射文件, 并将它们编译后保存在内存中。为了节省系统资源, 在程序初始化的过程中只产生一个SessionFactory实例, 多个线程可以并发调用以实现SessionFactory实例的共享。

Session接口是Hibernate进行持久化操作的基础, 相当于JDBC中的Connection对象所起的作用。Session提供了一系列的持久化操作方法, 例如save () 、update () 、delete () 和find () 等。Session还包含了一个针对持久化对象的一级缓存, 在遍历持久化对象或者根据持久化标识查找对象的时候将会使用到。

Transaction接口实现对数据库中事务的控制, 它为用户提供了进行持久化操作的原子操作单元范围的设置功能。通过Transaction接口, 用户可以将多个持久化操作组合成一个原子操作, 使这些操作要么全部执行, 要么全部不执行。

Query和Criteria接口是Hibernate的查询接口, 用于查询持久化对象, 以及控制执行查询的过程。Query实例包装了一个HQL (HibernateQueryLanguage) 查询语句, 它与SQL查询语句有些相似, 但HQL查询语句是面向对象的, 它引用类名及类的属性名, 而不是表名和表的字段名。

3 数据持久化层设计原则与模型

3.1 数据持久化层设计原则

数据持久化层的设计目标是为整个系统提供一个高层、统一、安全和并发的数据持久化机制。从目前JavaEE多层结构的可维护性和灵活性考虑, 完善的数据持久化层应该达到以下目标[5]:

(1) 完成对各种数据进行持久化的编程工作, 并为系统业务逻辑层提供访问数据持久化层的接口。

(2) 如果需要的话, 能够支持多种数据源平台。即数据存储方式的变化, 不会影响持久层的实现。

(3) 尽量减小数据库访问对整个应用产生的性能瓶颈。

为了达到上述目标, 构建一个可扩展性强、可维护性高的数据持久化层, 本文结合DAO模式与Hibernate框架构建了一个数据持久化层模型。

3.2 数据持久化层模型

由于Hibernate支持与几乎所有主流的关系型数据库之间的映射, 采用面向对象的查询语言-HQL来操作关系型数据库。在HQL语言中不会出现像SQL语法差别的情形, 因为Hibernate在配置文件中提供了与具体某一关系型数据库SQL“方言”转换的配置方法。通过这种配置, Hibernate会自动将HQL语言转化为具体关系型数据库所使用的SQL语言。所以在数据存储采用关系型数据库的应用中, 可以在DAO实现类中封装HibernateAPI来完成与持久化类相关的业务逻辑操作。图3为本文所建立的数据持久化层模型。

数据持久化层的业务流程为:业务逻辑模块调用DAOFactory, DAOFactory生成相应的DAO, DAO里通过HQL语句操作PO。Hibernate把HQL转换为SQL, 通过O/R映射文件实现对关系型数据库的操作。

4 数据持久化层的实现

咸阳师范学院计算机科学系《大学生科研立项管理系统》的数据持久化层采用上一小节所提出的模型而构建。本节结合部分源代码来详细论述该模型的实现。

4.1 配置文件与映射文件的实现

Hibernate配置文件与映射文件基于XML文档实现, 它们是实现持久化工作的主要内容之一。在一个具体应用中配置文件只能有一个, 而映射文件有多个。

(1) Hibernate配置文件的实现

Hibernate配置文件的主要工作是进行SessionFactory配置、关系型数据库“方言”与加载持久化类对应的映射文件等。Hibernate初始化期间会自动寻找这个文件, 并读取其中的配置信息, 为后期数据库操作做好准备。

(2) 映射文件的实现

映射文件用来声明Hibernate中持久化类的属性与数据库对应表之间字段的映射关系, 该文件中声明的属性名称要与对应数据表中的字段名称相同, 同时要与持久化类中所包含的属性名称相同。下面是科研立项的持久化类keYanInfoPO与数据库表t keYan之间的映射文件的部分源码。

4.2 持久化类的实现

持久化类的对象 (PersistenctObject, PO) 是一个简单Java对象 (POJO) , 一个PO代表了与数据库表中某条记录相对应的Hibernate实体[6], PO的变化在事务提交时将反映到实际的数据库表中。下面是科研信息所对应的持久化类的部分源码。

4.3 DAO模式的实现

DAO模式的实现包括两部分:一是DAO接口的定义。DAO接口中定义了特定持久化类所对应的抽象业务逻辑方法。二是DAO接口的实现类。该类利用HibernateAPI实现DAO接口所定义的抽象方法。这样设计的优点在于:当改用其他的持久化机制或持久化中间件时 (例如, 出现了更好的ORM框架) , 由于DAO向上层调用者提供的接口不会变化, 只需创建新的DAO实现类而无需更改应用中的业务逻辑代码。

1.科研项目信息所对应的DAO接口的部分源码如下:

2.科研项目信息DAO接口的实现类部分源码如下:

在DAO实现类中使用了HibernateUtil工具类, 它所包含的所有方法均为静态方法, 这些方法包含了获得Session对象、开始事务、结束事务、关闭Session等一系列Hibernate操作数据库的方法, 并且定义了两个静态的ThreadLocal实例来分别管理Session与Transaction, 保证在一次请求过程中只创建唯一的Session与Transaction实例。

5 结束语

论文设计了一种结合DAO设计模式与Hibernate框架相结合的数据持久化层模型, 并将该模型成功应用于大学生科研训练计划系统中。该模型对外封装了数据持久化操作的细节, 对内调用HibernateAPI完成对象/关系映射工作, 实现了面向对象技术操作关系型数据库的目的。该模型能够方便地在不同关系型数据库之间迁移, 甚至更换新的持久化策略, 系统也能轻松维护。

参考文献

[1]朱连章, 杨杰.对象/关系映射的基本策略, 微计算机应用.2006, 27 (5) , 584

[2]李小平, 肖岳峰, 宿元, 宋瀚涛, 姚永标.基于J2EE多层架构的Web开发框架研究, 计算机应用研究, 2008, 25 (5) :1430~1431

[3]邱哲, 王俊标, 马斗.Struts Web设计与开发大全.北京:清华大学出版社, 2006, 100~101

[4]苏芬平, 刘更, 王海伟.数据库管理系统持久层的Hibernate解决方案.计算机工程与设计, 2008, 29 (12) :2991~2992

[5]欧阳宏基.利用Struts与Hibernate框架构建Java Web应用的研究与实现.西安科技大学硕士学位论文, 2007.29~35

模型驱动在数据持久层开发中的应用 篇5

1 数据持久层的开发

1.1 数据持久层

一般的J2EE架构会被划分为三层:表现层,业务层,数据持久层。其中数据持久层则是负责各种数据的持久化操作。由于目前使用最多的仍然是采用关系数据库存储数据,所以数据持久层主要是针对关系数据库的操作。随着优秀的开源的ORM工具的出现,面向对象的开发方式可以被很好地应用到数据持久层的开发中。通过对象关系映射,所有的数据持久化操作可以直接针对一系列的域对象。Hibernate就是其中最优秀的ORM工具之一。

1.2 应用ORM需要注意的问题

把关系模型中的一个个数据表映射为一个个对象,需要编写映射文件。通过映射文件把关系和对象二者关联起来。显然,三者必须时刻保持一致,否则就会出现问题。使用对象关系映射,就必须维护对象和关系的同步。

1.3 数据驱动开发在数据持久层开发中的缺点

所谓数据驱动开发,是以识别数据通用性为中心的开发方法,它是通过建立一个数据模型和建立比直接应用更广泛的程序实现的。即根据对业务的分析建立数据模型来进行系统设计的一种方法。受这种开发方式的影响,目前J2EE架构中数据持久层的开发,首先是去建立关系数据模型即设计数据库,然后通过ORM工具把关系映射为对象。

根据数据驱动的系统设计以及实现方式,数据驱动适合于数据型的应用系统的建设,这类系统的共同点就是系统主要包括信息的录入、显示、查询以及编辑这样的一些数据操作,不存在复杂的数据业务逻辑处理。但是在面对较为复杂的业务逻辑处理时,通过建立关系数据模型去进行系统设计就显得很吃力。此时,关系数据模型应该应用于它所擅长的持久化功能而不是系统分析层面。

2 模型驱动开发

模型驱动开发是根据对业务的分析建立业务对象模型来进行系统设计的一种方法,通过业务对象模型结合系统架构约束来进行系统的实现。一般来说,在采取模型驱动的系统中多采用N层的结构体系,前台显示一般和业务显示模型进行交互,而业务显示模型则通过与业务对象模型交互来完成业务逻辑的处理,业务对象模型通过与持久对象模型进行业务持久的处理,在这样的情况下,势必增加了系统的复杂度,模型驱动适合于业务型应用系统的建设。这在行业化的业务应用上显得比较突出,这类系统的共同点在于业务逻辑较为复杂而且多变。

模型驱动开发以模型为中心,而模型是指以精确定义的语言对特定的系统做出的描述。目前应用最广泛的是用UML来描述模型。使用UML的静态图来进行系统设计就使得我们完全以面向对象的思维去解决问题。相比较数据驱动开发模型驱动开发的主要优点是:<1>系统设计和描述更符合现实。<2>更容易满足业务逻辑较为复杂和多变的需求。<3>使整个系统开发具备了面向对象开发的所有优点。

3 模型驱动开发在数据持久层中的应用

以下将通过一个基于J2EE架构的权限管理系统中数据持久层的建立来展示如何在数据持久层开发中应用模型驱动开发。

3.1 开发过程

采用模型驱动进行开发数据持久层通常采用的是一个这样的过程:首先,根据具体业务需求进行建模,通常使用UML静态图来描述基本业务对象之间的关联关系。这里的对象一般是POJO,不涉及具体的业务逻辑处理。然后,根据模型,编写带有XDoclet标签的Java类代码。再就是,使用XDoclet自动生成对象关系映射文件。最后,通过Hibernate中的工具Schema Export Task把对象关系映射文件再自动生成数据库中的数据表。

3.2 在权限管理系统中的应用

3.2.1 RBAC模型

本权限管理系统基于R B A C模型设计。RBAC(Role-Based Access Control)模型的基本思想就是根据安全策略划分出不同的角色,资源访问许可被封装在角色中,用户被指派到角色,用户通过角色间接地访问资源。RBAC的最大优点在于它能够灵活表达和实现组织的安全策略,使管理员从访问控制底层的具体实现机制中脱离出来,十分接近日常的组织管理规则。RBAC被认为是一种更普遍适用的访问控制模型,可以有效地表达和巩固特定事务的安全策略,有效缓解传统安全管理处理瓶颈问题。其中RBAC96模型如图1所示。

3.2.2 参照RBAC模型以及实际需求对权限管理系统进行建模

此权限管理系统把权限管理和组织机构管理结合起来,分配给用户的角色来自于部门,部门和角色之间是一对多的关系。权限许可是针对某一权限资源对象和权限操作,所以权限许可和权限资源对象以及权限操作都是一对一的关系。通过Borland公司的建模工具Together,将权限管理系统模型建立如图2。

3.2.3 根据所建模型编写带有XDoclet标签的Java类代码

XDoclet是一款开源的代码生成引擎,它使得Java能够面向属性编程。通过向Java源代码添加XDolcet标签,能够自动生成一些我们需要的代码或xml文件,由此可以提高编码效率。

根据图2,权限管理系统中基本的Java类有User、Role、Permission、ResourceObject、PrivilegeOperation、ResourceObejectType、Department、Post、Employee等。其中Role类很关键,其部分代码如下:

3.2.4 编写Ant任务文件,自动生成映射文件和数据表

Ant也是一种开源的基于Java的部署工具,它通过读取XML文件中tasks和targets来执行任务。通过编写其配置文件,可以实现程序的编译、运行、测试和部署等一些列工作的自动化。在权限管理系统数据持久层的实现过程中,我们可以利用ant使生成映射文件和数据表实现自动化,从而保证了关系和对象的同步。我们编写的ant配置文件build.xml中的主要部分如下:

当运行该build.xml文件后,将自动生成系统中所有基本业务对象相应的映射文件,然后再在数据库中自动生成所有的数据表。当我们对模型有所改动时,只需要再运行一次build.xml就是了,这样就很好的解决了关系对象的同步问题。

经过以上步骤,系统中所有的数据持久化操作就可以针对模型中基本的业务对象进行,面向对象的威力得以完全发挥。

总结

模型驱动开发较传统的数据驱动开发在很多应用中都有着明显的优势。我们把模型驱动应用在了J2EE架构数据持久层的开发中,最大限度地发挥了面向对象开发的优势。在具体应用时,通过使用ORM工具Hibernate以及开源工具XDoclet和Ant,实现了对象关系影射的自动化,很好地解决了对象关系的同步问题。

参考文献

[1]董洪杉,窦延平.利用Hibernate的J2EE数据持久层的解决方案.计算机工程[J].2004,30(增刊):17-18.

[2]戴祝英,左禾兴.基于角色访问控制模型分析与系统实现.计算机应用研究[J].2003,(9):173-175.

[3]郝玉龙等.J2EE编程技术[M].北京:清华大学出版社.2005.

[4]蔡明,陈明远.J2EE架构的研究与应用,计算机应用与软件[J].2004,21(1):42-43.

[5]孙卫琴.精通Hibernate:Java对象持久化技术详解[M].北京:电子工业出版社.2005.

数据持久化层 篇6

1问题描述

对比CMP,JPA采用POJO作为实体对象,不需要实现EJBObject、EJBLocalObject、EJBHome和EJBLocalHome等众多接口,能够支持面向对象的高级特性,例如类之间的继承、多态,而且支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常SQL才提供的高级查询特性。本节以消费者(Customer)和信用卡(CreditCard)为例,说明从CMP移植到JPA过程中可能发生的逻辑错误。假设Customer和CreditCard是一对一双向关联关系,Customer实体关联CreditCard实体,CreditCard实体反向关联它的持有者。

采用CMP技术作为数据持久层,通常调用EJBHome的create的函数初始化Customer的实例cust和CreditCard的实例card,执行cust.setCard(card)后,按照EJB规范中的关联关系赋值规则,EJB容器会建立cust与card的引用,同时自动建立card与cust的关联关系,即判断card.getCustomer()==cust结论为真。

采用JPA技术作为数据持久层,直接使用POJO类初始化函数初始化Customer的实例cust和CreditCard的实例card,执行cust.setCard(card)后,仅仅建立了实例cust指向实例card的引用,即判断card.getCustomer()==cust结论为假。

CMP的实体类是虚类,EJB容器按照EJB规范实现CMP的实体虚类,实现了规范中的赋值规则,而JPA采用POJO作为实体类,只实现了简单的字段存取功能。在对遗留系统移植过程中,如果忽视关系赋值规则,可能发生严重的逻辑错误。

2CMP关系赋值规则

CMP实体组件间存在四种关联关系:一对一、一对多、多对一和多对多。每种关系按照双向关联和单向关联共存在七种可能的关系类型:一对一双向、一对一单向、一对多双向、一对多单向、多对一单向、多对多双向和多对多单向关联关系。由于多对一双向和一对多的双向关联关系是相同的概念,因此将它们合并为一种关系类型。

为了形象描述CMP关联关系赋值规则,本文采用直观的图示来描述:以大写字母A和B表示CMP实体对象;以小写字母后接数字a1,...,an,b1,...,bn表示CMP实体对象的实例;方法getA或者getB返回的是A或者B对象的实例或者实例集合;方法setA或者setB设置对象A或者B实例或者实例集合;实心箭头表示引用;表达式表示执行的操作;空心箭头表示执行表达式后的实例之间的关联状态。图1~图6展示了七种类型的关联关系的赋值规则。

对于a.setB(b)赋值操作,本文称a为引用方,b为被引用方,a的原引用方bOld,b的原引用方aOld,b到a的关系为a到b的逆向关系。关联关系赋值规则具有以下特点,具体见表1:

(“√”代表建立关系;“×”代表删除关系;“―”代表无操作)

表1中有特别之处,对于一对一单向和一对多单向关联关系的赋值操作包含有删除aOld→b关系,因此对于一对一单向和一对多单向关联关系存在着隐式逆向关联关系,否则仅仅从关联对象b无法获知其原关联对象aOld。

3解决方案

JPA采用的是POJO作为实体对象,它对于实体对象中字段的存取函数的实现比较简洁,例如获取函数方法体一般直接返回实体对象类中的成员变量,设置函数方法体一般直接将输入参数直接赋值到实体对象类中的成员变量。从上节对CMP关系赋值规则的分析,对遗留系统中CMP数据持久层向JPA移植过程中,如果忽视CMP实体间的关联关系赋值规则,则会引起严重的逻辑错误。本文将通过增强POJO实体源代码的方法来保证移植应用的逻辑一致性。本节首先描述源代码增强算法,然后给出算法实现方案,最后介绍测试用例。

3.1算法描述

本文使用伪代码描述算法,描述三种重要操作的算法:赋值操作、集合对象的增加(add)和删除(remove)操作。相关符号定义如下:R(a, b)表示a对b的关系;AddRelation(a, b)表示建立a到b的关系;DelRelation(a, b)表示拆除a到b的关系;(1n)表示一对多双向关系。算法中不区分显式关联关系和隐式关联关系,忽略取值为空等异常情况的判断。

(1)赋值操作a.setB(b)

BEGIN a.setB(b)

(2)集合增加元素a.getB().add(b)

(3)集合删除元素a.getB().remove(b)

3.2算法实现

本文采用Eclipse的抽象语法树AST[6](Abstract Syntax Tree)工具对JPA的简单Java对象进行源代码级的增强。抽象语法树采用XML直观地表示源代码的语法结构,对AST遍历和操作十分方便。

根据EJB规范,CMP中的集合对象类型只可能是java.util.Collection和java.util.Set两种类型,使用JDK(Java SE Development Kit)中的集合实现类ArrayList、LinkedList、HashSet、TreeSet等是无法满足CMP的关联关系赋值规则的,必须新实现这两个集合类接口。本文通过继承java.util.ArrayList实现java.util.Collection接口,通过继承java.util.HashSet实现java.util.Set接口,为了保证正确处理关联关系的赋值规则,重写六个函数add、addAll、remove、removeAll、clear和retainAll。函数add和remove为基础函数,其他函数包括addAll、removeAll、clear、retainAll的实现是对元素逐个迭代调用add和remove基础函数完成元素的添加或删除与元素对应的逆向关联关系的建立或者删除。

使用AST工具对简单Java对象的代码级增强过程如下:逐个读取简单Java对象源文件,遍历源文件,查找到关联关系的设置函数,读取函数声明前的注释(Annotation),获取关联关系类别及关联方向,在函数体内加入本文提出的算法。对于简单Java对象中的集合对象变量,均以本文新实现的集合对象初始化。对于一对一单向和一对多单向关联关系,需要在简单Java对象中加入非序列化(transient)字典(Map)变量,记录隐式关联关系。

3.3测试

按照上述七类关联关系的图例,依次编写测试用例[7],部署到EJB3应用服务器中,进行容器内测试。本文以图1所示的一对一双向关联关系赋值规则为示例主要测试用例如下:assurtTrue((b2==a1.getB()) && (a2.getB() == null) && (b1.getA() == null) && (a1==b2.getA()))。经过测试,证明本文提出的源码增强方法能够满足CMP原有的赋值规则。

4总结及下一步工作展望

本文分析了EJB2.0和EJB2.1中容器管理Bean的关联关系赋值的复杂规则,针对CMP向JPA移植过程中可能发生的逻辑错误问题,提出了对JPA中简单Java对象进行源代码增强方法,保障了移植遗留应用的逻辑一致性。JPA和JDO以及Hibernate等O/R mapping框架都非常相似,该方法亦适用于CMP向Hibernate、JDO等ORM映射工具的移植。下一步工作是将本文提出的算法采用面向方面的编程(AOP)技术和Java字节码增强[8]技术动态加入到事务环境中,使得POJO关联关系的赋值规则只在事务环境内有效。

摘要:针对EJB2的容器管理Bean向Java持久化API移植可能出现逻辑错误的问题,全面归纳了容器管理Bean之间七种类型的关联关系的赋值规则,提出了处理各种关联关系赋值规则的通用算法,利用Eclipse的抽象语法树工具实现该算法,对Java持久化API的简单Java对象的源代码自动修改,保障了移植后的应用与基于EJB2技术的遗留系统的逻辑一致性。

关键词:容器管理Bean,JAVA持久化API,赋值规则,抽象语法树

参考文献

[1]何成万,余秋惠.JDO初探.计算机工程,2002,28(6):282~283,286

[2]邢波.用ibatis提升一类数据库检索查询的性能.计算机应用与软件,2007,24(12):205~207

[3]田坷,谢世波,方马.J2EE数据库持久层的解决方案.计算机工程,2003,29(22):93~95

[4]Sun Microsystems.JSR-000220Enterprise JavaBeans v.3.0[EB/OL].[2006-5-8]http://jcp.org/aboutJava/communi-typrocess/final/jsr220/index.html.

[5]Sun Microsystems.Enterprise JavaBeans Specification Version:2.1[EB/OL].[2003-11-24].http://java.sun.com/prod-ucts/ejb/docs.html.

[6]G.Fischer,J.Lusiardi,J.Wolff von Gudenberg.Abstract Syntax Trees-and their Role in Model Driven Software Development.International Conference on Software Engineering Advances(ECSEA'07),2007,pages:38.

[7]郑人杰.计算机软件测试技术.北京:清华大学出版社,1992.

数据持久化层 篇7

在企业项目开发中, 数据库技术是最为基础的一项技术,Java之所以被企业广泛的应用,与其方便快捷的数据库操作技术有直接关系。 Java语言通过JDBC实现数据库连接和CRUD操作。但是,如果直接通过JDBC技术进行数据库操作会产生大量重复的代码,降低编程效率, 数据访问层维护困难等问题, 所以在企业开发中经常将JDBC封装成操作方便的持久层框架,然后由程序进行调用。 本文主要讨论持久层框架Mybatis的具体应用。

2持久层框架

2.1什么是持久层

数据持久化是指将数据永久的存储在计算机的硬盘中,而在软件开发中,通常这些数据被存储在数据库中。 持久层是专门负责数据持久化的逻辑层,提供对数据库的CRUD操作。

2.2常见持久层框架

很多企业为了简化数据库操作,将对数据库操作封装为软件框架,Java语言成熟的持久层框架非常多,而且这些框架大部分是开源的, 其中非常典型的框架是Hibernate和Mybatis。 Hibernate框架无需用户编写SQL语句就可以实现ORM(实体关系映射),编程人员完全以面向对象的编程思想进行数据库操作,它提供较为完整的JDBC封装,但这也限制了用户灵活的运用SQL进行数据库的操作, 如果用户需要进行复杂的查询操作,反而会给用户制造更大的麻烦,学习成本被大大提高。

3 Mybatis框架技术

My Batis是集成SQL查询、存储过程调用和高级映射的持久层框架, 它封装了几乎所有通过手工设置的JDBC代码, 通过简单的XML配置和注解将Java的POJOs映射成数据库中的记录。

3.1 Mybatis的架构

(1)基础层:负责配置文件加载、数据库连接管理、 事务管理和缓存处理,这些作为数据处理层的支撑。

(2)数据处理层: 负责SQL语句的生成、 解析和执行,实现数据库记录和Java实体进行映射,根据用户请求执行对数据库的CRUD操作。

(3)API接口层:提供了大量的API,开发人员通过这些API接口更加方便的对数据库进行操作。

3.2 Mybatis的应用流程

Mybatis实现实体关系映射主要是基于XML配置, 它给用户提供了非常便捷的应用流程,如图1所示。

3.2.1编写主配置文件

主配置文件是Mybatis接入项目的初始文件, 这个配置文件默认的名字是“mybatis-config.xml”文件,主要配置数据数据库连接、事务处理模式、缓存方式和ORM映射文件等内容。

3.2.2建立SQLSession

与Hibernate相同,Mybatis对数据库的操作定义为一个会话过程,所以用户在再执行数据操作之前需要建立会话。在建立会话之前首先要构建 “SQLSession Factory”实例,这个实例创建的过程的同时加载主配置文件,构建数据库连接池,打开数据库链接。 通过 “SQLSession Factory” 的 “open Session” 方法建立 “SQLSession”实例,从而完成会话的创建。

3.2.3配置ORM(实体关系映射)

ORM的配置在Mybatis的体系中起到关键作用,通过配置查询、增加、修改和删除等操作,实现关系数据库和实体进行对应,在实际开发中通常对一个实体的操作配置在一个ORM文件中,这个文件被配置在主配置文件中,以下是查询的ORM配置代码:

“parameter Type” 和 “result Type” 分别是参数类型和查询结果类型,其中“result Type”可以是List、Map和实体等任何类型, 用户可以根据需求设定, 也可以利用result Map配合<result Map> 实现更加复杂的查询结果类型匹配。

在配置中可以结合ONGL实现动态SQL, 以上代码中的“IF”标签实现了如果条件满足的情况下增加查询条件。 另外,配置文件还提供了<SQL> 标签,它允许用户将SQL代码库注入到配置文件中, 通过以上的方式能够更加灵活的进行查询的配置

3.2.4数据库访问

Mybatis提供了丰富的API进行数据库访问, 这些方法主要通过SQLSession实例进行调用, 表1是常用的API。

3.2.5关闭Session

数据库操作完毕后,会话实例通过调用close方法关闭本次会话。 会话的关闭代表一次数据库访问的完成,合理的打开连接和关闭会话可以有效的节省系统资源。

4 Mybatis优势和劣势分析

4.1 Mybatis优势分析

Mybatis是开源免费,轻量级框架。 通过Mybatis的工作流程可以知道它非常容易上手,学习成本低,解除了SQL和程序代码的耦合,支持动态SQL,用户可以灵活的运用SQL进行数据的查询, 更符合对于SQL掌握较好的用户。 用户可以在他的基础之上继续封装满足自己需求的持久层。

4.2 Mybatis的劣势分析

Mybatis的缺点也非常明显, 它需要用户书写较多的SQL代码,这对于数据库的移植是个很大的问题,要求用户对于SQL语言掌握的非常纯属, 对于级联操作的支持不好,对于复杂的查询更多依赖用户的逻辑。

5结束语

本文从技术架构和应用流程两方面对于Mybatis进行了详细的论述, 分析了Mybatis的优势和劣势。 Mybatis作为持久层框架没有放弃SQL, 它允许用户更多的通过SQL实现ORM,这种模式虽然灵活,但在开发一个相对成熟的项目中会大大降低工作效率,所以企业如果使用Mybatis, 需要根据自己项目的实际情况对Mybatis进行再次的封装, 让数据库访问更加简洁和实用,从而提高工作效率。

摘要:数据库访问是软件开发中必不可少的技术环节,Java语言之所以能够在企业中占领非常重要的地位,这与其方便快捷和高可扩展性的数据库操作有很大关系。论文主要讨论如何使用Mybatis建立持久层。文中首先阐述了什么是持久层框架,然后从架构和应用流程两方面详细论述了Mybatis技术,最后分析了Mybatis存在的优势和劣势。通过论述可以得出结论:Mybatis完全可以满足企业需求,企业需要在它的基础之上进行再次的封装,从而提高数据库访问编程效率和持久层的成熟度。

关键词:Mybatis,持久层,实体关系映射,框架

参考文献

[1]王钱,王蓉等.基于ibatis的通用数据持久层的研究与设计[J].微计算机信息,2007,23(43),172-173页.

[2]徐雯,高建华.基于Spring MVC及Mybatis的Web应用研究[J].微型电脑应用,2012,28(7),1-5页.

数据持久化层 篇8

Java语言是面向对象编程语言,在编写代码时运用的是面向对象的编程思想,而在通过JDBC操作数据库时,运用的则是面向过程的编程思想。Hibernate是一个开放源代码的对象关系映射框架,通过对JDBC进行了轻量级的对象封装,使得Java程序员可以使用对象编程思维来操纵数据库。Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化。Hibernate还可以应用在任何使用JDBC的场合,既可以在Java的客户端程序获得使用,也可以在Servlet/JSP的Web应用中加以运用。Hibernate持久层技术的出现,使得操作数据库时运用的依然是面向对象的编程思想。只是在运用的过程中,要通过正确的方法和策略,尽量降低Hibernate对性能的影响,在实际的开发时要考虑对其性能进行优化,使其发挥最大的效用。

2 Hibernate优化方案实施

大多数开发机构经常采取创建各自独立的数据持久层。一旦底层的数据结构发生改变,那么修改应用的其余部分使之适应这种改变的代价将是十分巨大的。Hibernate适时地填补了这一空白,为Java应用提供了一个高效、易用的对象关系映射框架。Hibernate是个轻量级的持久性框架,功能却非常丰富。在开发Hibernate持久层时,下面介绍五个性能优化方案

2.1 方案1—优化配置持久化类映射文件

(1)合理选择主键生成策略

影响选择主键生成策略的因素有很多,比如底层数据库的类型、主键的内部含义等。如果主键没有什么含义,只是用一个int型数据来唯一标识记录,而底层数据库又是SQL Server2000,则完全可以采用数据库的自增策略,而不需采用Hibernate的自增策略;如果主键具有内部含义,比如学生的学号,则需要由程序控制生成。

(2)优化配置持久化对象之间的关系

能否合理配置持久化对象之间的关系,将显著影响软件的性能。最常用的关系是一对多关系,一对多关系又分为单向和双向,单向关系又分为从一方到多方的映射和从多方到一方的映射。

在软件开发时,不要将所有的一对多关系都配置成双向关系,需根据实际情况而定。如果软件中只需要从一方映射到多方,则只要建立从一方到多方的映射即可;如果软件中需要多方映射到一方,则只建立从多方到一方的映射;只有两者都需要时,才会建立一对多的双向关联。

2.2 方案2—优化批量增删改操作

在软件开发过程中,经常会遇到批量操作数据的情况,如果不能合理进行这些批量操作,将对软件的性能产生重大的影响。

(1)优化批量插入操作

批量插入数据时,如果反复调用session实例的save()方法,保存持久化类实例到数据库中,若插入记录的数量众多,很可能会出现Out Of Memory Error异常。出现这种异常往往是由Hibernate缓存所致。因为Hibernate的一级缓存由Hibernate自己进行管理,并且只存在于内存中,而在通过save()方法保存持久化类实例时,并不是立即保存到数据库中,而是保存在Hibernate的缓存中,真正将持久化对象保存到数据库是在提交事务清理缓存的时候,所以当插入海量的记录时,如果反复调用save()方法,一定会出现内存溢出的情况。

为了避免内存溢出的情况,需要在调用save()方法的同时,阶段性地通过Session实例的clear()方法清空一级缓存,将持久化对象同步保存到数据库中。

(2)优化批量修改和删除操作

在Hibernate 2中,如果需要对数据记录进行修改或删除,必须先执行查询操作,将所要修改或删除的记录加载到缓存中,才能执行相应的操作,但这种方式会占用大量内存,还需多次执行UPDATE或DELETE语句。而在Hibernate 3版本中,提供了用于批量修改或删除记录的功能,不必再加载到缓存中,只需要执行一条UPDATE或DELETE语句即可,例如在Hibernate 3中,可以通过以下方式批量删除记录:

2.3 方案3—在批量检索对象时,充分运用set First Result()和set Max Results()方法

在通过HQL语句批量检索对象时,有些时候只需要用到其中的一部分,例如现在想查看某单位薪水较高的前10名,可以通过下面的方式只加载这前10个持久化对象。

方法set First Result()用来设置开始加载持久化对象的索引位置,默认为从第一个持久化对象开始加载。需要注意的是,第一个持久化对象的索引位置是0,方法set Max Results()用来设置加载持久化对象的个数。如果不运用这两个方法,若加载该单位所有的员工,如果该单位有200名员工甚至更多的情况下,对软件性能的影响是十分明显的。

2.4 方案4—充分运用缓存机制

Hibernate提供了两种缓存机制,分别如下:

(1)一级缓存

一级缓存是基于Session实例生命周期的缓存,随着Session实例的创建而自动创建,Session实例的销毁而自动销毁,所以又称为Session Level Cache。一级缓存主要用作对象缓存,以持久化对象的OID为键保存持久化对象,软件开发人员对一级缓存的干预能力不大,通常由Hibernate自行管理,只对外提供了清理缓存的方法,这对批量添加记录很重要。

(2)二级缓存

二级缓存是Session Factory级别的全局缓存,在其下可以使用不同的缓存类库,比如ehcache、oscache等,所有通过该Session Factory实例创建的Session实例共享此缓存。Hibernate默认的设置不是为Session Factory实例创建二级缓存,需要使用时,由软件开发人员自行创建,创建方法是在Hibernate配置文件中添加如下代码,设置缓存提供类。

二级缓存包括对象缓存和查询缓存。在Hibernate配置文件中推荐使用对象缓存,其优点是可以统一管理对象缓存,在使用对象缓存的情况下,首先,get()和load()方法检索对象缓存。在对象缓存不存在的情况下才从数据库加载,然后,iterate()方法从数据库加载代理对象,再从缓存中获得持久化对象,当缓存中不存在持久化对象时将抛出异常。

使用查询缓存的前提是必须使用对象缓存,否则使用查询缓存,反而会降低软件的性能。list()方法支持查询缓存,不过在通过Query实例调用list()方法之前,必须调用set Cacheable(boolean cacheable)方法将入口参数设置为True,即可对此次查询使用查询缓存。

在使用二级缓存时,需要注意诸如数据不要太大,数据不会被频繁修改以及会被频繁查询等问题。

2.5 方案5—在检索指定对象时,充分使用get()方法

get()和load()方法都用于将制定OID的持久化对象加载到缓存中,其内部执行过程均为先检索一级缓存,再检索二级缓存。在两级缓存均已检索到的情况下,最后从数据库加载。get()方法和load()方法之间有两点差别:

(1)当数据库中不存在与指定OID对应的记录时,load()方法将抛出异常,而get()方法则返回NULL。

(2)get()方法总是立即加载对象,而load()方法支持延迟加载。

从这些细微差别考虑,推荐使用get()方法,原因如下:

(1)既然要加载指定OID的持久化对象,就是需要现在加载,以立即付诸使用,而load()方法支持延迟加载,不太合适。

(2)在编码时,应尽量避免通过Try/Catch语句块控制程序流程,而通过get()方法加载不存在的持久化对象时返回NULL,所以可通过判断返回的对象是否为空控制程序的流程。

3 结束语

本文涵盖了在Hibernate性能优化时很实用的一些优化方案,通过对上述几个方面的优化,利用Hibernate持久层技术进行软件开发将是一个很好的选择。

参考文献

[1]蔡格非,时元升.基于hibernate的数据缓存优化技术的研究[J].科技创新导报,2009(6):31-32.

[2]王国辉,王毅,尹相群.JavaWeb开发技术方案宝典[M].北京:人民邮电出版社,2008:718-722.

[3]王舜燕,刘刚.基于Hibernate的持久层性能优化[J].软件导刊,2007(1):93-95.

[4]汪萌,曲俊华.基于Hibernate技术的持久层解决方案及实现[J].计算机系统应用,2010(3):154-157.

数据持久化层 篇9

随着J2EE的发展, J2EE已经成为主流的企业级应用解决方案, 但是J2EE编程正变得越来越复杂。为了降低成本, 加快应用程序的开发和设计, J2EE平台提供了一种基于组件的方法。对于一个应用模型, 根据功能将其应用逻辑划分成为组件。J2EE规范中定义了应用客户组件、Enterprise JavaBeans组件、web组件 (Servlet和JSP) 和Applet, 我们要做的就是怎样组装这些组件, 使之成为一个便于开发、便于维护、有很好的扩展性的软件体系结构, 从而以更小的成本、更少的资源、更快地完成应用的设计和开发。

1 IOC容器Spring

Spring是一个开源框架, 是为了解决企业应用程序开发的复杂性而创建的。框架的主要优势之一就是其为分层架构, 分层架构允许您选择使用在一个组件, 同时为J2EE应用程序开发提供集成的框架。

Spring还是一个基于AOP和IOC构架的多层J2EE系统框架, AOP, 即面向方面的编程, 它允许程序员对横切关注点或横切典型的职责分界线的行为 (例如日志和事务管理) 进行模块化。AOP的核心构造是方面, 它将那些影响多个类的行为封装到可重用的模块中。IOC, 即控制倒置 (Inversion of Control) , 允许创建一个可以构造对象的应用环境, 然后向这些对象传递它们的协作对象。正如单词倒置所表明的, IOC就象反过来的JN-DI。没有使用一堆抽象工厂、服务定位器、单例 (singleton) 和直接构造 (straight construction) , 每一个对象都是用其协作对象构造的。我们在使用Spring集成组件服务和它们相关的事务关系的时候, 就是基于控制倒置 (IOC) 的。

2 O/R Mapping工具Hibernate

Hibernate是一个开放源代码的对象关系映射框架, 它对JDBC进行了非常轻量级的对象封装, 使得Java程序员可以随心所欲地使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合, 既可以在Java的客户端程序使用, 也可以在Servlet/JSP的Web应用中使用, 最具革命意义的是, Hibernate可以在应用EJB的J2EE架构中取代CMP, 完成数据持久化的重任。

Hibernate提供了一种称为Hibernate Query Language (HQL) 的查询语言, 这种语言与SQL非常相似, 便于开发人员掌握。更重要的是, HQL完全是面向对象的, 查询的是持久对象。HQL非常类似于JDO的JDO QL和EJB的EJB QL。尽管它更接近于前者, 但是Hibernate没有就此止步, 它还可以进行直接的SQL查询和/或使用Object Criteria很容易地在运行时构成查询条件。Hibernate还可以像JDO一样可以在J2EE容器内部或者外部工作。如果我们的应用程序必须在多个RDBMS系统上运行, 那么基于Hibernate的应用程序可以毫不费力地移植到IBM DB2、MySQL、PostgreSQL、Sybase、Oracle、HypersonicSQL和许多其他数据库。这样可以使得我们的系统脱离开J2EE容器和数据库更加灵活地运行。

3 系统架构

我们在项目中应用了多层架构, 多层架构是将整个系统清晰地分为多个功能单元:ClientTier、PresentationTier、Business-LogicTier、IntegrationTier和EISTier, 这将确保职责得到清晰地划分, 使得系统更易于维护和扩展。具有3层或多层的系统被证明比C/S模型具有更好的伸缩性和灵活性。图1是项目的总体构架。

4 事务持久层开发

Spring作为一个轻量级的事务基础架构, 实际上可以管理组件级的事务装配。它的优点在于, 我们不会被捆绑到J2EE容器服务 (如JNDI Data Source) 上。最重要的是, 如果我们想把这个轻量级事务基础架构关联到一个已可用的J2EE容器基础架构上, 将不会有任何问题。Spring提供了各种事务策略, 如Jta TransactionManager是用来代理J2EE服务器的事务协调器, 而JDBC DataSourceTransactionManager是用来为简单的JDBCDataSource (就是单一目标数据库) 执行事务。

Spring事务支持的核心接口org.springframework.transaction.Platform Transaction Manager。Spring提供了几种不同的PlatformTransaction Manager实现, 分为如下两个类别:

(1) 本地事务策略-支持单一资源的事务 (通常是单个数据库) , 其相应的类包括org.springframework.jdbc.datasource.Data Source Transaction Manager和org.springframework.orm.hibernate Hibernate Transaction Manager。

(2) 全局事务管理-支持可能跨越多个资源的全局事务, 其相应的类为org.springframework.transaction.jta.Jta TransactionManager, 它可以将事务委托给遵循JTA规范的事务协调器 (通常为J2EE服务器, 但不是强制的) 。

重要的是, Spring这个轻量级事务基础架构使用了AOP框架, AOP可以为Java Bean声明事务。例如, Transaction ProxyFactory Bean是个方便的代理类, 能够拦截对现有类的方法调用, 并把事务上下文应用到事务bean。在Spring的配置文件application Context.xml中, 是通过在组件服务级指定事务特性来划分事务。项目中的[application Context.xml]配置文件如下:

class="org.springframework.orm.hibernate.Hibernate Transaction Manager">

PROPAGATION_REQUIRED

一旦我们在服务级指定了事务属性, HibernateTransactionManager接口的一个特定实现就会截获并解释它们。该接口如下:

public interface Hibernate Transaction Manager{

Transaction Status get Transaction

(Transaction Definition definition) ;

void commit (Transaction Status status) ;

void rollback (Transaction Status status) ;

}

由上述代码我们可以看到, 通过配置文件, 我们可以将任意的Java Class纳入事务管理, 也就是说我们可以随意为某个类的某个方法指定事务管理机制。而且Spring的事务管理支持JDBC, JTA等多种事务资源, 这些都为我们提供了更多的选择, 从而也使我们的系统部署更加灵活。

5 结束语

在本文中, 介绍了如何使用Hibernate和Spring实现一个事务持久层。Hibernate是一种先进的OR映射工具, 而Spring是一个AOP框架和IOC容器。这两种技术的综合使用, 使得开发人员可以编写简洁明了的代码, 它可以在J2EE容器中运行, 也可以单独运行。但是对于比较庞大的系统来说, 大量配置文件的编写使得工作显得比较烦琐, 但总体而言基于这两个框架的J2EE架构开发简洁, 结构清晰, 有很好的可扩展性和可维护性, 非常适于面向对象的设计与开发。

摘要:针对J2EE架构中事务持久层开发的复杂性, 介绍了Spring和Hibernate两个开源框架以及它们对事务持久层开发的实现, 提出了基于这两种框架的J2EE架构, 给出了该架构的工作流程并分析了它的优缺点。

关键词:Spring,Hibernate,事务持久层,J2EE,架构

参考文献

[1]Rod Johnson, Juergen Hoeller, Alef Arendsen, Thomas Risberg, Colin Sampaleanu.Professional Java Development with the Spring Framework[M].Wrox, 2005 (7) .

[2]Craig Walls, Ryan Breidenbach.Spring in Action中文版[M].北京:人民邮电出版社, 2006 (4) .

[3]董洪彬, 窦延平.利用Hibernate的J2EE数据持久层的解决方案[J].计算机工程, 2004 (30) .

上一篇:工作方法和途径下一篇:湿地生态功能