将HashMap插入任何数据库表

Raz*_*ead 0 java jdbc

我有一个HashMap,其定义如下:

  myMap = new HashMap<String,String>();
Run Code Online (Sandbox Code Playgroud)

此映射包含字段名称作为键,字段值作为课程值.我正在尝试创建一个方法,将HashMap和表名作为参数.我的查询必须具有以下格式,因为我不插入表格中的所有列:

INSERT INTO $tableName (?,?,?,?)
VALUES (?,?,?,?)
Run Code Online (Sandbox Code Playgroud)

列数当然取决于HashMap的大小.如何通过迭代HashMap来实现这一目标.这是我到目前为止使用不同的方法,但我认为它不会正常工作:

public void insertData(HashMap<String, String> dataMap, String tableName) {

    int size=dataMap.size();
    String sql = "INSERT INTO " + tableName;
    Iterator<Entry<String, String>> it = dataMap.entrySet().iterator();
    int counter = 1;
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry)it.next();
        sql += pairs.getKey()+"="+pairs.getValue();
        if(size > counter )
            sql += ", ";
        counter++;
    }
    sql += ";";
}
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 8

您需要自己生成带有列名和占位符的预准备语句SQL字符串.这是一个启动示例:

StringBuilder sql = new StringBuilder("INSERT INTO ").append(tableName).append(" (");
StringBuilder placeholders = new StringBuilder();

for (Iterator<String> iter = dataMap.keySet().iterator(); iter.hasNext();) {
    sql.append(iter.next());
    placeholders.append("?");

    if (iter.hasNext()) {
        sql.append(",");
        placeholders.append(",");
    }
}

sql.append(") VALUES (").append(placeholders).append(")");
preparedStatement = connection.prepareStatement(sql.toString());
int i = 0;

for (String value : dataMap.values()) {
    preparedStatement.setObject(i++, value);
}

int affectedRows = prepatedStatement.executeUpdate();
// ...
Run Code Online (Sandbox Code Playgroud)

这样做,您可以使用额外的优势Map<String, Object>在那里Object也可以是Number(Integer,Long,等)Date,byte[]等,为此,至少那些类型PreparedStatement已经有setter方法.

请记住,如果tableName和映射键由最终用户控制,则会出现严重的SQL注入攻击漏洞.