基于mybatis的数据持久层研究

2020-06-29 12:36陈小虎邓惠俊
成都工业学院学报 2020年2期

陈小虎 邓惠俊

摘要:为解决传统的Mybatis数据库持久层在灵活性,可扩展性上存在的问题,在深入研究mybatis的技术架构和应用流程的基础上,利用数据库连接池技术和基于映射表的设计方案提出了基于连接池的mybatis持久层优化技术,通过实验的方式证明了该优化方案的有效性和可行性。在和c3p0、JDBC、tomcat-jdbc等中间件的性能对比实验证明,优化后的mybatis在持久层的读写性能有了10%以上的提升,有效地节约了服务器硬件成本,具有较高的实用性。

关键词:mybatis;持久层优化;高并发架构;读写性能

中图分类号:TP311.1文献标志码:A

文章编号:2095-5383(2020)02-0032-04

Abstract:  In order to solve the problems of flexibility and extendibility of persistence layer of traditional mybatis database, the technical framework and application process of mybatis was studied in-depth, and on this basis, the mybatis persistence layer optimization technology based on connection pool technology was proposed by using the database connection pool technology and the design scheme based on mapping table. The effectiveness and feasibility of this optimization scheme have been proved through experiments. Compared with the performance of c3p0, JDBC, Tomcat JDBC and other middleware, it proves that the read-write performance of mybatis optimized in this paper has been improved by more than 10% in the persistence layer, which effectively saves the cost of server hardware and has high practicability.

Keywords:

mybatis; persistent layer optimization; high concurrency architecture; read and write performance

在互联网企业级项目的開发中,数据库技术是最重要的一环,MySQL由于开源免费等优势,已经成为了企业项目的数据库首选,传统JAVA的企业框架通常采用基于JDBC的mybatis封装实现对数据库的优化。学术界企业界有很多关于mybatis的优化,魏静敏等[1]对mybatis的批量数据插入性能进行了研究,并对项目中常见的mybatis批量插入性能问题提出了解决方案。黄艳秀[2]利用mybatis进行了二次开发,结合spring的依赖注入技术,进一步提升了开发效率,降低了代码的耦合度。王渊博等[3]整合了mybatis和springmvc,利用mybatis生成了大量代码,提高了开发环境的自动化。荣艳冬[4]深入分析了mybatis建立持久层的技术方案,分析了mybatis存在的优势和劣势。上述方案更多是从应用层对mybatis进行创新或研究,但随着互联网业务功能的复杂化,数据量爆炸式增长,mybatis在持久层的开发便捷程度及性能开始出现瓶颈,本文立足于mybatis的底层功能,深入分析了mybatis的工作原理和框架技术,在此基础上提出了mybatis的持久层优化方案。

1 mybatis持久层方案研究

基于MySQL的服务器技术和面向对象的开发已经成为了当前互联网开发的主流,对于面向对象的技术而言,mybatis持久层操作的对象都是关系型数据库中的一条记录,因此在数据库基本的增删查改时都需要将代码中的对象转换为一条条数据库的记录,为了提升转换的效率,避免重复繁琐的工作,基于ORM(Object Relational Mapping,关系对象映射)的开发技术应运而生,ORM介于程序应用层和数据层,可以将对关系数据库的操作转换为代码中对象和属性的操作。当前常见的基于java的ORM框架有TopLink、Druid、c3p0、tomcat-jdbc等[5-8]。由于mybatis提供了更高的开发自由度,并且具有良好的结合和代码自动生成能力,可以大幅提高开发效率,因此受到更多开发者的欢迎。

1.1 mybatis执行原理

MySQL是一个集成了sql增删查改以及大量高级数据库操作的中间件,它封装了JDBC的所有操作,并且可以通过简单的xml配置和注解快速生成代码,提高开发者的生产力[9]。MySQL的框架设计采用分层的思想[10-11],从逻辑业务来说主要有3层:1)API接口层,该层提供了大量的API,这些API功能全面而且强大,可以让开发者直接调用,通过这些API大量简化了开发的工作。2)数据处理层,该层主要是通过java对象进行关系数据的解析,实现java实体与数据库数据的映射,从而完成对数据库的CURD操作[12]。3)基础配置层,该层主要负责配置数据的加载,数据库的管理连接,事务管理,是mybatis的底层驱动。

