2011-02-01 59 views
0

我使用以下代码根据来自基于Web的客户端的多个(可选)搜索参数从关系数据库中生成搜索结果。Java/JDBC - 多参数搜索最佳实践

目前我使用“java.sql.Statement”来实现功能,但为了防止SQL注入,我需要使用“java.sql.PreparedStatement”来实现相同的功能。

让我知道最好的做法来改变代码


例如

基于Web的客户端的用户输入。

  • 参数1 - 可选
  • 参数2 - 可选
  • dateParamFr - 可选
  • dateParamTo - 可选
取决于搜索参数如下

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 
……… 
SQL模式

伪代码

以下是在我的EJB

/* 
     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

这真的看起来像Hibernate Criteria Queries工作的Java代码片段...

标准是由合成 标准对象检索实体简化的API。 这是一个非常方便的 功能 类似于“搜索”屏幕,其中有 可变数量的条件为 置于结果集上。

+1

他使用普通的JDBC,我猜 – 2011-02-01 04:42:45

0

你在使用Hibernate吗?然后你可以使用criteria API。否则,对于非休眠状态,您可以查看SqlBuilder工具以根据条件生成SQL。

此外,你应该使用标记“?”而不是实际值。

所以这个查询应该是这样的。您可以使用PreparedStatements来为此列设置值。关于使用PreparedStatement的入门教程是here

+0

accordind标记和代码,他使用普通的jdbc – 2011-02-01 04:38:07

1

取决于你的数据库引擎,你可以在MSSQL使用SQL的功能,如

isnull(value,valueIfNull) 

例如

select * from Order where storeId = isnull(?,storeId) 

下一个在你的java代码

preparedStatement.setNull(1,java.sql.Types.INTEGER) 

,如果你需要省略此来自过滤器的参数,或

preparedStatement.setInt(1,20) 

,如果你需要找到所有订单STOREID = 20

4

而不是

sb.append ("COLUMN1 ='"+pSearchParam.get("param1")+"' "); 

你将不得不做

sb.append ("COLUMN1 = ? "); 

,然后在创建你

声明
stmt.setString(1, pSearchParam.get("param1")); 

这只是第一个参数,则需要在

setString(int index, String param); 

请注意,您将需要使用其他方法的int,long,日期为所有语句做到这一点,并列举了指数...等

+0

很好的答案,但请记住,JDBC索引是基于1 - 不是基于0。 – 2011-02-01 04:57:34