自学内容网 自学内容网

借老系统重构我给jpa写了个mybatis风格的查询模块

因为公司老系统是用hibernate3开发的,重构自然过渡到使用Spring Data JPA。由于系统中对sql的使用方式还是手动为主,这就造成在service层存在大量的sql拼接方式,后续维护比较困难。
因为怀念以往项目对sql驱动的持久层开发用的mybatis的时光,笔者参考b站up主Java灭霸詹的手写mybatis系列,为JPA扩展了一个mybatis风格的查询模块。
在这里插入图片描述
在大佬讲解实现的基础上完成了plugin模块的编写以支持分页特性,同时扩展了mybatis的xml文件中的sql节点标签,让功能按照个人需求实现进一步的定制。
在整个代码实践过程中,笔者对mybatis的实现原理也有了进一步的认识,同时通过编写这个JPAmybatis风格查询的扩展模块,为后面做sql的重构也铺平了道路。

封装JDBC

对于JPA它的优势自然是ORM框架所具有的对象关系映射,而实际业务中存在大量手写sql的情况下,用JPA自然不是最好的选择,如果是公司架构的要求,那对JPA操作JDBC的那部分代码做一层封装,让其具有了mybatissql处理能力,自然会是一件两全其美的事情。
这里封装JPAJDBC操作,只是做了一层sql映射的逻辑层的节点树结构,在实际执行查询时会执行节点树,通过上下文的串联,将每个sql节点对应解析出来的sql进行拼接,得到要执行的目标sql。并在这个过程中完成sql中参数占位符的处理,映射参数列表。
sql执行所处的环境、数据源连接、事务环境这些都托管给了Spring管理。最底层只需要调用org.hibernate.Sessionsession.doReturningWork()方法操作jdbc即可。

xml中编写sql的示例

这里给出笔者实现该模块的示例查询:
在这里插入图片描述
这里在实现mybatis动态查询功能的基础上,做了一些扩展。比如这里的<in>标签、用于分页查询优化的<sql>标签。

in查询标签

mybatis在处理列表形式的参数时使用的<foreach>标签用起来比较麻烦,笔者在手写mybatis实现基础功能的基础上扩展了原有标签的功能,实现了简单易用的<in>标签。执行的效果和mybatis<foreach>标签一样:
在这里插入图片描述

分页查询

对于mybatis提供的plugin功能,市面上有类似于PageHelper这样的第三方插件来整合分页功能。笔者翻看其源码,体会到由于mybatis在封装上的一些安全性考虑,并没有为Plugin的拦截扩展功能开太多的口子,这就造成插件的第三方开发者需要做很多的设计和实现来适配。
而对于笔者手写mybatis来说,要扩展插件就变得简单了。框子是笔者定的,为了更好的扩展,可以适当的把口子开大点,让扩展更好的适配。在实现分页拦截器时,笔者为框子底层的类开了类似切面的口子,方便扩展:
在这里插入图片描述
这样基于笔者手写的mybatis,用短短20几行代码就实现了一个功能完备的分页插件:
在这里插入图片描述

分页功能的优化

目前市面上的分页插件对于分页的select count查询,并没有实现对内部sql的干预机制,更多的是在外面包一层select count(1) from (...) t,而内层的sql诸如select *的处理方式并没有屏蔽掉。所以count查询的效率自然不敢恭维。而笔者在扩展mybatis手写功能时,对这一块做了用户定制优化:
在这里插入图片描述
这里<sql>标签包裹的内容是在分页列表查询时必要的,而count查询将会被替换掉,如果指定了countSql属性,就用属性值代替,否则替换为空。这样无论一个结构多复杂的sql,用这种包裹和替换方式,都无需为了提高count查询效率,而单独写一个查询sql。执行结果正如我们所期望的那样:
在这里插入图片描述


原文地址:https://blog.csdn.net/felix_alone2012/article/details/143053230

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!