admin 管理员组

文章数量: 1086019


2024年5月15日发(作者:免费模板网官网)

2017年第8期

信息与电脑

China Computer&Communication

计算机工程应用技术

基于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

Abstract:

In the early stage of design information management system, complex CRUD operations occupy most of the time the

(Ningxia Finance & Economics Vocational College, Yinchuan Ningxia 750021, China)

system design, the system development cycle of growth. Aiming at this problem, a design based on MyBatis, Sping and JAVA unified

development cycle of the system, and increasing the flexibility and scalability of the system.

data annotation to components, and introduced its application in enterprise OA system. The framework uses the mainstream MyBatis

Key words:

MyBatis; Spring; JAVA annotation; data persistence layer framework; ORM

and Spring framework, greatly simplifying the data additions and deletions, checking and modifying operations, shortening the

目前,基于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-),女,宁夏银川人,本科,讲师。研究方向:计算机应用。

— 73 —

计算机工程应用技术

信息与电脑

China Computer&Communication

2017年第8期

果值或者结果字段通过配置文件一一映射到指定POJO中。

实际上,使用MyBatis作为项目的ORM框架,SQL语句的

实际操作的控制权还是在程序开发人员手中,这样依赖系统

的灵活性得到很大的提升,性能也得到了提高,但是却需要

开发人员熟悉SQL语句,进行大量的配置,同时在数据库

的移植上会比其他ORM框架复杂得多,尽管如此MyBatis

以其灵活的使用方式吸引了一大批使用者,使用MyBatis做

ORM映射的系统有着更大的灵活性和自由空间。

Spring是一个轻量级的企业开源框架,主要是为了降

低企业级应用程序设计的复杂性,Spring不针对某个层的解

决方案,主要提供JAVA企业开发的各层解决方案。传统的

J2EE应用开发效率低,没有一个统一的技术来支撑各厂商的

应用服务器,使得J2EE程序没有真正实现“一处开发,处

处运行”的目的,而Spring作为一个应用中间件,其独立于

各应用服务器之上,在某些情况下甚至可以脱离应用服务器

而独立工作,因此,它成为了企业级应用开发的一站式解决

方案,但是Spring并不能取代其他框架,它是其他框架的粘

合剂,能让其他框架在一起很好地工作。Spring框架轻量,

最小可以打包在不到1 M的JAR包中发布,它具有控制反

转(Ioc)、面向切面、可以当作容器使用等特点,还具有

MVC、事务控制等功能,这些功能完全独立,开发者可以在

使用过程中按需引入,使用十分灵活简单

[1]

3 组件设计

鉴于以上的缺陷,本文提出了一种基于Spring和JAVA

注解方法的解决方案,首先看一下MyBatis的执行原理。

3.1 MyBatis执行原理

如图1所示,使用更改时序图来形象说明MyBatis的工

作原理,具体执行过程如下。

(1)应用程序调用相对应函数(一般和操作ID相同),

传入指定参数。

(2)读取XML配置文件,被调用的程序通过通过

以及操作对象名称找到对应的XML配置

文件。

(3)程序将对象和配置文件载入内存中。

(4)查找到对应ID的SQL语句。

(5)带入参数,程序根据映射文件映射的关系将传入

对象的属性替换成相对应的SQL所需要的参数值。

(6)执行SQL语句,将替换完参数的SQL语句通过驱

动程序传入数据库管理系统中执行。

(7)返回结果,根据XML文件中对应操作ID配置的

返回类型,将执行SQL语句后的结果返回给应用程序。

具体Update的执行过程如图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.2 设计思路

了解了执行原理后,可以发现只要能让程序在运行中自

动找到相对应的XML配置文件而不需要程序员手工指定就

可以弥补上文中提到的第二个缺陷。

为了让JAVA应用程序在运行的过程中动态获取到这个

对象实体在XML映射文件中配置的SQL语句,可以使用

