今天遇到的一些问题

包括jdbc一些写法的问题,结构问题,jersey2整合swagger的问题

 

1.jersey2整合swagger

记得之前整合的过jersey2和swagger,但是当时swagger的版本是2.24(现在出到2.25了),当时整合得可谓是一帆风顺。但是这次整合的是2.22.2,足足落后了半年。因为版本要对应上,所以我只能选择2.22.2版本的swagger和jersey的整合包,没想到这样一搞就出了大问题。

(1)缺少各种依赖。

只是jersey本身的包是远远不够的,我还增加了一堆包。比方说swagger全家桶,然后jackson全家桶,之后是jersey的一系列组件包entity-filtering,media-json-jackson,media-multipart(估计是用来解析swagger上传的文件之类的),再之后是slf4j全家桶,再再之后是一个Apache出的Commons-Lang包,最后居然是一个google出的guava包。前前后后加起来数量轻松超过了10个。

我认为这是版本落后导致的。低版本的整合包可能自身不包含各种依赖,都需要手动添加。这就很尴尬了。

(2)对中文严重不友好。

之前我的新版本的swagger的注解是这样的:

问题是在现在的版本中,这个注解完全没有效果…ui中的选项不会变成相应的中文。

如果写成这样:

选项中是可以显示为中文了,但是读取接口的路径也会自动使用选项中的中文路径,浏览器会将中文自动转码,导致ui中的选项无法打开,只能通过右上角的Show/Hide等操作方法进行ui的操作。

无论是spring mvc和新版的jersey2,,我是完全没有遇到这种问题的,但是这个bug会在2.22.2中发生。

2.要及时关闭数据库链接

无论是使用orm框架还是jdbc,在任何时候都要注意这个底层的问题。orm框架往往帮我们做了链接的释放,但是在jdbc中,这个问题会被放大,显得特别重要。

如果只是进行链接而不释放,因为程序没有识别链接是否已经使用完毕的功能,就会导致数据库链接一直累积,直到达到数据库的链接上限。对于数据库来说,到达上限之后,可能造成正在使用的链接丢失,无法创建新连接等恶性后果。对于程序来说,不断创建链接对象会严重消耗内存,影响程序执行效率,吸引GC导致运行缓慢,甚至造成溢出,导致程序崩溃。这两种情况显然是我们不想看到的。所以,手动进行链接的释放在jdbc中显得尤为重要。

举个例子,这个是我认为正确释放链接的方法:

这样写可以正确释放链接,但是也会导致一些问题,下面将会提到。

3.如何正确构建jdbc的结构

上面这样写链接的释放,那么就要求数据库的链接不能为static

我之前是这样获取数据库链接的:

因为这里的Connection是static字段,只会在该类对象的初始化过程中在内存里创建一次,如果释放掉就会被置为null。之后所有尝试对数据库的操作都会抛出链接已经被释放掉的错误。

也就是说,我们已经不能使用同一链接了,只能动态去获取链接。如下:

每次调用该方法,都会重新去取链接。所以,我们每当需要执行一个方法,都会新创建一个链接,执行完数据库操作之后,就把链接释放掉。这样方法和释放都可以正常执行。

仔细回想一下2中的写法,这样真的是最佳解决方案吗?

这里没有考虑到方法之间相互调用的情况。假如方法A要去调用方法B,如果两个方法都要各自去取数据库链接,是不是A中取一次,B中取一次,然后各自释放掉?明明可以只取一个链接,然后完成所有操作的,为什么要取两次呢?

所以这里就要从结构进行优化:

service层的service.java

dao层的dao.java

这样就保证了链接的复用,并且能够正确释放资源。

但是,这真的是最佳解决方法吗?

如果分两层,我们岂不是要写很多代码?如果每个接口都要这样分层处理,那么就真的是夭寿了。

所以也要分情况,如果一个方法既不要调用别的方法,也不会被别的方法调用,那么写成2中的那种形势也是没有问题的。反正不用太在意链接的复用和释放。

还有一种高级的处理方式,就是通过传入参数、类、方法的信息到Service类的一个方法中,然后在方法中利用java反射去获取各种dao并且加以执行。这样只要写一个Service层就可以实现对所有dao的调用,起到一劳永逸的效果。

这点特别重要,我是从前辈的代码中留意到的。如果使用orm框架根本就不会注意到这种用法,需要好好学习下。

4.总结

总之,通过思考这几个问题,感觉自己仍然有很大的提升空间。特别是使用反射的做法,非常值得我去学习模仿。

发表评论

电子邮件地址不会被公开。 必填项已用*标注