web-dev-qa-db-fra.com

Comment effectuer une mise à jour par lots au printemps avec une liste de cartes?

Nouveau sur Spring, j'essaie d'insérer un List<Map<String, Object>> dans une table. Jusqu'à présent, j'utilisais la variable SqlParameterSource pour la mise à jour par lots, ce qui fonctionne bien lorsqu'un bean Java leur est fourni. Quelque chose comme ça:

    @Autowired
    private NamedParameterJDBCTemplate v2_template;

    public int[] bulkInsertIntoSiteTable(List<SiteBean> list){
            SqlParameterSource[] batch = SqlParameterSourceUtils
                    .createBatch(list.toArray());
            int[] updateCounts = v2_template
                    .batchUpdate(
                            "insert into sitestatus (website, status, createdby) values (:website, :status, :username)",
                            batch);

            return updateCounts;

        }

Cependant, j'ai essayé la même technique avec une liste de cartes à la place d'un haricot, cela a échoué (à juste titre).

public int[] bulkInsertIntoSiteTable(List<Map<String, Object>> list){
        SqlParameterSource[] batch = SqlParameterSourceUtils
                .createBatch(list.toArray());
        int[] updateCounts = v2_template
                .batchUpdate(
                        "insert into sitestatus (website, status, createdby) values (:website, :status, :username)",
                        batch);

        return updateCounts;

    }

Le code ci-dessus a échoué avec l'exception suivante:

Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'website': Invalid property 'website' of bean class [org.springframework.util.LinkedCaseInsensitiveMap]: Bean property 'website' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
    at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.Java:322)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils$1.setValues(NamedParameterBatchUpdateUtils.Java:45)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.Java:893)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.Java:1)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:587)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.Java:615)
    at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.Java:884)
    at org.springframework.jdbc.core.namedparam.NamedParameterBatchUpdateUtils.executeBatchUpdateWithNamedParameters(NamedParameterBatchUpdateUtils.Java:40)
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.Java:303)
    at tester.utitlies.dao.VersionTwoDao.bulkInsertIntoSites(VersionTwoDao.Java:21)
    at tester.utitlies.runner.Main.main(Main.Java:28)

Il échoue car il considère que la liste est un lot de haricots, je suppose. Je ne trouve pas le moyen d'effectuer une mise à jour par lots au printemps avec une liste de cartes et avec NamedParameterJDBCTemplate. S'il vous plaît des conseils.

13
Mono Jamoon

Selon Spring NamedParameterJDBCTemplate docs, trouvé ici , cette méthode peut être utilisée pour la mise à jour par lots avec des cartes. 

int[] batchUpdate(String sql, Map<String,?>[] batchValues) 

Le véritable défi consistait à obtenir un tableau de Map<String, Object> à partir d'un List<Map<String, Object>> correspondant. J'ai utilisé le code suivant pour obtenir le tableau et effectuer la mise à jour par lots.

public static Map<String, Object>[] getArrayData(List<Map<String, Object>> list){
        @SuppressWarnings("unchecked")
        Map<String, Object>[] maps = new HashMap[list.size()];

        Iterator<Map<String, Object>> iterator = list.iterator();
        int i = 0;
        while (iterator.hasNext()) {
            Map<Java.lang.String, Java.lang.Object> map = (Map<Java.lang.String, Java.lang.Object>) iterator
                    .next();
            maps[i++] = map;
        }

        return maps;
    }
7
Mono Jamoon

J'ai testé avec du code.

Map<String, Object>[] rs = new Map<String, Object>[1];

Map<String, Object> item1 = new HashMap<>();
item1.put("name", "Tien Nguyen");
item1.put("age", 35);
rs[0] = item1;

NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(datasource); 
// datasource from JDBC.
jdbc.batchUpdate("call sp(:name, :age)", rs);

J'espère que c'est facile à savoir. Merci

0
Tien Nguyen