我正在使用以下代码从关系数据库生成搜索结果,具体取决于基于Web的客户端的多个(可选)搜索参数。
目前我正在使用“java.sql.Statement
”来实现功能,但我需要使用“java.sql.PreparedStatement
”来实现相同的功能,以防止SQL注入。
让我知道更改代码的最佳做法
E.g。
来自基于网络的客户的用户输入。
SQL模式的伪代码取决于搜索参数,如下所示
IF (WITHOUT ANY SEARCH PARAMETER){
SELECT * FROM TEST_TABLE;
}
ELSE IF(WITH param1){
SELECT * FROM TEST_TABLE WHERE COLUMN1= param1;
}
ELSE IF(WITH param1 & param2){
SELECT * FROM TEST_TABLE WHERE COLUMN1= param1 AND COLUMN2= param2
}
SO ON
………
以下是我的EJB中的Java代码片段
/*
NOTE : Hashtable pSearchParam is a method parameter
*/
Connection cnBOP = null;
Statement stmt = null;
StringBuffer sb = new StringBuffer("");
try {
cnBOP = jdbcBOP.getConnection(); // DataSource jdbcBOP
stmt = cnBOP.createStatement();
/* ######################## SQL BODY ######################################*/
sb.append("SELECT COLUMN1, COLUMN2, DATE_COLUMN ");
sb.append("FROM TEST_TABLE ");
/* ######################## SQL WHERE CLAUSE ##############################*/
if(pSearchParam.size()>=1){
sb.append("WHERE ");
Enumeration e = pSearchParam.keys();
int count =0;
while(e.hasMoreElements()){
if (count >=1) sb.append("AND ");
String sKey = (String) e.nextElement();
if (sKey.equals("param1")) sb.append ("COLUMN1 ='"+pSearchParam.get(sKey)+"' ");
else if (sKey.equals("param1")) sb.append ("COLUMN2 ='"+pSearchParam.get(sKey)+"' ");
else if (sKey.equals("dateParamFr")) sb.append ("DATE_COLUMN >= TO_DATE('"+pSearchParam.get(sKey)+" 00:00:00','DD/MM/YYYY HH24:MI:SS') ");
else if (sKey.equals("dateParamTo")) sb.append ("DATE_COLUMN <= TO_DATE('"+pSearchParam.get(sKey)+" 23:59:59','DD/MM/YYYY HH24:MI:SS') ");
count ++;
}
}
/* ######################## SQL ORDER BY CLAUSE ############################*/
sb.append("ORDER BY DATE_COLUMN DESC");
ResultSet rs = stmt.executeQuery(sb.toString());
答案 0 :(得分:4)
而不是
sb.append ("COLUMN1 ='"+pSearchParam.get("param1")+"' ");
你必须这样做
sb.append ("COLUMN1 = ? ");
然后在创建语句后
stmt.setString(1, pSearchParam.get("param1"));
这仅适用于第一个参数,您需要对所有语句执行此操作并枚举
中的索引setString(int index, String param);
请注意,您需要使用int,long,Date ......等其他方法
答案 1 :(得分:1)
依赖于您的数据库引擎,您可以使用
之类的SQL函数isnull(value,valueIfNull)
例如在MSSQL中
select * from Order where storeId = isnull(?,storeId)
下一个java代码
preparedStatement.setNull(1,java.sql.Types.INTEGER)
如果您需要从过滤器或
中省略此参数preparedStatement.setInt(1,20)
如果您需要找到storeId = 20的所有订单
答案 2 :(得分:0)
这看起来像是Hibernate Criteria Queries ...
的工作Criteria是一个简化的API,用于通过撰写来检索实体 标准对象。 这是非常的 方便的功能方法 像“搜索”屏幕那里有一个 可变数量的条件 放在结果集上。
答案 3 :(得分:0)
你在使用Hibernate吗?然后你可以使用criteria API。对于非休眠,您可以查看SqlBuilder工具以根据条件生成SQL。
你还应该使用标记“?”而不是实际值。
所以这个查询应该是这样的。
SELECT * FROM TEST_TABLE WHERE COLUMN1= ?;
然后,您可以使用PreparedStatements为此列设置值。关于使用PreparedStatement的入门教程是here。