`

Java杂谈(十三)——ORM

阅读更多

   其实J2ee的规范指南里面就已经包括了一些对象持久化技术,例如JDO(Java Data Object)就是Java对象持久化的新规范,一个用于存取某种数据仓库中的对象的标准化API,提供了透明的对象存储,对开发人员来说,存储数据对象完全不需要额外的代码(如JDBC API的使用)。这些繁琐的工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库(RDBMS)JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMS)等等,使得应用可移植性更强。我们如果要理解对象持久化技术,首先要问自己一个问题:为什么传统的JDBC来持久化不再能满足大家的需求了呢?  
 
   笔者认为最好是能用JDBC真正编写过程序了才能真正体会ORM的好处,同样的道理,真正拿Servlet/Jsp做过项目了才能体会到Struts、Spring等框架的方便之处。很幸运的是笔者这两者都曾经经历过,用混乱的内嵌Java代码的Jsp加Servlet转发写过完整的Web项目,也用JDBC搭建过一个完整C/S项目的后台。所以现在接触到新框架才更能体会它们思想和实现的优越之处,回顾从前的代码,真是丑陋不堪啊。^_^  
 
   回到正题,我们来研究一下为什么要从JDBC发展到ORM。简单来说,传统的JDBC要花大量的重复代码在初始化数据库连接上,每次增删改查都要获得Connection对象,初始化Statement,执行得到ResultSet再封装成自己的List或者Object,这样造成了在每个数据访问方法中都含有大量冗余重复的代码,考虑到安全性的话,还要加上大量的事务控制和log记录。虽然我们学习了设计模式之后,可以自己定义Factory来帮助减少一部分重复的代码,但是仍然无法避免冗余的问题。其次,随着OO思想深入人心,连典型的过程化语言Perl等都冠冕堂皇的加上了OO的外壳,何况是Java中繁杂的数据库访问持久化技术呢?强调面向对象编程的结果就是找到一个桥梁,使得关系型数据库存储的数据能准确的映射到Java的对象上,然后针对Java对象来设计对象和方法,如果我们把数据库的Table当作Class,Record当作Instance的话,就可以完全用面向对象的思想来编写数据层的代码。于是乎,Object Relationship Mapping的概念开始普遍受到重视,尽管很早很早就已经有人提出来了。  
 
   缺点我们已经大概清楚了,那么如何改进呢?对症下药,首先我们要解决的是如何从Data Schema准备完美的映射到Object Schema,另外要提供对数据库连接对象生命周期的管理,对事务不同粒度的控制和考虑到扩展性后提供对XML、Properties等可配置化的文件的支持。到目前为止,有很多框架和技术在尝试着这样做。例如似乎是封装管理得过了头的EJB、很早就出现目前已经不在开发和升级了的Apache OJB、首先支持Manual SQL的iBATIS,还有公认非常优秀的Hibernate等等。在分别介绍它们之前,我还想反复强调这些框架都在试图做什么:  
 
   毕竟Java Object和数据库的每一条Record还是有很大的区别,就是类型上来说,DB是没有Boolean类型的。而Java也不得不用封装类(Integer、Double等)为了能映射上数据库中为null的情况,毕竟Primitive类型是没有null值的。还有一个比较明显的问题是,数据库有主键和外键,而Java中仍然只能通过基本类型来对应字段值而已,无法规定Unique等特征,更别提外键约束、事务控制和级联操作了。另外,通过Java Object预设某Field值去取数据库记录,是否在这样的记录也是不能保证的。真的要设计到完全映射的话,Java的Static被所有对象共享的变量怎么办?在数据库中如何表现出来……  
我们能看到大量的问题像一座座大山横在那些框架设计者们面前,他们并不是没有解决办法,而是从不同的角度去考虑,会得到很多不同的解决方案,问题是应该采取哪一种呢?甚至只有等到真正设计出来了投入生产使用了,才能印证出当初的设想是否真的能为项目开发带来更多的益处。笔者引用一份文档中提到一个健壮的持久化框架应该具有的特点:  
   A robust persistence layer should support----  
   1. Several types of persistence mechanism  
   2. Full encapsulation of the persistence mechanism.  
   3. Multi-object actions  
   4. Transactions Control  
   5. Extensibility  
   6. Object identifiers  
   7. Cursors: logical connection to the persistence mechanism  
   8. Proxies: commonly used when the results of a query are to be displayed in a list  
   9. Records: avoid the overhead of converting database records to objects and then back to records  
   10. Multi architecture  
   11. Various database version and/or vendors  
   12. Multiple connections  
   13. Native and non-native drivers  
   14. Structured query language queries(SQL)  
 
   现在来简短的介绍一下笔者用过的一些持久化框架和技术,之所以前面强调那么多共通的知识,是希望大家不要盲从流行框架,一定要把握它的本质和卓越的思想好在哪里。  
   1. Apache OJB  
   OJB代表Apache Object Relational Bridge,是Apache开发的一个数据库持久型框架。它是基于J2ee规范指南下的持久型框架技术而设计开发的,例如实现了ODMG 3.0规范的API,实现了JDO规范的API, 核心实现是Persistence Broker API。OJB使用XML文件来实现映射并动态的在Metadata layer听过一个Meta-Object-Protocol(MOP)来改变底层数据的行为。更高级的特点包括对象缓存机制、锁管理机制、Virtual 代理、事务隔离性级别等等。举个OJB Mapping的简单例子ojb-repository.xml:  
 
   <class-descriptor class=”com.ant.Employee” table=”EMPLOYEE”>  
   <field-descriptor name=”id” column=”ID”   
   jdbc-type=”INTEGER” primarykey=”true” autoincrement=”true”/>  
 
   <field-descriptor name=”name” column=”NAME” jdbc-type=”VARCHAR”/>  
   </class-descrptor>  
 
   <class-descriptor class=”com.ant.Executive” table=”EXECUTIVE”>  
   <field-descriptor name=”id” column=”ID”   
   jdbc-type=”INTEGER” primarykey=”true” autoincrement=”true”/>  
 
   <field-descriptor name=”department” column=”DEPARTMENT” jdbc-type=”VARCHAR”/>  
     
   <reference-descriptor name=”super” class-ref=”com.ant.Employee”>  
   <foreignkey field-ref=”id”/>  
   </reference-descriptor>  
   </class-descrptor>  
 
   2. iBATIS  
   iBATIS最大的特点就是允许用户自己定义SQL来组配Bean的属性。因为它的SQL语句是直接写入XML文件中去的,所以可以最大程度上利用到SQL语法本身能控制的全部特性,同时也能允许你使用特定数据库服务器的额外特性,并不局限于类似SQL92这样的标准,它最大的缺点是不支持枚举类型的持久化,即把枚举类型的几个对象属性拼成与数据库一个字段例如VARCHAR对应的行为。这里也举一个Mapping文件的例子sqlMap.xml:  
   <sqlMap>  
   <typeAlias type=”com.ant.Test” alias=”test”/>  
 
   <resultMap class=”test” id=”result”>  
   <result property=”testId” column=”TestId”/>  
   <result property=”name” column=”Name”/>  
   <result property=”date” column=”Date”/>  
   </resultMap>  
 
   <select id=”getTestById” resultMap=”result” parameterClass=”int”>  
   select * from Test where TestId=#value#  
   </select>  
 
   <update id=”updateTest” parameterClass=”test”>  
   Update Tests set Name=#name#, Date=”date” where TestId=#testId#  
   </update>  
   </sqlMap>  
 
   3. Hibernate  
   Hibernate无疑是应用最广泛最受欢迎的持久型框架,它生成的SQL语句是非常优秀。虽然一度因为不能支持手工SQL而性能受到局限,但随着新一代Hibernate 3.x推出,很多缺点都被改进,Hibernate也因此变得更加通用而时尚。同样先看一个Mapping文件的例子customer.hbm.xml来有一个大概印象:  
 
   <hibernate-mapping>  
   <class name=”com.ant.Customer” table=”Customers”>  
   <id name=”customerId” column=”CustomerId” type=”int” unsaved-value=”0”>  
   <generator class=”sequence”>  
   <param name=”sequence”> Customers_CustomerId_Seq </param>  
   </generator>  
   </id>  
 
   <property name=”firstName” column=”FirstName”/>  
   <property name=”lastName” column=”LastName”/>  
 
   <set name=”addresses” outer-join=”true”>  
   <key column=”Customer”/>  
   <one-to-many class=”com.ant.Address”/>  
   </set>  
  
   …  
   </class>
 
   </hibernate-mapping>  
 
   Hibernate有很多显著的特性,最突出的就是它有自己的查询语言叫做HQL,在HQL中select from的不是Table而是类名,一方面更加面向对象,另外一方面通过在hibernate.cfg.xml中配置Dialect为HQL可以使得整个后台与数据库脱离耦合,因为不管用那种数据库我都是基于HQL来查询,Hibernate框架负责帮我最终转换成特定数据库里的SQL语句。另外Hibernate在Object-Caching这方面也做得相当出色,它同时管理两个级别的缓存,当数据被第一次取出后,真正使用的时候对象被放在一级缓存管理,这个时候任何改动都会影响到数据库;而空闲时候会把对象放在二级缓存管理,虽然这个时候与数据库字段能对应上但未绑定在一起,改动不会影响到数据库的记录,主要目的是为了在重复读取的时候更快的拿到数据而不用再次请求连接对象。其实关于这种缓存的设计建议大家研究一下Oracle的存储机制(原理是相通的),Oracle牺牲了空间换来时间依赖于很健壮的缓存算法来保证最优的企业级数据库访问速率。  
 
   以上是一些Mapping的例子,真正在Java代码中使用多半是继承各个框架中默认的Dao实现类,然后可以通过Id来查找对象,或者通过Example来查找,更流行的是更具Criteria查找对象。Criteria是完全封装了SQL条件查询语法的一个工具类,任何一个查询条件都可以在Criteria中找到方法与之对应,这样可以在Java代码级别实现SQL的完全控制。另外,现在许多ORM框架的最新版本随着JDk 5.0加入Annotation特性都开始支持用XDoclet来自动根据Annotation来生成XML配置文件了。  
 
   笔者不可能详细的讲解每一个框架,也许更多的人在用Hibernate,笔者是从OJB开始接触ORM技术的,它很原始却更容易让人理解从JDBC到ORM的过渡。更多的细节是可以从官方文档和书籍中学到的,但我们应该更加看中它们设计思想的来源和闪光点,不是盲从它们的使用方法。  
 
   到这里全部Java杂谈这个主题就正式结束了,笔者也可以长叹一口气,拿到毕设题目后也该开始忙自己的毕业设计了。最近看了很多Spring AOP的资料,实习下班回家还会研究Ajax和极限编程,如果有时间了话,会把自己的学习笔记拿出来分享的。衷心希望大家都能不断的进步,在喜欢的道路上不回头的走下去……^_^
另外,大家也回帖也够累的,呵呵,就让此帖沉下去吧,现在重写看到这些,觉得好多好多地方没说清楚或者有漏洞,自己都觉得挺惭愧的
 
不过我觉得,任何人在学习一门技术的道路上都是要带着错误去前进的,而且要用于带着错误和疑惑向前走,适当的时候停下来抖一抖,抖掉身上累赘的错误然后再继续前进,最终达到精通的高峰!畏首畏尾只会阻碍人前进……笔者脸大,所以坚持写下来了,呵呵……
 
现在工作加毕设实在是忙,每每看到论坛的朋友学习讨论技术的热情这么高,都很感动,再过2个半月本科毕业,一定要接着写,义无反顾的写下去,大伙一起进步才是真正的成功!

==================结束===================
分享到:
评论

相关推荐

    java_学习资料

    - **Jpa**:Java Persistence API,用于实现ORM。 **Bmt与cmt** - **概念**:Bean Management Transaction 和 Container Management Transaction,分别代表Bean管理和容器管理的事务。 **Xml** - **DTD**:...

    C2000系列DSP芯片串口读写方案与FlashPro2000编程器应用详解

    内容概要:本文详细介绍了基于TMS320F系列芯片的C2000串口读写方案及其编程器——FlashPro2000的功能特点和支持的接口模式。文中不仅涵盖了硬件连接的具体步骤,还提供了代码实例来展示Flash擦除操作,并对比了JTAG和SCI-BOOT两种模式的优缺点。此外,针对不同型号的C2000系列芯片,给出了详细的适配指导以及避免烧录过程中可能出现的问题的方法。 适合人群:从事DSP开发的技术人员,尤其是对TI公司C2000系列芯片有一定了解并希望深入了解其编程和烧录细节的人群。 使用场景及目标:适用于实验室环境下的程序调试阶段,以及生产线上的批量烧录任务。主要目的是帮助开发者选择合适的编程工具和技术手段,提高工作效率,减少因误操作导致设备损坏的风险。 其他说明:文中提供的代码片段和命令行指令可以直接用于实际项目中,同时附带了一些实用技巧,如防止芯片变砖的小贴士和自动化重试脚本,有助于解决常见的烧录难题。

    汉字字库存储芯片扩展实验通常是为了学习和理解如何在嵌入式系统或计算机硬件中增加或管理存储资源,特别是针对需要处理中文字符的应用 这类实验对于想要深入了解计算机体系结构、嵌入式开发以及汉字编码的学生和工

    汉字字库存储芯片扩展实验 # 汉字字库存储芯片扩展实验 ## 实验目的 1. 了解汉字字库的存储原理和结构 2. 掌握存储芯片扩展技术 3. 学习如何通过硬件扩展实现大容量汉字字库存储 ## 实验原理 ### 汉字字库存储基础 - 汉字通常采用点阵方式存储(如16×16、24×24、32×32点阵) - 每个汉字需要占用32字节(16×16)到128字节(32×32)不等的存储空间 - 国标GB2312-80包含6763个汉字,需要较大存储容量 ### 存储芯片扩展方法 1. **位扩展**:增加数据总线宽度 2. **字扩展**:增加存储单元数量 3. **混合扩展**:同时进行位扩展和字扩展 ## 实验设备 - 单片机开发板(如STC89C52) - 存储芯片(如27C256、29C040等) - 逻辑门电路芯片(如74HC138、74HC373等) - 示波器、万用表等测试设备 - 连接线若干 ## 实验步骤 ### 1. 单芯片汉字存储实验 1. 连接27C256 EPROM芯片到单片机系统 2. 将16×16点阵汉字字库写入芯片 3. 编写程序读取并显示汉字 ### 2. 存储芯片字扩展实验 1. 使用地址译码器(如74HC138)扩展多片27C256 2. 将完整GB2312字库分布到各芯片中 3. 编写程序实现跨芯片汉字读取 ### 3. 存储芯片位扩展实验 1. 连接两片27C256实现16位数据总线扩展 2. 优化字库存储结构,提高读取速度 3. 测试并比较扩展前后的性能差异 ## 实验代码示例(单片机部分) ```c #include <reg52.h> #include <intrins.h> // 定义存储芯片控制引脚 sbit CE = P2^7; // 片选 sbit OE = P2^6; // 输出使能 sbit

    测控装备干扰源快速侦测系统设计研究.pdf

    测控装备干扰源快速侦测系统设计研究.pdf

    嵌入式八股文面试题库资料知识宝典-【开发】嵌入式开源项目&库&资料.zip

    嵌入式八股文面试题库资料知识宝典-【开发】嵌入式开源项目&库&资料.zip

    嵌入式八股文面试题库资料知识宝典-百度2022年嵌入式面试题.zip

    嵌入式八股文面试题库资料知识宝典-百度2022年嵌入式面试题.zip

    少儿编程scratch项目源代码文件案例素材-空间站.zip

    少儿编程scratch项目源代码文件案例素材-空间站.zip

    基于关联规则的商业银行个性化产品推荐.pdf

    基于关联规则的商业银行个性化产品推荐.pdf

    嵌入式八股文面试题库资料知识宝典-Linux基础使用.zip

    嵌入式八股文面试题库资料知识宝典-Linux基础使用.zip

    MATLAB仿真轴棱锥生成贝塞尔高斯光束及环形光束光强图像分析

    内容概要:本文详细介绍了利用MATLAB进行轴棱锥生成贝塞尔高斯光束及环形光束光强图像的仿真研究。首先阐述了实验的背景与目标,强调了MATLAB在光学和计算科学领域的广泛应用。接着,具体描述了实验的方法与步骤,包括材料准备、仿真过程中的参数设定和光束生成代码编写。最后,对实验结果进行了深入分析,展示了贝塞尔高斯光束和环形光束的光强分布特点,验证了其光学性能的预期表现。文章还对未来的研究方向和技术改进提出了展望。 适合人群:从事光学、物理学及相关领域研究的专业人士,特别是对光束生成和光学性能分析感兴趣的科研工作者。 使用场景及目标:适用于需要进行光束生成和性能分析的实验室环境,旨在帮助研究人员更好地理解和优化光束特性和传播行为。 其他说明:本文不仅提供了详细的实验方法和步骤,还附有丰富的实验结果和数据分析,为后续研究提供了宝贵的参考资料。

    三电平NPC型APF模型预测控制中滞环控制模块的应用与开关频率优化研究

    内容概要:本文探讨了三电平NPC型有源电力滤波器(APF)的模型预测控制(MPC)中存在的开关频率过高问题及其解决方案。传统MPC方法会导致极高的开关频率,增加了系统的能耗和热量。通过引入滞环控制模块,可以在不大幅牺牲性能的情况下有效降低开关频率。具体来说,滞环控制通过在价值函数计算后增加一个判断条件,对状态切换进行惩罚,从而减少不必要的开关动作。实验结果显示,开关频率从4392Hz降至3242Hz,降幅达26.2%,虽然电流总谐波畸变率(THD)略有上升,但仍符合国家标准。此外,文中还提出了动态调整滞环宽度的方法,以进一步优化不同负载条件下的表现。 适合人群:从事电力电子、电力系统控制领域的研究人员和技术人员,特别是关注APF和MPC技术的人群。 使用场景及目标:适用于需要优化APF系统开关频率的研究和工程项目,旨在提高系统效率并降低成本。目标是在不影响系统性能的前提下,显著降低开关频率,减少能量损失和热管理难度。 其他说明:文章不仅提供了理论分析,还包括具体的实现代码片段,有助于读者理解和实践。同时,强调了在实际应用中需要注意的问题,如中点电位漂移等。

    计算流体力学中三维POD DMD程序的原网格处理方法及应用

    内容概要:本文介绍了三维POD DMD程序在处理原网格数据方面的独特优势和技术细节。首先阐述了该程序能读取结构化和非结构化网格数据及其拓扑关系,在生成模态数据过程中保持原始网格形态而不需要进行网格插值操作。接着展示了简化版本的Python代码片段,揭示了读取网格数据和生成模态数据的核心逻辑。最后提到提供的辅助学习资料如代码、视频教程、Word教程和实例数据,帮助用户深入理解并掌握该程序的应用。 适合人群:从事计算流体力学领域的研究人员和技术爱好者,尤其是那些希望提高数据处理效率的人群。 使用场景及目标:适用于需要处理复杂网格数据的研究项目,旨在简化数据处理流程,提升工作效率,同时保持数据的原始特性。 其他说明:文中不仅提供了理论性的讲解,还有具体的代码示例和丰富的学习资源,使读者可以边学边练,快速上手。

    融合双向路由注意力的多尺度X光违禁品检测.pdf

    融合双向路由注意力的多尺度X光违禁品检测.pdf

    嵌入式八股文面试题库资料知识宝典-Linux_Shell基础使用.zip

    嵌入式八股文面试题库资料知识宝典-Linux_Shell基础使用.zip

    嵌入式八股文面试题库资料知识宝典-联发科2021武汉嵌入式软件开发.zip

    嵌入式八股文面试题库资料知识宝典-联发科2021武汉嵌入式软件开发.zip

    基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf

    基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf

    嵌入式八股文面试题库资料知识宝典-ARM常见面试题目.zip

    嵌入式八股文面试题库资料知识宝典-ARM常见面试题目.zip

    基于LWR问题的无证书全同态加密方案.pdf

    基于LWR问题的无证书全同态加密方案.pdf

    嵌入式八股文面试题库资料知识宝典-符坤面试经验.zip

    嵌入式八股文面试题库资料知识宝典-符坤面试经验.zip

    三电平逆变器带不平衡负载的DSC与双闭环PI控制策略仿真研究

    内容概要:本文详细探讨了三电平逆变器在带不平衡负载条件下的仿真研究。主要内容包括仿真环境的搭建、不同拓扑结构的选择(如T型、I型NPC和ANPC)、延时相消法(DSC)和双二阶广义积分器(DSOGI)的正负序分离控制策略、SVPWM或SPWM调制技术的应用、双闭环PI控制以及直流均压控制。文中通过具体的参数设置(交流电压220V,直流侧电压750V)进行了详细的仿真实验,并展示了各个控制策略的效果。最终,通过仿真实验验证了所提出方法的有效性,确保了交流侧三相电压波形的对称性和电流波形的自适应调节。 适合人群:从事电力电子、电机驱动、新能源发电等领域研究的技术人员和研究人员。 使用场景及目标:适用于需要理解和掌握三电平逆变器在复杂负载条件下控制策略的研究人员和技术人员。目标是提高对三电平逆变器及其控制策略的理解,优化实际应用中的性能。 其他说明:本文不仅提供了理论分析,还包含了具体的仿真步骤和代码实现,有助于读者更好地理解和应用相关技术。

Global site tag (gtag.js) - Google Analytics