最近带一个新人,犯了一个比较低级的小错误造成功能崩溃:
1、使用jfinal的sql管理,为了方便拼接sql,使用了 where 1 = 1,然后判断参数是否存在追加 and xxx = xxx
2、刚好某句代码未将该有的参数传递过去;
3、刚好测试没有测出来;
4、刚好单表数据量较大,sql表关联较多,逻辑稍微复杂;
结果:
造成了findFirst执行了find后返回大量数据,最终内存消耗太高造成程序崩溃无响应。
建议:在findFirst中使用paginate分页查询,默认查询一页,每页1条数据,而不使用find进行查询list,避免此类问题发生。
select * from xxx where ... limit 1
这个设计在 8 年前是这么来考虑的:
1:不同的数据库由于限定方式不同所以 Dialect 中没有帮你加 limit 1,而是留给用户自己加
2:后来过了几年有人提出这个需求,希望 jfinal 自动加 limit 1,但这时考虑到会影响已经加过 limit 1的用户,也就没再动这里。虽然可以通过判断 sql 中是否存在 limit 来决定要不要加 limit,但代码不太优雅,也就作罢
3:不同的数据库是加不同的限定,如 Sql Server 是加 select top 1,所以想加也不太方便,担心会干扰现有 sql,不如用户自己加来得方便
4:退一步讲,findFirst 查询一般用的查询条件是 id 值,出现问题的情况并不多
总得来说还是该进一步处理一下,jfinal 3.7 考虑改进