首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2EE开发 >

Spring jdbc 批量更新数据,该怎么处理

2013-12-04 
Spring jdbc 批量更新数据使用spring封装的jdbc批量进行数据库更新操作,代码如下:Person类package com.ked

Spring jdbc 批量更新数据
使用spring封装的jdbc批量进行数据库更新操作,代码如下:

Person类

package com.kedacom.spring;

public class Person {

public int id;
public String name;
public int age;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

操作数据库代码


public void insertPersons(final List<Person> list)
throws CannotGetJdbcConnectionException, SQLException {
super.getJdbcTemplate().batchUpdate(INSERT_INTO_PERSON,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement,
int i) throws SQLException {
preparedStatement.setObject(1, list.get(i).getName());
preparedStatement.setObject(2, list.get(i).getAge());
}

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

测试代码

public void test() {

List<Person> persons = new ArrayList<Person>();
// 生成1000个Person对象
for (int i = 0; i < 1000; i++) {
Person person = new Person();
person.setName("NO" + String.valueOf(i));
person.setAge(i);
persons.add(person);
}
long start = System.currentTimeMillis();
this.insertPersons(persons);
long end = System.currentTimeMillis();
System.out.println("所用时长" + (end - start) + "毫秒");
}


运行结果为:所用时长8784毫秒。



感觉有些郁闷spring批量插入1000条数据,居然要8秒钟的时间··
但是如果将操作数据库代码做如下修改,则执行完成时间能缩短为:0.2秒左右


public void insertPersons(final List<Person> list)
throws CannotGetJdbcConnectionException, SQLException {
                //设置不自动提交
                getConnection().setAutoCommit(false);
super.getJdbcTemplate().batchUpdate(INSERT_INTO_PERSON,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement,
int i) throws SQLException {
preparedStatement.setObject(1, list.get(i).getName());
preparedStatement.setObject(2, list.get(i).getAge());
}

@Override
public int getBatchSize() {
return list.Size();
}
});
                //手动提交
                getConnection().commit();
getConnection().setAutoCommit(true);
}



由此猜想可能spring事务自动提交导致批量插入效率低了,但是看了spring源码,又没有找到原因所在,希望大家能够指点一下,是代码中缺陷,和造成性能差的原因。

spring 批量更新的源码
public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL batch update [" + sql + "]");
}

return execute(sql, new PreparedStatementCallback<int[]>() {
public int[] doInPreparedStatement(PreparedStatement ps) throws SQLException {
try {
int batchSize = pss.getBatchSize();
InterruptibleBatchPreparedStatementSetter ipss =
(pss instanceof InterruptibleBatchPreparedStatementSetter ?
(InterruptibleBatchPreparedStatementSetter) pss : null);
if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
ps.addBatch();
}
return ps.executeBatch();
}
else {
List<Integer> rowsAffected = new ArrayList<Integer>();
for (int i = 0; i < batchSize; i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
break;
}
rowsAffected.add(ps.executeUpdate());
}
int[] rowsAffectedArray = new int[rowsAffected.size()];
for (int i = 0; i < rowsAffectedArray.length; i++) {
rowsAffectedArray[i] = rowsAffected.get(i);


}
return rowsAffectedArray;
}
}
finally {
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
}
}
}
});
}





spring jdbc java
[解决办法]

   public static String valueOf(int i) {
        return Integer.toString(i);
    }

 public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        char[] buf = new char[size];
        getChars(i, size, buf);
        return new String(buf, true);
    }


[解决办法]
第一种是没插入一条数据都要打开数据库连接,插入,提交,关闭
第二种是只操作一次,你说谁快
[解决办法]
要看下你的getConnection()方法,如果是SPRING容器对insertPersons方法进行事务管理,默认是自动提交被禁用的,即setAutoCommit(false)。可能是你的事务管理有问题。

热点排行