[框架那点事儿-快速开发季]编写自己的数据持久层(6)思考

news/2024/11/9 15:49:07 标签: 框架, object, sql, string, class, null
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

这一章题目是思考,是因为工作进行到现在,我开始反思着一些API,到底能覆盖多少的日常工作,带来多少的便捷。从最开始的插入开始,到现在已经完成了根据class="tags" href="/tags/SQL.html" title=sql>sql来实现分页查询,我发现用这种纯面向对象的API封装思想去开展我的工作已经无法满足自己大脑中能思考到的使用场景。

比如目前我们的查询API,其参数形式都是默认采用AND的关系,同时由于采用的是Map来保存参数,导致无法使用多个同样参数的条件,比如下面这2条class="tags" href="/tags/SQL.html" title=sql>sql:

 

select id from person where age=25 or age =27;

select id from person where age=25 and age=27;

 

他们有两个查询条件,但是却只有一个age列作为查询一句,同时对于参数也是具有两个不同的值,并且,一个是AND的关系,另一个是OR的关系,使用我们封装的API,将无法满足这样的需求。那么该怎么办呢?我想过很多种方案,但是直到现在,我依旧能想出新的应用场景,导致上一种方案无法满足需求。一种极端的思想:

 

Map<Map<String,Object>,OperateEnum>  其中的key值是具体的条件键值对,后面的是当前的条件与其他的条件是什么关系的枚举。

然后组装class="tags" href="/tags/SQL.html" title=sql>sql的时候可以使用上述的内容解析。但是,下面一种情况呢:

 

SELECT * FROM PERSON WHERE (AGE=25 OR AGE=26) AND STATUS=1;

我们知道在同时具有or和and的表达式中,表达or关系的语句必须要包含其来,否则很容易出现关系结合错位。

 

当这种情况出现的时候,即便是那种极端的方案我们还是一筹莫展。该怎么办呢?曾经我一度陷入到这个问题中,于是去看hibernate,看ibatis,发现hibernate提供了非常复杂的API,纵然解决了这个问题,但是对于使用者而言,并没有减少工作反而增加不少,而且很容易出错。再看看ibatis,这个问题很容易的被解决是因为他使用的是映射文件的形式,其中不过是些class="tags" href="/tags/SQL.html" title=sql>sql,所以这个问题对其而言,迎刃而解。那么我们该怎么做,是学习hibernate去封装一堆的API出来,让使用者不断的采用add的方法去添加后缀,然后得到一个并不复杂的class="tags" href="/tags/SQL.html" title=sql>sql,然后执行?

这样的工作是无意义的,我们的目的是降低工作量,而不是增加复杂度和使用门槛。所以无奈之下,我想还是沿用ibatis的思想吧,就是接收class="tags" href="/tags/SQL.html" title=sql>sql,就让使用者来告诉我,这个class="tags" href="/tags/SQL.html" title=sql>sql是什么样子吧!

 

所以我们接纳合法的class="tags" href="/tags/SQL.html" title=sql>sql:

select * from table where param1=? and (param2=? or param3=?) order by param4 desc;

这样的一条class="tags" href="/tags/SQL.html" title=sql>sql,使用了占位符的形式,对于使用者而言并不困难。

而对于只查询一条结果的情况,干脆就直接使用具体的值来替代占位符吧,这样省去了使用者使用Map<String,Object>的麻烦。

 

那么我们就需要提供支持使用class="tags" href="/tags/SQL.html" title=sql>sql来进行数据库操作的API,增加以下几个API:

 

 

 

 

 

 

 

 

 

 

 

这几个API,支持了class="tags" href="/tags/SQL.html" title=sql>sql作为参数直接进行数据库操作。而之前的那几个api,是我一直很希望能达到的一种结果,既不要像ibatis这样使用配置文件编写class="tags" href="/tags/SQL.html" title=sql>sql,导致映射文件和java文件同时编写增加出错率,也不要像hibernate那样api使用起来需要特殊学习。那他们的定位就是作为便捷方法吧,虽然他们的功能,上面这几个方法也能实现,但是在使用上,他们并不需要编写具体的class="tags" href="/tags/SQL.html" title=sql>sql,只需要像操作API一样的调用方法,传入参数,拿到结果就可以了。

 

工作进行到目前为止,这个过程中,在进行工作前很多的没想到的问题都已经逐渐清晰,比如封装的过程中,会遇到哪些问题,需要注意哪些问题,这里可以简单的总结一下:

1、封装的api的类型,增删查改只是一个笼统是说法,单纯就 查 而言,就可以细化成无数种,比如使用单个字段查,使用多个字段联合查,联合查的字段的关系是AND还是OR还是BETWEEN还是同时存在,比如分页查询某列,分页查询对象,排序查询等等等等。增加可以分成单个对象增加,批量增加等等。难倒这些都要去通过封装提供吗?对于查询的分类而言,是无法通过一个又一个api去满足,然后提供给使用者一堆的API,让他们去费劲脑汁的选择,这样是得不偿失的,不能单纯的为了封装而封装。而如果要达到一个简练的封装,是否要提供一个解析算法,动态的解析使用者到底要什么样的class="tags" href="/tags/SQL.html" title=sql>sql?这样该如何去设计,至少现在我还没想好。

