JSP自定义标签动态sql条件处理

JSP自定义标签
placeholder image
admin 发布于:2015-11-20 18:05:48
阅读:loading

这是一些很早之前写的代码了,一来丰富一下系统的内容量,二来觉得这些个实现方法特别的好,坚决不能丢了,近期将其整理整理,本篇着重的讲一下查询标签中的sql处理方式。

既然是处理sql,显然离不开要说道dao层的实现了,可以在关于系统栏目下找到关于系统持久层解决方案中的相关描述,也可就只看此篇对于查询标签的sql处理。

处理sql的相关问题:

1、sql的参数传递问题,如果直接在页面上sql页面上是否方便维护逻辑?

查询sql语句中包括一些基本的参数可以通过el表达式${param.xxx}的方式进行获取,可拼接在sql语句当中,参数值获取很方便,不对页面的美观造成影响,参考效果如下:

<my:queryOne

sql="SELECT

             userid AS 'userId' , realname 'realName' FROM sysuser

         WHERE

             userId = ${param.userId }">

如果要说有对此处传递的sql存在注入问题的时候,我们可以专门的对这个参数值进行处理,也可使用过滤器对所有传递的参数进行特殊字符的过滤,包装来解决;另外一种解决方案,也可以这么干,这是对sql语句中的特殊表达式做特殊的处理,参考如下:

<my:queryOne

sql="SELECT

             userid AS 'userId' , realname 'realName' FROM sysuser

         WHERE

             userId = [{userId}]">

它将会采用“?”的方式去处理参数值,来达到防止注入的问题。需要注意的是,每一个[{xxx}]表达式的意思是从request中获取相关的xxx属性的值,如果request范围内没有传递xxx,这个sql会报语法错误,一般也可以给'[{userId}]'加上单引号,这个属于常识性的问题,另[{userId}]的意义是指:与request.getParameter("userId")一致。参考截图如下:

查询SQL.jpg

2、能否对传递参数二次包装?

如果一个查询时模糊查询,那么就需要对参数二次封装了,两种解决办法,第一种通常采用给参数值前后追加“%”的方式,可以是提交查询后去添加,即每当用户的查询条件提交时,将需要做模糊查询的字段单独处理,这种也是传统的方式;另外一种方式,这里给[{xxx}]表达式也提供了一种方式,参考处理方式如下:

<my:queryOne var="sysMenu"

    sql="SELECT

        userid AS 'userId' , realname 'realName' FROM sysuser

    WHERE

        realname like [%{userName}%]

        and createDate >= [{createDate} 00:00:00]

        and createDate <= [{createDate} 23:59:59]

        ">

它的处理方式支持的语法结构为[before{xxx}after],详细分解为:xxx为request中传递的参数值,before的意思可以是任意单词字符,将此处的字符拼接到传递的参数前面,而after远离一样,是将字符拼接到传递的参数后面,如支持的like查询时的%xxx%,以及日期查询时的日期时间后缀。

当然如果还有其他特殊的逻辑包装处理,可自行在其他地方解决,也可扩展sql表达式,比如对xxx做decode处理等等。

3、sql的参数动态查询问题?

页面上罗列了一堆的查询条件,当我们输入用户姓名时,sql会出现按名称查询;当选择用户生日的日期段时出现日期的查询条件,否则就没有此段sql语句的where条件,这就是这里所说的动态sql语句,虽然我们可以用上述1中的方式解决,但是查询时的like %%跟没有这个查询条件在执行时还是存在差异的,我们的解决办法参考如下:

<my:queryOne var="sysMenu"

    sql="SELECT

        userid AS 'userId' , realname 'realName' FROM sysuser

    WHERE 1=1

        [%{ and realname like result(realname) }%]

        [{ and createDate >= result(createDate) } 00:00:00]

        ">

它的处理方式支持的语法同上面的查不到,只不过,在[{xxx}]中的xxx部分,不为属性了,而是一组查询条件,其中result(xxx)的格式为固定的,xxx同样为request中的属性值,当xxx在request中为null时,会直接忽略此段sql语句,如果不为空,则直接输出查询sql语句,当然处理的方式也是用“?”的方式来的。

4、sql的查询防止注入的问题?

其实除了上述的几种解决方案中,这个问题也属于常识性的问题,应该说所有的系统中都应该去解决的一种问题,大家也都可以将所熟知的方式给画出来。

5、sql的传递获取方式,包括分页时传递的参数是否再浏览器上看得到?

查询时我个人还是建议使用此部分提供的示例中的处理方式,采用表单提交的方式去实现,这样可以使用form的post提交方式,有效的将参数采用后台提交的方式提交给业务处理;另外传递的中文参数也不用专门的去做一些编码解码的事情。

6、提供有专门的sql配置方式,可供专门集中声明维护sql语句?

相关的几篇示例实现介绍中都存在一个sqlKey的参数,此参数是专门的从sql配置文件中读取的方式,将所有的sql进行配置读取,可以是多个不同目录下的多个xml形式的文件,写法参考如下:

sql-xml.jpg

sql文件配置.jpg

上述中的sql文件可以是在这个目录结构中的任何位置,另外,每个文件中的key需要保证唯一不重复,容器启动时会有这个重复性检查的提示,另外也提供一个系统级的参数,控制是否每次都去读取这个sql配置文件,让我们在开发时频繁的修改sql文件可以达到不用重启就会生效的效果,比较方便。

7、更多......还有别的什么问题吗?


 点赞


 发表评论

当前回复:作者

 评论列表


留言区