同时支持mybatis,hibernate等技术的通用持久层实现思路

java开源平台的技术框架非常丰富,但是开源平台上的权限管理、会员管理之类的纯业务模块往往与某种技术框架耦合在一起,比如与mybatis,hibernate等持久层技术耦合。一旦你选定了某个现成的业务组件,就必须接受他对应的持久层框架。比如如果你选择用知名开源框架jeesite做自己的小型web应用系统,你在用它的权限、cms业务模块的时候,就必须用mybaits做持久化框架,而不能用hibernate或spring jpa之类的,这对于只考虑用hibernate而不打算用mybatis的团队来说,不得不得放弃这个框架。所以,我在想,如果能有一些通用的业务组件,可以同时支持mybatis,hibernate等不同的持久层技术,可能具有更好的通用性和可移植性。
在开源平台上,确实有这类似需求的解决方案,比如开源中国上的Uncode-DAL项目,就支持同时支持mybatis、spring jdbc、hibernate等ORM框架。但遗憾的是,它只支持单表操作,不支持多表关联之类的功能。实事上,在待久层框架中,处理多表关联确实是一个比较复杂的问题。
我经过一番摸索,找到了一种感觉还过得去的解决方案,并已经用到了自己的jad项目中。这里先给出实现的思路和原理,以后jad项目开源后,再将这个框架一起开源。
功能需求
既然称之为通用持久层,那么需要实现的功能至少有以下几点:
1、需要同时支持不同的待久层,至少需要同时支持mybatis、hibernate和spring jpa。
也就是说,通过这个框架实现的业务组件,可以在不修改任何业务代码的基础上,可灵活的在mybatis、hibernate和spring jpa之间任意切换。
2、支持多表关联,至少需要支持一对多。
3、能自动处理不同数据库之间的方言,比如分页。
大致实现思路
考虑到不同的持久层框架,对OR映射,数据访问等方式迥异。要做一个他们之间通用的框架,必须在它们之间找到一个共同的规范,让它们同时遵守这个规范,就基本上能达到通用的目地。
似乎所有对数据库的访问,都是通过sql语问来实现的,只不过hibernate等比较重量级的持久化框架还提供一些比如hql之类的语句来访问,然而,这种hql最终还是被框架解释成sql语句被传送到数据库。对于查询语句,在数据库返回数据后,大部分框架都会把数据库的数据转换成相应的实体对像(即使它是传统的关系型数据库),这个过程就是所调的OR映射。只不过不同的框架,对OR映射的实现机制有所不同。
对于mybatis来说,需要开发人员自己维护对像属性与表字段之间的关系,它并没有实现完整的OR映射,但是它有比较完善动态sql引擎,用来实现动态拼接sql访问数据库。而hibernate非常完美的实现了OR 映射并对JPA规范都有很好的支持,而且还提供了一个面象对象的hql查询语言,大大方便了开发人员。spring jpa本身并没有实现数据访问逻辑,它只不过在JPA规范的基础上进行了一些扩展,采用一些大家都能接受的编码规范来精简编码工作。程序员甚至只要写一些简单的操作数据的Dao接口而无需任何实现就可以通过spring强大的IOC机制自动生成Dao的代理实现类来访问数据库。而且,Spring jpa底层并没有实现访问数据库的具体逻辑,对于数据库操作的具体逻辑,它最终还是委托给了比如Hibernate之类的框架作为一个持久化提供者的角色来实现数据访问(Spring jpa默认的持久化提供者就是Hibernate,它支持通过配置,采用别的持久化提供者)。所以,spring jpa的本质只不过是对现有的持久化方案做扩展,以提高开发效率而已。
通过以上分析,可以整理出一个大致的实现通用的持久化思路,就是统一的使用sql访问数据库,并实现统一的OR映射,把这两点作为它们共同的规约。那么问题来了,首先,如何不依赖于特定持久化框架来生成访问数据库的sql语句?其次,对于查询,如何把关系型数转换为对象?如果遇到多表关联怎么办?难点汇总如下:
难点汇总与解决方案
1、如何不依赖于特定持久化框架来生成sql语句
对于普通的insert,update,delete语句,开发人员可以随意写sql语句,直接交给底层实现就行了。但是对于查询,考虑到需要将查询结果映射成对像,那么就不通随意写了,需要符合某些规范。
因为hibernate有比较完整的OR实现,通过面向对象的hql语言就可以操作数据库,程员无需写sql,同样spring jpa也提供了类似的jql语句来进行操作,但mybatis就需要开发人员自己写sql了。对于前两个框架,他们都实现了jpa规范,可以通过jpa注解来做到实体属性与表数据实段之间的映射。基于此,我在想,如果mybatis也能实现jpa规范,哪怕只是部分实现也好。要么,我们自己写实现这个的逻辑,参考jpa规范,我们自己用一些诸如Column之类的注解来标识实现字段,通过反射的方式来构建对应的查询sql。嗯,这确实是一个不错的主意。
2、生成sql语句的过程如何解决表间关联
在不依赖于特定持久化框架来生成sql语句的过程,难免会碰到多表关联的情况,特别在处理查询sql的查询结果时,表间关联的查询比较普遍。上述第一点问题的解决方案中,通过返射来处理这些关联时,稍微复杂一点。
实事上,对于所有持久层技术来说,表间关联都比较难处理。在一些比较小众的对常用持久层框架作改造或扩展的开发者们往往都会避开多表关联,只考虑对单表的持久化功能扩展。而遇到多表关联时,依旧采用原始依赖的持久化框架来实现。比如号称同时支持mybatis、spring jdbc、hibernate等ORM框架的Uncode-DAL框架,它也就只支持单表操作而已,再比如对mybatis扩展的比较好的mybatis-plus项目,它也就只扩展了单表操作,对于多表关联时,还是要自己用原始的mybatis api来做关联映射。
在JPA规范中,处理表间关联时,可以采用一些诸如OneToMany和ManyToOne之类的注解来处理这些关系。所以,在不依赖于特定持久化框架来生成sql语句时,我们同样可以自己写代码来处理ManyToOne之类的注解,把这些注解翻译成我们自己的查询sql,只不过有一点小复杂而已,但致少是一种思路。如果实在处理不了,可以只处理ManyToOne,把它翻译成left join语句。
2、如何处理查询语句的返回结果
对于数据库返回的查询结果,如何转换对像?转换过程中如何处理关联?这确实是一个比较难处理的问题。我们都可以参考mybatis的实现方式,通过在构建查询sql的过程中,把sql中查询字段用类属性名字作为别名,这样mybatis就会自己转换成对像。对于hibernate来说,也可以通过写sql的方式,然后参考hibernate中的基于别名的结果集转换器AliasedTupleSubsetResultTransformer的实现机制来做到转换结果。如果要处理关联,也可以参考mybatis的方式,在别名点用一些点号(".")来处理关联列。而用hibernate时,我们也可以自己写一个结果集处理器,从AliasedTupleSubsetResultTransformer类继承,再在自己的处理器按照别名中的点号来自己实现关联结果的转换。这个过程可能有点复杂,但肯定是行得通的,因为我已经实现了。对于spring jpa,因为没有比较好的结果集处理方案,但是考虑到spring jpa底层,本身也可以依赖于hibernate作为持久化提供者。在这种情况下,我们对查询结果的处理,可以不用spring jpa的api而是退回来,使用原始的hibernate,采用跟hibernate一样的处理方式来处理结果集映射。
如何集成
通过以上分析,我们完全可以不依赖于mybatis和hibernate等特定框架而只采用jpa规范中的注解配合返射,就可以生成自己的sql语句,而且在生成sql语句的过程中,借鉴了mybatis中的按照别名的方式自动映射的机制,生成了方便处理结果集的相对规范的查询语句。
有了上述基础,做一个通用的框架就不难了。基于不重复造轮子的原则,参考spring jpa的架构思路。我们可以采用适配器的设计模式,同spring jpa一样把操作数据库的具体逻辑交给mybatis或hibernate等具体的提供方来实现(实事上,我们做的事情,就是spring jpa做的事情,只不过我们把跟本不支持jpa规范的mybatis也考虑进来了,通用性更强)。
这样,在使用通过这个通用框架的做出来的业务组件时,如果项目用的是mybatis,就通过配置,把操作数据的具体逻辑委托给mybaits实现,在用hibernate的项目里,就把这些逻辑委托给hibernate来做(可以把操作数据库的动作分为两大类,一类是insert,update,delete执行语句,另一类是需要映射结果的select语句)。这样,就实现了无需修改业务组件的代码,而通用于mybatis,hibernate等任何持久化化框架的项目中。
值得一提的是,在集成mybatis的时候,如何自己处理sql中的问题参数占位符,如何分页等,这都需要自己写mybatis插件来实现。另外还有其它的种种细节问题,这里就不多说了。本人已经按照这个思路实现了一个同时支持mybatis,hibernate和spring jpa并且支持一对多映射的通用框架,准备测试好后开源出来,有兴趣的朋友们可以扫以下二维码关注我的原创公众已获取最新信息。

