基于MyBatis和Spring的JavaEE数据持久层的
研究与应用
乔 岚
(宁夏财经职业技术学院,宁夏 银川 750021)
摘 要:在信息管理系统的设计初期,繁杂的增删查改操作占据了系统设计的大部分时间,使系统的开发周期延长。笔者针对这一问题,设计了一种基于MyBatis、Sping和JAVA注解的数据统一提交组件,并介绍了其在企业办公OA系统中的应用。框架使用了主流的MyBatis和Spring框架,大大简化了数据的增删查改操作,缩短了系统的开发周期,增加了系统的灵活性和可扩展性。
关键词:MyBatis;Spring;JAVA注解;数据持久层框架;ORM
中图分类号:TP311.52  文献标识码:A  文章编号:1003-9767(2017)08-073-04
Research and Application of JavaEE Data Persistence Layer based on MyBatis
and Spring
Qiao Lan
(Ningxia Finance & Economics Vocational College, Yinchuan Ningxia 750021, China) Abstract: In the early stage of design information management system, complex CRUD operations occupy most of the time the system design, the system development cycle of growth. Aiming at this problem, a design based on MyBatis, Sping and JAVA unified data annotation to components, and introduced its application in enterprise OA system. The framework uses the mainstream MyBatis and Spring framework, greatly simplifying the data additions and deletions, checking and modifying operations, shortening the development cycle of the system, and increasing the flexibility and scalability of the system.
Key words: MyBatis; Spring; JAVA annotation; data persistence layer framework; ORM
目前,基于B/S模式的三层或者多层的开发模式已成为了Web开发的主流方法,在系统的开发和使用过程中应用系统需要频繁对关系数据库中的记录进行增删改查操作,由于面向对象方法的普遍适用,在应用系统中数据表现为对象,在关系数据库中数据表现为带有关系的一条条记录,所以在插入时必须将对象转换为关系数据通过SQL插入到关系数据库中,而对于查询又必须将关系数据组装成对象供程序使用,如何避免这一繁琐的操作呢?关系-对象映射(ORM)的出现解决了这一问题,ORM在系统应用层
和数据存储层之间建立一个一一对应的关系,把对关系数据的操作直接转化为对对象方法和属性的操作。目前主流的ORM框架主要有TopLink、Hibernate、Apache OJB、EJB、MyBatis等。但由于MyBatis自由灵活,因此,受到了很多用户的喜爱。本文就基于MyBatis提出了一种数据统一提交组件。1 MyBatis和Spring简介
MyBatis是一个半自动化的ORM框架,主要作用是将POJO与数据库中的表对应,在应用开发中采用面向对象的方法操作数据库记录。Mybatis的核心思想主要是在XML文件中配置好对关系数据库的所有操作的SQL语句,同时为每一条SQL语句配置一个ID,用来作为操作的标识符,此外还需要配置参数值以及返回值。所以MyBatis是一种半自动化的ORM框架,对于熟练使用面向对象编程的程序开发人员来说,通过MyBatis来操作对象就可以对关系数据库进行操作,这一点和Hibernate等是一样的,但是MyBatis并不会在运行期自动生成SQL执行,具体的SQL需要开发人员自己编写,然后在程序中指定每个操作的操作标识符ID,接着通过操作ID在XML配置文件中到相应的SQL语句,同时将需要执行的SQL语句中的所需的操作参数、返回的结
作者简介:乔岚(1982-),女,宁夏银川人,本科,讲师。研究方向:计算机应用。
果值或者结果字段通过配置文件一一映射到指定POJO中。实际上,使用MyBatis作为项目的ORM框架,SQL语句的实际操作的控制权还是在程序开发人员手中,这样依赖系统的灵活性得到很大的提升,
性能也得到了提高,但是却需要开发人员熟悉SQL语句,进行大量的配置,同时在数据库的移植上会比其他ORM框架复杂得多,尽管如此MyBatis 以其灵活的使用方式吸引了一大批使用者,使用MyBatis做ORM映射的系统有着更大的灵活性和自由空间。
Spring是一个轻量级的企业开源框架,主要是为了降低企业级应用程序设计的复杂性,Spring不针对某个层的解决方案,主要提供JAVA企业开发的各层解决方案。传统的J2EE应用开发效率低,没有一个统一的技术来支撑各厂商的应用服务器,使得J2EE程序没有真正实现“一处开发,处处运行”的目的,而Spring作为一个应用中间件,其独立于各应用服务器之上,在某些情况下甚至可以脱离应用服务器而独立工作,因此,它成为了企业级应用开发的一站式解决方案,但是Spring并不能取代其他框架,它是其他框架的粘合剂,能让其他框架在一起很好地工作。Spring框架轻量,最小可以打包在不到1 M的JAR包中发布,它具有控制反转(Ioc)、面向切面、可以当作容器使用等特点,还具有MVC、事务控制等功能,这些功能完全独立,开发者可以在使用过程中按需引入,使用十分灵活简单[1]。
2 MyBatis现存缺陷
MyBatis灵活方便,SQL Maps组件让开发人员在脱离了JDBC API、JAVA代码以及SQL语句的情况下直接对对象和关系数据库进行读写操作。但是,MyBatis也有自己的缺陷,具体如下。
(1)MyBatis以XML作为对象与数据库的中间配置文件,虽然可以提高系统的灵活性、降低程序的耦合
性,但是随着对象数量的不断增长,程序员将编写大量的XML配置文件,尤其是开发大型商业系统时,如大型ERP系统,系统中包含的数据表达到几百张,如果手工为每一张表都编写相应的配置文件,其工作量可想而知[2]。
(2)在如今的系统开发中都采用分层思想,把系统分为DAO(数据访问)层、Service(业务逻辑)层、View(表示)层,而DAO层的大部分工作是对实体进行增删查改操作,由于MyBatise是将所有操作存放在XML配置文件中,于是在DAO层中操作每个实体时必须手工指定操作的ID,这样程序才能到相应的SQL语句并执行,所以在系统实体较多的情况下DAO层的实现非常繁杂和重复,并且在使用Spring的情况下,Spring中DAO层Bean的配置文件也将变得繁琐复杂。
第一个缺陷的解决方法相对简单,可以自制相应的配置工具,每一个对象生成其相应的XML配置文件。下面主要介绍对第二个缺陷的解决方案,并基于该方案设计一个数据统一提交组件。3 组件设计
鉴于以上的缺陷,本文提出了一种基于Spring和JAVA 注解方法的解决方案,首先看一下MyBatis的执行原理。3.1 MyBatis执行原理
如图1所示,使用更改时序图来形象说明MyBatis的工作原理,具体执行过程如下。
(1)应用程序调用相对应函数(一般和操作ID相同),传入指定参数。
(2)读取XML配置文件,被调用的程序通过通过l以及操作对象名称到对应的XML配置文件。
(3)程序将对象和配置文件载入内存中。
(4)查到对应ID的SQL语句。
(5)带入参数,程序根据映射文件映射的关系将传入对象的属性替换成相对应的SQL所需要的参数值。
(6)执行SQL语句,将替换完参数的SQL语句通过驱动程序传入数据库管理系统中执行。
(7)返回结果,根据XML文件中对应操作ID配置的返回类型,将执行SQL语句后的结果返回给应用程序。
具体Update的执行过程如图1
所示:
图1 MyBatis基本执行原理
3.2 设计思路
了解了执行原理后,可以发现只要能让程序在运行中自动到相对应的XML配置文件而不需要程序员手工指定就可以弥补上文中提到的第二个缺陷。mybatis和springmvc
为了让JAVA应用程序在运行的过程中动态获取到这个对象实体在XML映射文件中配置的SQL语句,可以使用JAVA的反射功能和JAVA的注解功能来实现[3]。事先需要在每个POJO对象类上增加一个自定义注解,注解上标明该对象所对应的XML映射文件名称、主键名称、不需要查询的列名称以及其他需要的信息,然后使用JAVA的反射功能,让应用程序在JAVA虚拟机运行的过程中获得该对象对应的XML文件名称,通过查文件内容到某次操作对应的SQL语句。
J2EE企业级应用程序开发一般都采取三层结构,即持久层、业务逻辑层、展现层,在应用程序中一般都会有持久
层对应的数据接口DAO 和实现数据接口的DaoImpl ,业务逻辑层的接口Service 和实现该接口的ServiceImpl 以及展示层的Action 或者Servlet [4]
。应用系统中的每个业务模块几乎都需要这五个结构。如果该应用系统比较大,或者每个业务模块之间存在着调用引用等耦合现象的话,在各层就需要进行大量的配置工作,尤其是在Action 和Service 层。为了解决配置复杂的难题,在开发应用程序之前,就需要设计一个公用的底层数据接口Dao ,Dao 中几乎包含了对单表实体操作的所有功能,然后根据该Dao 配置好对应的XML 文件,接着设计一个Service
接口,该接口中使用Dao 完成绝大多数增删改查等工作。然后在引用系统的展现层Action 中就只需要申明一个Service 就可以完成对单表的操作。由于系统集成了MyBatis 和Spring ,所以Dao 的实现一般都要继承SqlMapClientDaoSupport [5]。具体设计类图如图2
所示:
图2 组件类图
(1)CommonDao :该接口中定义了一系列通用的操作实体类的方法,如Save 、Delete 、Update 、Get 、Find 、分页查询,通过SQL 语句查询或使用存储过程查询等。
(2)CommonDaoImpl :CommonDao 的实现类,借助于MyBaise 和SQL 的结合,实现所有基本的增
删改查等功能,注意在设计实现类时,XML 配置文件中的查询列表不要使用“*”符,而尽量使用数据表的列标题,一是为了后来更改数据库表时XML 文件只需要在对应的列语句中更改相对应的列名称,二来对于一些无关紧要的自己可以精简,以此提高系统运行的效率。
(3)CommonService :该接口为通用服务类接口,定义了一系列通用服务方法,包括对实体的增删查改,同时增加了这些方法的重载,并且扩展了一些高级功能,比如查询数量、获得主键、检查更新时间戳、统计分析等。
(4)CommonServiceImpl :CommonService 的实现类,在CommonServiceImpl 中包含了CommonDao 的一个实现实例Dao ,Dao 使用Spring 的依赖注入框架IoC 来实现注入。
(5)Ormannotation :这是一个注解,在数据提交组件中最关键的就是在程序运行时自动到实例所对应的配置文件,该信息就保存在实体类上加的注解中,注解中包含了配置文件信息、对应的表名、主键、外键和表明blob 、clob 的字段名等信息,增加表明blob 和clob 的字段的原因是在查
询时将类型为blob 和clob 的属性去除,原因在于查询和更改时不会经常查和更改blob 的字节类型和clob 的长文本类型,将类型为blob 和clob 的字段排除在外,以提高系统运行的效率。
(6)AnnotationInject :这是一个工具类,主要根据JA V A 反射和实体中的注解信息在程序运行过程中获得相关的信息。
(7)SqlClientDaoSupport :该类为Spring 中封装的使用MyBatis 操控数据库的工具类。
(8)AccountDao 、AccountDaoImpl 、AccountService 、AccountServiceImpl 、AccountAction 为系统中为说明实现某种特殊功能而增加的一个实际账户例子,AccountDao 继承CommonDao ,AccountDaoImpl 继承SqlClientDaoSupport 实现AccountDao ,AccountService 继承CommonService ,AccountServiceImpl 为AccountService 的实现类。
通过数据提交组件更新上例中的Account 得到的顺序图如图3
所示:
图3 使用组件更新Account顺序图
通过图3可以得知系统更新一个账户(Account )只需调用CommonDao 传入一个添加了注解的账户的实例,就可以实现更新。同理,如果系统是要更新一个用户(User ),那么在CommonDao 中传入一个添加了注解的User 实例即可,修改系统内其他实体同理,通过组件对系统内所有的实体进行增删查改的操作都可以使用CommonDao 来实现,而不需要为某个实体专门编写数据访问接口。在展现层(Action/Servlet )中对多个实体进行操作时也只需要定义一个CommonService 。
同时如果系统中对Account 实体有特殊的操作需要,例如对Acount 的统计分析、关联等,CommonDao
无法满足时可以自定义一个AccountDao ,让其继承CommonDao ,同时添加自己的特殊操作即可。  3.3 详细设计 3.3.1 CommonDao
CommonDao 是一个通用的数据库操作接口,其需要通过MyBatis 操控底层的数据库,因此需要到相应的配置信息。由于操作的对象不同,所需的配置信息也不同,需要在程序运行时动态获取,所以每个方法中都需要一个namespace 的参数。具体的接口定义的函数有保存、更新、隐藏、逻辑删除、物理删除、通过Map 查、通过对象查、
通过ID查唯一对象、分页查等。
3.3.2 CommonService
CommonService接口是服务层的通用接口,其接收应用层传过来的实体对象参数,然后通过注解和JAVA反射获取配置信息,传给数据操作层,所以接口参数中不需要指定namespace参数,但是在有searchListByMap对象的实例中没有办法获取到配置信息,必须手动指定。具体接口设计包含功能如下:
void save(Record record):保存一个对象;
boolean isExists(Record record):判断某个对象是否存在;
void saveOrupdate(Record record):保存或者更新一个对象,如果该对象ID存在就更新,否者就新增;
void update(Record record):更新一个实体对象;
void del(Record record, int flag):删除一个对象,flag为1表示逻辑删除,为0表示物理删除;
void del(Record record, Map map):通过一个Map对象删除一个对象;
List searchListByMap(Record record, Map map):通过一个Map对象查匹配的实体列表;
List searchListByMap(String namespace, Map map):通过Map对象和命名空间直接查实体对象列表;
Object searchObjectByMap(Record record , Map map):通过Map查单个实体对象;
Object searchObjectByMap(String namespace, Map map):通过Map和命名空间查单个实体对象;
List searchListByObject(Record Record):通过实体对象查和该实体对象属性相同的对象列表;
Object searchObjectByObject(Record record):通过实体对象查单一实体对象;
Object searchById(Record record , long id):通过实体对象和对象的ID查到唯一的实体对象;
Object searchById(String namespace, long id):通过命名空间和实体对象的ID直接获取到唯一的实体对象;
List searchAll(Record record):通过实体对象查所有的实体对象。
3.3.3 OrmAnnotation
SQL语句可以通过配置文件来获取并执行,但是如何让JAVA虚拟机在运行时知道该实体对应的XML文件在哪里,到文件后如何查到对应的SQL呢?上面已讲过可以通过JAVA反射和注解来实现,主要配置RetentionPolicy. RUNTIME和ElementType.TYPE,在注解内部增加了table、pk、fk、namespace、bytes等属性,具体实现代码如下所示:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface OrmAnnotation {
String table() default "";
String pk() default "";
String fk() default "";
String namespace() default "";
String bytes() default "";}
其中table表示该实体对应的关系数据库的表名,pk表示主键属性,fk表示外键关联属性,namespace表示该实体在配置文件中对应在哪个命名空间下,用于自动寻操作ID 和对应的SQL语句,tytes表示实体中类型为byte[]对应关系数据库中类型为blob的字段,用于排除查询条件。同时为了能在程序中方便得到namespace的值,需要设计一个工具类来实现AnnotationInject。
3.3.4 调用示例
在Action或者Servelet中声明一个CommonService的实现类service,然后使用hod(object)来实现对实例的操作,比如增加一个用户service.save(user)、更新一个账户service.update(account)、查所有的商品service. searchAll(good)等。
4 结 语
现如今许多企业已不同程度地实现了信息化,但是随着业务的发展各种信息系统功能不断增加,涉及的
数据库表增多,表之间的关系复杂,表结构变化频繁、数据量大,这样对于基础数据的维护成了系统开发升级中繁琐但又不得不做的工作,以至于延长了系统开发的周期。虽然Hibernate在解决数据的增删查改问题方面很有优势,但是Hibernate在一些特定的环境中,如老系统升级、表结构封闭、对查询要求极为苛刻的条件下就不太合适了,故笔者提出将基于MyBatis的数据统一提交组件应用于现有的系统中,缩减了系统开发周期,同时也增强了系统的灵活性,对于企业信息系统的建设有很好的借鉴和参考价值。
参考文献
[1]李洋.SSM框架在Web应用开发中的设计与实现[J].计算机技术与发展,2016,26(12):190-194.
[2]徐雯,高建华.基于Spring MVC及MyBatis的Web 应用框架研究[J].微型电脑应用,2012,28(7):1-4,10.
[3]林显忠.基于SSM框架的思想政治工作方法分析系统设计与实现[J].金融科技时代,2017(1):36-39.
[4]贺军,焦荣.基于XML应用的MyBatis技术[J].火力与指挥控制,2013(z1):86-88.
[5]阳小兰,罗明.基于Spring+SpringMVC+MyBatis网上论坛的设计与实现[J].黑龙江科技信息,2016(36):279-280.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。