Mybatis主要是采用xml作為连接数据库和java代码的配置文件,利用分层的思想提高了系统的灵活性,另外mybatis采用了类似于MVC的方案,将系统分为DAO层[13]、service层、view层。而每次操作一个实体时都需要制定实体对应的ID,在大型系统中存在大量的数据表,指定ID的操作会变得非常繁琐复杂。同时mybatis的数据库连接还是基于简单的JDBC,建立连接和释放链接都会占用大量的系统资源。

1.2 对象文件编程优化

对象文件的简化主要是减少开发的复杂度,其方案如下:直接在根目录执行./gradlew mybatis Generator实现新增表映射方式。1)项目中的gradle控制面板中找到项目配置。2)在数据库中建立表结构信息。3)generatorConfig.xml 文件中配置要新映射的数据库表 注意: 一般需要删除不需要操作的表信息,单独留下需要操作的表信息。4)在gradle控制面板中找到项目根目录,在Tasks/mybatis 中双击运行目录中的 mybatisGenerator (涉及以下文件) - entity/ XxxxXxx文件 - entity/ XxxxXxxExample文件- entity/ XxxxXxxKey文件 - mapper/ XxxxXxxMapper文件 - mapper/ XxxxXxxSqlProvider文件。5)注意其中有些自定义修改的Mapper和provider文件要回滚或者合并(例如批量插入的逻辑)。

1.3 连接池优化

连接池优化方案的核心思路是利用独立的线程池来异步实现连的创建回收,采用定时的线程池来监控连接泄露。主要流程为:

1)申请连接,利用一个线程池mbsPool来对连接资源进行管理,用一个数据结构ConcurrentBag作为所有连接共享类,封装了PoolEntry对象,PoolEntry对象利用borrow方法从bag中获取,再通过PoolEntry.createProxyConnection来生成连接池的返回。

2)回收连接,当数据库操作完毕之后,调用close方法来通知连接池该线程可以关闭,此时通过mbsPool调用ConcurrentBag的fillPool方法来对连接池中的数据进行回收。同时也可以利用evictConnection方法手动对物理连接关闭,而本方法在线程池内部进行,一般不需要开发者显式调用。

3)创建连接,本文的优化方案定义了addConnectionExecutor类来完成新连接的生成,其具体的方法是PoolEntryCreate,当ConcurrentBag中存在等待线程,或者有连接被关闭时,会触发调用PoolEntryCreate。

另外需要注意的是,本文实现的连接池提供了3种类型,第1种是固定大小连接池(fixPool),该连接池在初始化前就配置好池的大小,一旦池满,有新的连接请求过来则会被丢弃不处理;第2种是DynamicPool,这是一种动态扩容的连接池,在连接池才启动时按照初始设置来配置连接池的大小,而当连接池中的连接数超过阈值时可以动态扩容;第3种是QueuePool,这种连接池的大小也已经在初始化过程中设置好,但是当连接池已经满了的情况下如果收到新的连接请求会将其放置到一个队列中,等到连接池空闲下来再从队列中按照先进先出的原则取出连接进行处理。

1.4 集成spring

Mybatis作为MySQL数据库的中间件,其主要作用是用于和j2ee框架的集成,本文的集成流程如下:

1)配置mybatis. 通过maven的打包工具,我们通过如下配置配好mybatis。

org.mybatis

mybatis-spring

1.2.0

org.springframework

spring-context-support

3.1.3.RELEASE

commons-logging

commons-logging

org.springframework

spring-jdbc

3.1.3.RELEASE

org.springframework

spring-test

3.1.3.RELEASE

test

org.aspectj

aspectjrt

1.6.8

org.aspectj

aspectjweaver

1.6.8

2)在spring中设置mybatis,为了让spring实例化mybatis组件,如sqlsessionfactory,sqlsession和mapper等对象,需要在spring中进行配置。在本文实现的方案中,一旦配置了sqlsessionfactory bean,就需要对应地配置sqlsessiontemplate bean,它是一个线程安全的spring bean,使用者可以从中获取线程安全的sqlsession对象。因为sqlsessiontemplate提供了线程安全的sqlsession对象,所以可以与多个springbean共享同一个sqlsessiontemplate实例。在概念上,sqlsessiontemplate类似于spring dao模块的jdbctemplate。

