最近做的一个项目中用到了Hibernate的,然后数据库批量插入数据的时候就使用到了hibernate的批处理,但是效率比较低,看网上说还有一些限制,要禁止二级缓存,还要多一个batch_size的配置什么的,不知道是用的不对还是怎么滴,插入一万条数据最快的时候也需要三十多秒时间,慢的五十多秒,比较纠结,然后改用了jdbc的批处理,这里有三张表,Device,Alarm和SyslogAlarm,不过device表可以忽略,用处不大,就是和Alarm有个一对多的关系,Alarm和SyslogAlarm的主键都是手动控制的,不自增,Alarm和SyslogAlarm是一对一的关系,现在控制Alarm和SyslogAlarm的主键值相同,即有关联关系的Alarm和SyslogAlarm的主键值相同,知道其中一个的主键就可以查出另外一张表,SyslogAlarm中有Alarm的外键,因此在这里也不能够让主键自增。

首先需要一个工具类,该工具类的作用是获取同一个Connection链接

//获取同一个connection,参照了hibernate的getCurrentSession的实现
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;

public class ConnectionUtil{

public static final ThreadLocal<Connection> connections = new ThreadLocal<Connection>();
public static Connection getConnection(DataSource dataSource) throws SQLException{
  Connection c = connections.get();
  if(null==c){
    c=dataSource.getConnection();
    connections.set(c);   }
  return c;
  }
}

spring的配置文件就不搞了下面是dao层的具体实现,servce层省略

@Repository
@Scope("prototype")
public class SyslogAlarmDao2 extends JdbcDaoSupport implements InitializingBean{
  @resource
  public void setDatasource(DataSource dataSource){
    this.setDataSource(dataSource);
  }
  private long count = 0L;
  String sql1 = "";
  String sql2 = "";
  PreparedStatement ps1 = null;
  PreparedStatement ps2 = null;
  Connection c = null;
   /**  这里有篇文章可以帮助理解下面这个注解 http://blog.csdn.net/yaerfeng/article/details/8447530  */  @PostConstruct //
  public void set() throws SQLException{
    sql1 = "sql";//省略,带问号的sql字符串,注意字符串内容不能有;,比如"insert into alarm values(?,?,?,?,?,?);"就是错误的,我因为这个问题纠结了不少时间,"insert into alarm values(?,?,?,?,?,?)"
    sql2 ="sql";  //同上
    c = ConnectionUtil.getConnection(this.getDataSource());
    ps1 = c.prepareStatement(sql1);
    ps2 = c.prepareStatement(sql2);      /**       由于主键是手动控制的,所以需要查一下数据库中已经存在的id的最大值,然后从最大值+1处开始添加数据       alarm和syslogalarm的主键值相同,所以查一个就可以      */
    PreparedStatement ps3 = c.prepareStatement("select max(id) from alarm2");
    ResultSet rs = ps3.executeQuery();
    while(rs.next()){
        count = rs.getLong();
    }
  }
public void executeBatch(SyslogAlarm sAlarm) throws SQLException{
//这个可以提取到service层  if(sAlarm==null||sAlarm.getAlarm ==null){
    System.out.println("input error");
    return;
  }   count++;
  ps1.setLong(,count);
   //从sAlarm中取值填充到ps1的sql字符串中     //..............

  ps2.setLong(,count);
  //从sAlarm中取值填充到ps2的sql字符串中      //..........

  ps1.addBatch();
  ps2.addBatch();
  System.out.println("调用了 "+count+" 次");
  ==){   //为10的时候插入一万条需要4.061秒,为100插入一万数据需要1.403秒,为1000的时候插入一万条数据需要大概需要0.747秒时间
    ps1.executeBatch();
    ps2.executeBatch();
    ps1.clearBatch();
    ps2.clearBatch();
  }
  //ps1.executeBatch();   //执行剩余sql,但是在这里写的话效率较低,因为每次都会调用,实际情况是只需要最后调用一次即可,所以可以单独写一个方法,在测试中的数据满足批处理的全部执行完成之后再调用这个方法  //比如,现在批处理是1000条一次,如果处理9999条数据,则剩余999条不满1000,则不会插入到数据库中,这个时候可以在执行完前9000条数据之后再执行这两句,对此写了个方法,executeRemainderSQL
  //ps2.executeBatch();  //同上
}public void executeReminderSQL() throws SQLException{   ps1.executeBatch();    ps1.clearBatch();    ps2.executeBatch();    ps2.clearBatch(); }
}

测试

//Service shenglue