时间: 2024-09-28 01:51:03

同时支持mybatis,hibernate等技术的通用持久层实现思路的相关文章

Hibernate延迟加载技术详解_java

本文实例讲述了Hibernate延迟加载技术.分享给大家供大家参考,具体如下: Hibernae 的延迟加载是一个非常常用的技术,实体的集合属性默认会被延迟加载,实体所关联的实体默认也会被延迟加载.Hibernate 通过这种延迟加载来降低系统的内存开销,从而保证 Hibernate 的运行性能. 下面先来剖析 Hibernate 延迟加载的"秘密". 集合属性的延迟加载 当 Hibernate 从数据库中初始化某个持久化实体时,该实体的集合属性是否随持久化类一起初始化呢?如果集合属性

Google Chrome浏览器支持沙盒Flash技术

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 除了不断出现的Flash安全漏洞,很多用户经常会使用不更新的Flash插件.因此,Adobe Flash经常成为攻击者的目标. Google Chrome浏览器的一大优点是内置Flash插件.由于Chrome浏览器是通过后台自动升级,因此内置插件总是可以得到及时更新,从而在很大程度上确保了Chrome用户的安全. 除此之外,Chrome还为用

率先支持第六代光纤通道技术 QLogic重申市场发展策略

3月初,QLogic与合作伙伴一道面向市场推出第六代32Gb光纤通道产品,并面向中国,就旗下光纤通道业务和以太网业务发展,重申市场策略. 不单是一家存储网络公司 更是一家有声望的网络连接公司 业界对QLogic的认可更多来自于光纤通道存储方面,据Dell′Oro Group在2015年第四季度光纤通道市场份额报告,从2012年到2015年,QLogic在光纤通道市场上的份额由53%上升至56%.无论在服务器还是在存储业务方面,QLogic都收获了光纤通道市场第一的表现.在以太网方面,QLogic

