How to create a prepared statement dynamically - a

2019-06-12 04:50发布

问题:

I've been trying to create a class that handles queries from different Classes that create different objects, for example.

Class Employees, Class Customers, Class Sales

I'd like to pass a SQL query via the constructor derived from JTextField values (to the query class, "Database").

For example, from two different classes:

new Database (SELECT PRODUCT FROM SALES WHERE DATE = YESTERDAY);

new Database (SELECT FULLNAMES FROM CUSTOMER WHERE ADDRESS = NEWYORK);

The problem I'm facing is when it comes to creating the following items dynamically (PreparedStatement Parameters):

stmt.setString(2, NEWYORK);

so that "sql" at "?" can be populated:

String sql = "SELECT FULLNAMES FROM CUSTOMER WHERE ADDRESS = ?";

In my project there could be one statement that passes values to the parameter just as above, or there could be more parameters, meaning more statements, hence the above can't be reused.

Could anyone have ideas on how to generate "stmt.setString(2, NEWYORK);" dynamically so that I could generate it dynamically and as per the number of parameters being passed. So that I could for example have:

stmt.setString(1, NEWYORK);
stmt.setString(2, FULLNAMES);
stmt.setString(3, EMPLOYEE);

NOTE: The whole point is to reuse the database class.

回答1:

Assuming you already are able to create SQL string dynamically (inserting the ? in the right position as needed), I would suggest use a Map to pass in parameters where the key would be the parameter order (1,2,3 and so on). Something like this:

public class Database{
    private String _sqlString;
    private Map<Integer,Object> _parameters;

    public Database(String sql){
        _sqlstring = sql;
    }

    public void setParameters(Map<Integer,Object> param){
        _parameters = param;
    }

    /* 
     * I'm assuming you already have a method like this
     */
    public List processQuery(){
        List results = new ArrayList();
        /* 
         * establish connection here
         */
        PreparedStatement preparedStatement = connection.prepareStatement(this._sqlString);

        if(_parameters != null){
            /* 
             * Iterate over the map to set parameters 
             */
            for(Integer key : _parameters.keySet()){
                preparedStatement.setObject(key, _parameters.get(key));
            }
        }            

        ResultSet rs = preparedStatement.executeQuery();
        /*
         * process the ResultSet
         */
        return results;
    }

}

Finally you can use Database as follows:

String sql = "SELECT FULLNAMES FROM CUSTOMER WHERE ADDRESS = ? OR ADDRESS = ?";

Map<Integer,Object> param = new HashMap<>();
param.put(1,"NEW YORK");
param.put(2,"CHICAGO");

Database db = new Database(sql);
db.setParameters(param);
List customers = db.processQuery();