特性列表:
问题:
<a name="xsqlbuilder-%E9%97%AE%E9%A2%98%3A" data-cke-saved-name="xsqlbuilder-%E9%97%AE%E9%A2%98%3A"><span style="color:#000000"> </span></a>
- String sql = "select * from user where 1=1 ";
- String user_id = (String)filters.get("user_id");
- if( user_id != null && user_id.length() > 0) {
- sql = sql + " and user_id = " + user_id;
- }
- String age = (String)filters.get("age");
- if(age != null && age.length() > 0) {
- sql = sql + " and age > " + age;
- }
String sql = "select * from user where 1=1 ";
String user_id = (String)filters.get("user_id");
if( user_id != null && user_id.length() > 0) {
sql = sql + " and user_id = " + user_id;
}
String age = (String)filters.get("age");
if(age != null && age.length() > 0) {
sql = sql + " and age > " + age;
}
过多的if判断导致sql语句不清晰,我们再来看下rapid-xsqlbuilder的做法
rapid-xsqlbuilder构造SQL例子
- // 清晰的sql语句,/~ ~/为一个语法块
- String sql= "select * from user where 1=1 "
- + "/~ and username = {username} ~/"
- + "/~ and password = {password} ~/";
- // filters为参数
- Map filters = new HashMap();
- filters.put("username", "badqiu");
- filters.put("sex", "F");
- XsqlFilterResult result = new XsqlBuilder().generateHql(sql,filters);
- assertTrue(result.getAcceptedFilters().containsKey("username"));
- assertFalse(result.getAcceptedFilters().containsKey("sex"));
- assertEquals("select * from user where 1=1 and username = :username ", result.getXsql());
// 清晰的sql语句,/~ ~/为一个语法块
String sql= "select * from user where 1=1 "
+ "/~ and username = {username} ~/"
+ "/~ and password = {password} ~/";
// filters为参数
Map filters = new HashMap();
filters.put("username", "badqiu");
filters.put("sex", "F");
XsqlFilterResult result = new XsqlBuilder().generateHql(sql,filters);
assertTrue(result.getAcceptedFilters().containsKey("username"));
assertFalse(result.getAcceptedFilters().containsKey("sex"));
assertEquals("select * from user where 1=1 and username = :username ", result.getXsql());
XsqlFilterResult为处理完返回的东西,包含两个属性xsql,acceptedFilters
被过滤掉的东西:
SQL过滤: /~ and password = {password} ~/
这一段由于在filters中password不存在而没有被构造出来
filters过滤: sex
filters中由于没有类似/~ sex={sex} ~/ 这一段,所以在过滤完的filters中不存在
最终构造生成的结果
<a name="xsqlbuilder-%E6%9C%80%E7%BB%88%E6%9E%84%E9%80%A0%E7%94%9F%E6%88%90%E7%9A%84%E7%BB%93%E6%9E%9C" data-cke-saved-name="xsqlbuilder-%E6%9C%80%E7%BB%88%E6%9E%84%E9%80%A0%E7%94%9F%E6%88%90%E7%9A%84%E7%BB%93%E6%9E%9C">select * from user where 1=1 and username=:username</a>
构造后返回的Map filters: XsqlFilterResult.acceptedFilters 属性
username=badqiu
语法
数据据类型修饰
/~ {username} ~/
/~ {age?int} ~/
/~ {birthDate?timestamp(yyyy年MM月dd日)} ~/
中括号[]与大括号{}的区别
SQL注入攻击的防范
问题:
拼接的SQL如果不对单引号(有些数据库有反斜杠)进行过滤,则会存在SQL注入攻击问题
解决:
使用SafeSqlProcesser,进行sql过滤
- XsqlBuilder builder = new XsqlBuilder(SafeSqlProcesserFactory.getMysql());
XsqlBuilder builder = new XsqlBuilder(SafeSqlProcesserFactory.getMysql());
SafeSqlProcesser其中的一个源码分析
- /**
- * 过滤单个单引号为双引号的SafeSqlFilter<p>
- * 适用数据库(MS SqlServer,Oracle,DB2)
- */
- public String process(String value) {
- if(value == null) return null;
- return value.replaceAll("'", "''"); // Mysql还需过滤反斜框
- }
/**
* 过滤单个单引号为双引号的SafeSqlFilter<p>
* 适用数据库(MS SqlServer,Oracle,DB2)
*/
public String process(String value) {
if(value == null) return null;
return value.replaceAll("'", "''"); // Mysql还需过滤反斜框
}
Project Home: http://code.google.com/p/rapid-xsqlbuilder/
最后不忘为rapid-framework宣传一下,本工具也集成在里面
rapid-framework简介:
一个类似 ruby on rails 的java web快速开发脚手架,本着不重复发明轮子的原则,框架只是将零散的struts(struts2)+spring+hibernate各个组件组装好在一起,并对struts及struts2进行改造,提供零配置编程,并内置一个强大的代码生成器及模板文件, 可以生成java的hibernat model,dao,manager,struts+struts2 action类,可以生成jsp的增删改查及列表页面