Java 使用spring jdbcTemplate将数据插入多个表

Java 使用spring jdbcTemplate将数据插入多个表,java,mysql,spring,spring-jdbc,Java,Mysql,Spring,Spring Jdbc,我正在使用java、SpringJDBC模板将n个记录插入到两个表中。有些像这样 假设daos.xml配置正确 ApplicationContext ctxt = new ClassPathXmlApplicationContext("daos.xml"); JdbcTemplate template = (JdbcTemplate) ctxt.getBean("jdbcTemplate"); final List<Person> list = new ArrayList<&

我正在使用java、SpringJDBC模板将n个记录插入到两个表中。有些像这样

假设daos.xml配置正确

ApplicationContext ctxt = new ClassPathXmlApplicationContext("daos.xml");
JdbcTemplate template = (JdbcTemplate) ctxt.getBean("jdbcTemplate");

final List<Person> list = new ArrayList<>();
        final List<Role> roles = new ArrayList<>();
        for(int i =1; i<=100; i++){
            Person item = new Person();
            item.setFirstName("Naveen" + i);
            item.setLastName("kumar" + i);
            item.setDescription("D" + i);
            list.add(item);

            Role role = new Role();
            role.setName("Admin");
            role.setCode("c"  + i);
            roles.add(role);

        }

String sql = "insert into person(first_name, last_name, description) values(?,?,?)";

            int[] arr = template.batchUpdate(sql, new BatchPreparedStatementSetter() {

                        @Override
                        public void setValues(PreparedStatement ps, int i) throws SQLException                             {
                            Person person = list.get(i);
                            ps.setObject(1, person.getFirstName());
                            ps.setObject(2, person.getLastName());
                            ps.setObject(3, person.getDescription());
                        }

                        @Override
                        public int getBatchSize() {
                            return list.size()
                        }
                    });

我想分批执行。因为在我的例子中,我有至少10000人的列表要用文件解析。所以它可能是一个性能杀手,我将角色插入表中,然后得到它,然后他们再次插入person

您可以使用多通道语句和
LAST\u INSERT\u ID()
MySql函数:

String sql = "insert into role(name, code) values(?,?);" +
    "insert into person(first_name, last_name, description, role_id) values(?,?,?,(SELECT LAST_INSERT_ID()));";

int[] arr = template.batchUpdate(sql, new BatchPreparedStatementSetter() {

    @Override
    public void setValues(PreparedStatement ps, int i) throws SQLException {
        Role role = roles.get(i);
        Person person = list.get(i);
        ps.setObject(1, role.getName());
        ps.setObject(2, role.getCode();
        ps.setObject(3, person.getFirstName());
        ps.setObject(4, person.getLastName());
        ps.setObject(5, person.getDescription());
    }

    @Override
    public int getBatchSize() {
        return list.size()
    }
});

如果您有10K记录,请考虑使用Spring Spring批量。我将只对少数记录使用JdbcTemplate的批处理方法,例如发票的详细信息,其中发票的详细信息为1到20。比如说角色和人员表。我必须分析一个文件,其中可能包括一个镜头10k记录。所以在将文件中的数据解析为Role和Person对象之后,我想插入第一个Role对象,然后获取插入的Role对象id,然后插入具有Role的Person对象。所以我的问题是,我想维护事务以及批处理,这样就不会有到db的往返。现在你能告诉我实现以下任务的正确方法吗。什么是弹簧批,如何使用。给我任何一个例子的链接。嗨,SpringBatch涵盖了你的需求,有事务支持,还有一些重要的东西,“chunks”你可以有10个1K的chunks,有事务支持。仅供参考,非常感谢。亲爱的Nailgun,第一个问题-当多个线程同时运行以插入此类数据时,这是否是正确的方法。这意味着获取最后一个id。第二个问题-我将如何插入角色。如果我使用jdbcTemplate.update()。然后又是成千上万的人朝着db打去。这就是为什么我一直在寻找一些解决方案,将这两个插入到单个批处理执行中。1)LAST_INSERT_ID()返回从当前连接插入的最后一个ID,这样就可以了2)然后您只需稍微更改代码即可使用
public int[][]batchUpdate(字符串sql、最终集合batchArgs、最终int batchSize、最终参数化PreparedStatementSetter pss)
JdbcTemplate
中的
方法。我建议将
batchSize
参数设置为1000。谢谢,我希望它能起作用。我也做了与我们所说的一样的事情。在Postgres中,
的多行插入不起作用;
PSQLException:返回的更新结果太多。请参阅:您可以使用CTE
String sql = "insert into role(name, code) values(?,?);" +
    "insert into person(first_name, last_name, description, role_id) values(?,?,?,(SELECT LAST_INSERT_ID()));";

int[] arr = template.batchUpdate(sql, new BatchPreparedStatementSetter() {

    @Override
    public void setValues(PreparedStatement ps, int i) throws SQLException {
        Role role = roles.get(i);
        Person person = list.get(i);
        ps.setObject(1, role.getName());
        ps.setObject(2, role.getCode();
        ps.setObject(3, person.getFirstName());
        ps.setObject(4, person.getLastName());
        ps.setObject(5, person.getDescription());
    }

    @Override
    public int getBatchSize() {
        return list.size()
    }
});