JAVA的反射功能和JAVA的注解功能来实现

[3]

。事先需要在

每个POJO对象类上增加一个自定义注解,注解上标明该对

象所对应的XML映射文件名称、主键名称、不需要查询的

列名称以及其他需要的信息,然后使用JAVA的反射功能,

让应用程序在JAVA虚拟机运行的过程中获得该对象对应

的XML文件名称,通过查找文件内容找到某次操作对应的

SQL语句。

J2EE企业级应用程序开发一般都采取三层结构,即持

久层、业务逻辑层、展现层,在应用程序中一般都会有持久

图1 MyBatis基本执行原理

— 74 —

2017年第8期

信息与电脑

China Computer&Communication

计算机工程应用技术

层对应的数据接口DAO和实现数据接口的DaoImpl,业务

逻辑层的接口Service和实现该接口的ServiceImpl以及展示

层的Action或者Servlet。应用系统中的每个业务模块几乎

都需要这五个结构。如果该应用系统比较大,或者每个业务

模块之间存在着调用引用等耦合现象的话,在各层就需要进

行大量的配置工作,尤其是在Action和Service层。为了解

决配置复杂的难题,在开发应用程序之前,就需要设计一个

公用的底层数据接口Dao,Dao中几乎包含了对单表实体操

作的所有功能,然后根据该Dao配置好对应的XML文件,

接着设计一个Service接口,该接口中使用Dao完成绝大多

数增删改查等工作。然后在引用系统的展现层Action中就

只需要申明一个Service就可以完成对单表的操作。由于系

统集成了MyBatis和Spring,所以Dao的实现一般都要继承

SqlMapClientDaoSupport

[5]

。具体设计类图如图2所示:

[4]

询时将类型为blob和clob的属性去除,原因在于查询和更

改时不会经常查找和更改blob的字节类型和clob的长文本

类型,将类型为blob和clob的字段排除在外,以提高系统

运行的效率。

(6)AnnotationInject:这是一个工具类,主要根据JAVA

反射和实体中的注解信息在程序运行过程中获得相关的信息。

(7)SqlClientDaoSupport:该类为Spring中封装的使用

MyBatis操控数据库的工具类。

(8)AccountDao、AccountDaoImpl、AccountService、

AccountServiceImpl、AccountAction为系统中为说明实现某种特殊功

能而增加的一个实际账户例子,AccountDao继承CommonDao,

AccountDaoImpl继承SqlClientDaoSupport实现AccountDao,AccountService

继承CommonService,AccountServiceImpl为AccountService的实现类。

通过数据提交组件更新上例中的Account得到的顺序图

如图3所示:

图2 组件类图

图3 使用组件更新Account顺序图

(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的字段的原因是在查

通过图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查找、通过对象查找、

— 75 —

计算机工程应用技术

通过ID查找唯一对象、分页查找等。

3.3.2 CommonService

信息与电脑

China Computer&Communication

2017年第8期

@interface OrmAnnotation {

String table() default "";

String pk() default "";

String fk() default "";

String namespace() default "";

String bytes() default "";}

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和,在注解内部增加了

table、pk、fk、namespace、bytes等属性,具体实现代码如

下所示:

@Retention(E)

@Target()

其中table表示该实体对应的关系数据库的表名,pk表

示主键属性,fk表示外键关联属性,namespace表示该实体

在配置文件中对应在哪个命名空间下,用于自动寻找操作ID

和对应的SQL语句,tytes表示实体中类型为byte[]对应关

系数据库中类型为blob的字段,用于排除查询条件。同时为

了能在程序中方便得到namespace的值,需要设计一个工具

类来实现AnnotationInject。

3.3.4 调用示例

在Action或者Servelet中声明一个CommonService的

实现类service,然后使用(object)来实现对

实例的操作,比如增加一个用户(user)、更新

一个账户(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.

— 76 —


本文标签: 对象 系统 操作 实体 应用