2、对于数据库类型和DO类中类型的转换问题,是使用一个Object笼统的概括掉,还是使用? extends Object更精准的定位,对于一个api的返回值,在多种应用场景下,是否满足大多数的而且是便捷而友好的?

3、该如何去选择jdbcTemplate提供的方法来实现我们的功能,是query还是queryForList,是update,还是batchUpdate,这些都是要在特定的api中具体思考的。

4、整个抽象类的设计上,抽象出来的原子方法是否可以为不同的包装api服务?比如类中queryForList和queryForMap两个方法,还有rowMapper的转换方法,我们抽象出来以后,向上封装了多种多样的api,虽然底层都是这几个基础服务,但是对外丰富的封装手段将使得我们的父类功能完善多种多样。

5、这个封装的过程,到底为了什么,我们将是为了提高开发效率,降低编码工作量,所以在设计api的时候,其输入输出一定要保证简捷,易用,至少目前虽然采用了@Table的注解方法解决获取表名称的问题,还是会想是否有更好的方法,比如外部传入对象类型的问题等等。

 

就让这个过程当做是自己的学习和修炼吧,以后再次遇到相同的工作,多想想这一次的经历,我得到了什么样的经验,遇到了哪些问题,这或许才是本次工作最重要的收获吧!

 

最后附上目前为止的整个类的内容://后续将继续封装。。。。

 

 

 

注解方法:

 

 


http://www.niftyadmin.cn/n/1639139.html

相关文章

[框架那点事儿-快速开发季]编写自己的数据持久层(7)总结篇

// 备注&#xff1a;本章节的代码较多&#xff0c;在IE下显示有点问题&#xff0c;请用firefox浏览&#xff0c;或者请留下邮箱&#xff0c;我会将整个工程打包发送 在前面的六篇文章中&#xff0c;针对日常开发常用到的DB的操作对spring框架的jdbcTemplate进行了一定的封装&am…

Java生成并导出Json文件

将一个list集合转换成json文件并导出&#xff1a; 数据集合&#xff1a;List<Object> agencyList new ArrayList<Object>();Map<String, Object> agencyMap new HashMap<>();agencyMap.put("agencyName",agencyName);agencyMap.put("…

使用JST模板引擎加快页面交互内容开发

首先看一个需求&#xff1a; 页面上存在一个select box&#xff0c;当选择了下拉框中的一个选项的时候&#xff0c;异步请求获取数据并在页面某个区域显示出来。而且这个显示区域是具有样式和自己固有的js等内容的&#xff0c;并非简单的静态文字。 如果用传统的js方式&#x…

[前端控件开发]freemarker框架下编写自己的分页器

对于web系统来说&#xff0c;分页器就好像是一个器官&#xff0c;是无论如何都必须要具备的一项功能&#xff0c;而分页器呢&#xff0c;是既通用又无怪乎那么几种样子&#xff0c;所以我们这里就利用添加了freemarker框架的一个系统来做自己的分页器。先看下结果样子&#xff…

优化Elasticsearch查询性能

给文件系统缓存提供内存 Elasticsearch严重依赖于文件系统缓存&#xff0c;以便快速进行搜索。 通常应该确保至少有一半的可用内存进入文件系统缓存&#xff0c;以便Elasticsearch可以将索引的热区域保留在物理内存中。 使用更快的硬件 如果搜索受I / O限制&#xff0c;应该调…

[小插曲]spring+freemarker中文乱码了,囧

spring freemarker 中文乱码了&#xff0c;其实是配置的时候粗心忘了配置viewResolver的编码&#xff0c;只配置了freeMarkerConfigurer的default-coding。 配置一下即可&#xff1a; <bean id"freeMarkerConfigurer"class"org.springframework.web.servlet…

Elasticsearch的Bulk API使用

1、Elasticsearch的Bulk API允许批量提交index和delete请求。如&#xff1a; &#xff08;1&#xff09;用法1 BulkRequestBuilder bulkRequest client.prepareBulk(); bulkRequest.add(client.prepareIndex("index1", "type1", "id1").setSou…

[HeadFirst]观察者模式 - 老王跳灰机的故事

写博客&#xff0c;看博客&#xff0c;要的是直接进入主题&#xff0c;不要太多的前戏&#xff0c;否则读者看着看着就没了兴趣。 所以直接看设计模式-观察者模式的图示介绍&#xff1a; 所谓的主题&#xff0c;即被观者的对象&#xff0c;当这个对象发生变化的时候&#xff0…