3)在完成了spring中的设置之后,可以开始进行ORM(实体关系映射)的配置,在spring的应用中,最常用的ORM操作主要是数据库的增、删、查、改。为了实现4大操作,需要完成关系数据库和实体的一一对应,也就是需要在实际开发中将每一个实体的操作都写到ORM配置里。

2 实验和结果分析

通过本文的优化算法,利用本文线程池技术对mybatis持久层的操作进行优化,并和常用的数据库持久层中间件c3p0、JDBC、tomcat-jdbc进行对比。对比实验方案如下:初始连接和最小连接都设置为15,最大连接设置为100,打开关闭数据库连接的次数设置为100万次,通过使用MySQL在不同线程并发下的响应时间来进行测试,测试结果如图1所示。

在分别5、20、50、100个连接数的情况下,其详细的响应时间如表1所示。

由表1可知,在高并发的响应时间上,本文方案>tomcat-jdbc>dbcp>c3p0。本文方案在并发较高的情况下,性能基本上没有下降,同时也可以看到c3p0连接池的性能很差,不建议使用该数据库连接池。

3 结语

本文针对mybatis在数据库持久化过程中开发逻辑复杂,数据库连接容易耗尽,读写操作响应时间慢等问题,提出了一套基于mybatis持久层的优化方案,本文设计了3种不同类型的连接池,开发者可以通过配置方便地选择自己需要的连接池类型,同时在连接池的实现部分,本文在连接池的创建、回收和关闭上通过异步的方式,在每次关闭连接的时候都将连接资源放回连接池,并让连接池管理了连接的断开、建立、回收等过程。通过和c3p0、JDBC、tomcat-jdbc等中间件的实验证明,本文优化后的mybatis在持久层的读写性能有了10%以上的提升,有效节约了服务器硬件成本,具有较高的实用性。

参考文献:

[1]魏静敏, 刘欢杰. 基于Mybatis框架的批量数据插入的性能问题的探讨[J]. 计算机光盘软件与应用, 2013(19):160-162.

[2]黄艳秀. 基于mybatis的面向數据库自动生成技术[J]. 河南科技, 2014(4):29-30.

[3]王渊博, 周树军. 农村物流“最后一公里”互联网信息服务平台研究[J]. 现代电子技术, 2018, 41(22):42-45,49.

[4]荣艳冬.关于Mybatis持久层框架的应用研究[J]. 信息安全与技术, 2015, 6(12):86-88.

[5]宋波, 刘杰, 周传生,等. 基于TopLink的J2EE数据持久层的实现[J]. 微电子学与计算机, 2006, 23(8):132-135.

[6]YANG F, TSCHETTER E, MERLINO G, et al. Druid: a real-time analytical data store[C]// Acm Sigmod International Conference on Management of Data,2014.

[7]于广和. MySQL数据库服务器下C3P0连接池的配置[J]. 金融科技时代, 2010(9):67.

[8]YONG S. A browser/server product data management system[C]// Power Electronics & Design, 2011.

[9]JEROEN O, DAVID J, SAIKAT D, et al. RMySQL: database interface and MySQL driver for R[J]. 2018.

[10]NASH T, OLMSTED A. Performance vs. security: implementing an immutable database in MySQL[C]// 2017 12th International Conference for Internet Technology and Secured Transactions (ICITST), 2017.

[11]SN R, MU±OZ A, CASTRO A L, et al. Executing complexity-increasing queries in Relational (MySQL) and NoSQL (MongoDB and EXist) size-growing ISO/EN 13606 standardized EHR databases[J]. JVis Exp, 2018(133).

[12]張世雄. PHP操作MySQL数据库的面向对象模型类实现[J]. 清远职业技术学院学报, 2018, 11(6):51-54.

[13]陈欣. 基于java三层构架的管理信息系统中DAO层的构建探索[J]. 科技资讯, 2015, 13(11):26-27.