当前位置: 首页 > 知识库问答 >
问题:

Java/JDBC-使用JDBC PreparedStatement进行多参数搜索

步兴德
2023-03-14

使用JDBC准备语句创建多参数搜索,以防止SQL注入攻击,提高性能。因为我在网上找不到最好的方法。

我试着自己实现如下。

    null
    PreparedStatement stat = conn.prepareStatement(sql.toString());
    public class EmpDAO {

        public static List<Employee> findByCriteria(Employee e)
                throws SQLException, IOException {

            try (Connection conn = getConnection()) {

                StringBuilder sql = new StringBuilder("SELECT * FROM Employee ");

                //collect user supplied parameters
                Map<String, String> params = new HashMap<String, String>();
                if (e.getFname() != null && e.getFname().length() != 0) {
                    params.put(EmpDAO.FNAME, e.getFname());
                }
                if (e.getLname() != null && e.getLname().length() != 0) {
                    params.put(EmpDAO.LNAME, e.getLname());
                }

                if (e.getDepid() > 0) {
                    params.put(EmpDAO.DEPT_ID, new Integer(e.getDepid()).toString());
                }

                //construct prepared statement based on the parameters

                Set<String> colSet = params.keySet();
                if (colSet != null && !colSet.isEmpty()) {
                    StringBuilder whereClause = new StringBuilder(" WHERE");
                    String andOp = "";
                    for (String colName : colSet) {                 
                        whereClause.append(andOp);
                        whereClause.append(" ");
                        whereClause.append(colName);
                        whereClause.append("=? ");
                        andOp = " AND ";
                    }

                    sql.append(whereClause);
                }

                PreparedStatement stat = conn.prepareStatement(sql.toString());
                int paramPos = 1;
                for (String colName : colSet) {
                    if (colName.equals(EmpDAO.FNAME)) {
                        stat.setString(paramPos, params.get(colName));
                    }

                    if (colName.equals(EmpDAO.LNAME)) {
                        stat.setString(paramPos, params.get(colName));
                    }

                    if (colName.equals(EmpDAO.DEPT_ID)) {
                        stat.setInt(paramPos, Integer.parseInt(params.get(colName)));
                    }
                    paramPos++;
                }

                List<Employee> emp1 = new ArrayList<>();
                try (ResultSet result = stat.executeQuery()) {

                    while (result.next()) {
                        Employee emp = new Employee();
                        emp.setDepid(result.getInt("DEPT_ID"));
                        emp.setEmpid(result.getInt("EMP_ID"));
                        emp.setFname(result.getString("FNAME"));
                        emp.setJobid(result.getInt("JOB_ID"));
                        emp.setLname(result.getString("LNAME"));
                        emp.setMangid(result.getInt("MANAGER_EMP_ID"));
                        emp.setSalary(result.getInt("SALARY"));
                        emp1.add(emp);
                    }
                }
                return emp1;
            }
        }

        public static Connection getConnection() throws SQLException, IOException {
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException ex) {
                ex.printStackTrace();
            }
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/test",
                    "root", "root");
        }

        public static final String FNAME = "FNAME";
        public static final String LNAME = "FNAME";
        public static final String DEPT_ID = "FNAME";
    }

共有1个答案

阎佑运
2023-03-14

是的--正如所写的那样,这将防止SQL注入攻击,是的,这就是使用.PrepareStatement的方式。如果您希望对它的实现方式进行批评,那么您可能应该将此代码发布到https://codereview.stackExchange.com/上。

 类似资料:
  • 问题内容: 我正在使用Hibernate 4和Lucene 3.6。我对构面计数有要求。根据我的要求,我有一个实体“产品”。实体“产品”具有某些属性,例如ID,颜色,品牌。 现在,我的要求是,我想以多维方式获取该实体的商品数,并获取红色(彩色)耐克(品牌)服装的数量。 所以举个例子。我的数据库中保存了以下产品实体。 id品牌颜色 1锐步红 2锐步黑 3锐步绿 4利红 5利黑 6利黑 现在,我希望我

  • 我有一个数据帧,我想按两个参数分组(1)相同的第一列中的连续编号和(2)第二列中的匹配值 数据帧: 组1包括前2行,因为30和31是连续的,第二列匹配。创建组2是因为Col1中的31和35不是连续的。创建组3是因为H和E不匹配。 在pandas groupby中对列表中的行进行分组 我很感谢你给我的建议

  • 问题内容: 我被要求对数组进行排序和搜索。对数组进行排序很简单,我的代码也起作用了,但是每当我尝试调用二进制搜索方法时,它就可以对数组中的第一个元素起作用,但是结果是“ -1” 我的完整代码如下: 问题答案: 您搞砸了二进制搜索间隔

  • 我刚刚学习了如何使用存储库Java进行分页(我有一个BBDD MySQL)。我基本上在我的模型(pregunta)中使用DAO,并将我的模型转换为我的DTO(preguntaDTO)。 我的控制器接收分页参数。 但是现在,我需要在我的JQUERY(文本和id)中使用参数。我会试着更好地解释它。我的模型是: 我的搜索,除了分页,必须返回我所有的问题(pregunta),有: 在字段deEnferme

  • 但我得到以下错误: 我错在哪里?

  • 用git grep 命令查找Git库里面的某段文字是很方便的. 当然, 你也可以用unix下的'grep'命令进行搜索, 但是'git grep'命令能让你不用签出(checkout)历史文件, 就能查找它们. 例如, 你要看 git.git 这个仓库里每个使用'xmmap'函数的地方, 你可以运行下面的命令: $ git grep xmmap config.c: co