Hibernate作为数据持久层的分析和研究

数据 摘要 在Java技术中有许多方法可以对数据进行持久化,持久层也是Java应用程序中最重要的部分之一.本文在分析了3种持久层主流解决方案的基础上,介绍了O-R映射开源项目Hibernate,并介绍了在Web应用开发中怎样配置Hibernate的环境,并使用它建立一个应用. 关键字 hibernate,数据持久化,JDBC, EJB,JDO 数据持久层简介 J2EE的三层结构是指表示层(Presentation),业务逻辑层(Business Logic)以及基础架构层(Infrastruct

MyBatis持久层框架使用总结

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 2013年11月迁移到Github,MyBatis的Github地址:https://github.com/mybatis/mybatis-3.      iBATIS一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架.iBAT

java持久层框架mybatis防止sql注入的方法_java

sql注入大家都不陌生,是一种常见的攻击方式,攻击者在界面的表单信息或url上输入一些奇怪的sql片段,例如"or '1'='1'"这样的语句,有可能入侵参数校验不足的应用程序.所以在我们的应用中需要做一些工作,来防备这样的攻击方式.在一些安全性很高的应用中,比如银行软件,经常使用将sql语句全部替换为存储过程这样的方式,来防止sql注入,这当然是一种很安全的方式,但我们平时开发中,可能不需要这种死板的方式. mybatis框架作为一款半自动化的持久层框架,其sql语句都要我们自己来手

MyBatis持久层框架的用法知识小结_java

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录. MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google c

Java持久层框架MyBatis简单实例_java

什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .iBATIS一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架.iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO). MyBatis 本是apache的一个开源项目iB

区块链技术在物联网中应用的思路探讨

物联网作为新一代信息通信技术高度集成和综合应用的典范,正在与经济社会深度融合,深刻改变生产活动.社会管理.公共服务.随着物联网技术在各行业中的普及和不断深化,人类社会正进入"万物互联"的新时代,可穿戴设备.智能家电.自动驾驶汽车.智能机器人等数以百亿计的新设备将接入网络,也使得物联网成为当今全球技术创新最活跃.应用空间最广阔的领域之一. 云计算.大数据.新一代移动通信技术与智能感知.行业应用相互交织,激荡融合,不断激发创新活力,成为物联网发展的新动力.区块链技术作为当前国内外的焦点技术