@Test
public void testBatchInsert(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring xml path");
double start = System.currentTimeMillis();
SyslogAlarmService sas = (SyslogAlarmService) ac.getBean("syslogAlarmService");

;i<;i++){//当为1000批处理时,插入一万数据需要一秒左右,十万数据7秒左右,20万数据13秒左右,50万数据31秒左右
Device d = new Device();
d.setId();

Alarm alarm = new Alarm();
alarm.setDevice(d);
//alarm.set

SyslogAlarm sAlarm = new SyslogAlarm();
sAlarm.setAlarm(alarm);
//sAlarm.set

sas.batchInsert(sAlarm);
}sas.executeReminderSQL();//执行剩余的sql
double end = System.currentTimeMillis();
System.+ " 秒");
}
}

使用JDBC批量保存数据(JdbcDaoSupport,JdbcTemplete)的更多相关文章

  1. JDBC批量插入数据优化,使用addBatch和executeBatch

    JDBC批量插入数据优化,使用addBatch和executeBatch SQL的批量插入的问题,如果来个for循环,执行上万次,肯定会很慢,那么,如何去优化呢? 解决方案:用 preparedSta ...

  2. Jquery Easy UI Datagrid 上下移动批量保存数据

    DataGrid with 上下移动批量保存数据 通过前端变量保存修改数据集合,一次性提交后台执行 本想结合easyui 自带的$('#dg').datagrid('getChanges'); 方法来 ...

  3. springboot jpa 批量保存数据--EntityManager和 JpaRepository

    1: 项目里面使用springboo-boot-start-data-jpa操作数据库,通过源码,在repository上继承JpaRepository 可以实现保存操作,其中源码接口为: <S ...

  4. 使用EntityManager批量保存数据

    @PersistenceContext EntityManager em; 从别的系统中定期同步某张表的数据,由于数据量较大,采用批量保存 JPA EntityManager的四个主要方法 ① pub ...

  5. MySQL:JDBC批量插入数据的效率

    平时使用mysql插入.查询数据都没有注意过效率,今天在for循环中使用JDBC插入1000条数据居然等待了一会儿 就来探索一下JDBC的批量插入语句对效率的提高 首先进行建表 create tabl ...

  6. 【实践】jdbc批量插入数据

    参考文献:http://my.oschina.net/u/1452675/blog/203670 http://superjavason.iteye.com/blog/255423 /*测试批量写入数 ...

  7. JDBC批量插入数据效率分析

    对于需要批量插入数据库操作JDBC有多重方式,本利从三个角度对Statement和PreparedStatement两种执行方式进行分析,总结较优的方案. 当前实现由如下条件: 执行数据库:Mysql ...

  8. jdbc批量插入数据

    //插入很多书(批量插入用法) public void insertBooks(List<Book> book) {   final List<Book> tempBook=b ...

  9. Hibernate 批量保存数据

    public Boolean save(Collection<Object> os) { int batchSize = 50,i=0; Session session=this.sess ...

随机推荐

  1. 去除字符串中的html标记及标记中的内容

    去除字符串中的html标记及标记中的内容 --1.创建函数 create function [dbo].[clearhtml] (@maco varchar(8000)) returns varcha ...

  2. jvm运行机制与内存管理

    http://blog.csdn.net/lengyuhong/article/details/5953544 http://www.cnblogs.com/nexiyi/p/java_memory_ ...

  3. WebAPI身份验证

    对WebAPI接口的开放当然要做控制,需要身份验证如何做到呢. 进行身份验证后的 服务器拒绝了访问! 第一步添加一个CustomHandler.cs的类 1: using System; 2: usi ...

  4. CSS3属性

    1.边框阴影(box-shadow ): 投影方式,X轴偏移,Y轴偏移,阴影模糊半径,阴影扩展半径,颜色 2.边框图像(border-image) 3.边框圆角:border-radius:5px 4 ...

  5. PHP Java 设置cookie方法

      Java Cookie cookie = new Cookie(COOKIE_NAME, encrypt_cookieV); cookie.setMaxAge(60 * 60); cookie.s ...

  6. Python基础6- 流程控制之if条件语句

    Python条件语句是通过判断一条或多条条件语句的执行结果来决定执行哪条代码块的.Python 中if 语句用于控制程序的执行,基本形式为:if 判断条件: 执行语句……else: 执行语句…… #c ...

  7. jquery事件重复绑定解决办法

    一$.fn.live 重复绑定 解决:使用die()方法,在live()方法绑定前,将此元素上的前面被绑定的事件统统解除,然后再通过live()方法绑定新的事件. //先通过die()方法解除,再通过 ...

  8. jQuery入门第一天

    使用jQuery之前,我们需要加一些代码到HTML文件中. 首先在页面顶端增加一行script元素,然后写上结束符. 浏览器会运行script 里所有的Javascript,包括jQuery. 在你的 ...

  9. iOS学习02C语言分支结构

    1. BOOL类型 返回值:真:YES  假:NO BOOL数据类型占一个字节的内存空间,占位符为%d. 计算机在识别时,YES就替换成1,NO就替换成0. bool是C语言中的布尔类型,返回值为tr ...

  10. So you want to be a 2n-aire?[HDU1145]

    So you want to be a 2n-aire?Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...