【问题标题】:How to create a prepared statement dynamically - and re-use the query如何动态创建准备好的语句 - 并重用查询
【发布时间】:2013-08-30 06:13:57
【问题描述】:

例如,我一直在尝试创建一个类来处理来自创建不同对象的不同类的查询。

Class Employees, Class Customers, Class Sales

我想通过从 JTextField 值派生的构造函数传递一个 SQL 查询(到查询类“数据库”)。

例如,来自两个不同的类:

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

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

我面临的问题是动态创建以下项目(PreparedStatement 参数):

stmt.setString(2, NEWYORK);

所以“sql”在“?”可以填充:

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

在我的项目中,可能有一个语句像上面一样将值传递给参数,或者可能有更多的参数,意味着更多的语句,因此上述不能重复使用。

任何人都可以对如何生成“stmt.setString(2, NEWYORK);”有想法吗?动态地,以便我可以根据传递的参数数量动态地生成它。这样我就可以拥有:

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

注意:重点是重用数据库类。

【问题讨论】:

    标签: java mysql database jdbc prepared-statement


    【解决方案1】:

    假设您已经能够动态创建 SQL 字符串(根据需要在正确的位置插入 ?),我建议使用 Map 传入参数,其中 key 将是参数顺序( 1,2,3 等等)。像这样的:

    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;
        }
    
    }
    

    最后你可以使用Database如下:

    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();
    

    【讨论】:

    • 这是否会导致问题,因为它使用PreparedStatement.setObject 时对象类型可以是字符串、整数或其他任何类型,在这种情况下setIntegersetString 会更好?
    • @KyleAnderson 请注意这个主题已经在PreparedStatement JavaDoc
    猜你喜欢
    • 1970-01-01
    • 2021-01-06
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多