我通过程序产生一批数据,这批数据是通过程序产生的,而不是从数据库中来的。
大概每一批会有十万左右。工程使用的是ssh , 但是数据库表是通过sql动态产生的,不能使用hibernate的pojo...
我现在要将这批数据插入到数据库中。通过循环去批量插入,每次插入2千条
我通过
insert into tablename (a) select 's125' union all select 'a112' union all .....
把SQL进行组装,然后通过hibernate 执行原生sql , 但是执行的效率太低。这样2000条都要大几秒中能否有更加高效的办法?  如果非要使用存储过程,那这个参数 字符串 a ,如何批量传参? 

解决方案 »

  1.   

    当然不能用循环insert,hibernate提供了批量更新的方法,楼主可以百度其用法
      

  2.   

    hibernate的批量更新方法? 你是说saveOrUpdate() ? 那是hibernate操作对象呀,我现在是没有对象只能用原生SQL
    public Integer execute(final String sql) {
         return (Integer)getHibernateTemplate().execute(new HibernateCallback() {
    @SuppressWarnings("unchecked")
    public Object doInHibernate(Session session) throws HibernateException, SQLException {
    return session.createSQLQuery(sql).executeUpdate();
    }
            });
        }
    这是我最终将数据插入的方法想问下怎样在此基础上进行优化。。或者在SQL上进行优化, 1 楼你说用JDBC,那我还得去写一个链接的Connection? 这样是否太麻烦。
      

  3.   

    Transaction tx = session.beginTransaction(); 
    Work work = new Work(){ 
    public void execute(Connection connection ) throws SQLException{ 
     PreparedStatement stmt = ...
    }
    //执行
    Worksession.doWork(work);
     tx.commit();
      

  4.   

    刚刚想到了应该可以在execute方法中以jdbc的形式去批量执行sql吧脑子转不过弯呐。。
      

  5.   

    我现在是在Dao层去处理sql 
    能通过hibernate连接方式去产生Connection么?也就是写JDBC的时候要用到Connection ,PreparedStatement  这些
    那在Dao层的方法里面如何取获取这个呢?
      

  6.   

    Connection con = session.getSessionFactory().getCurrentSession().connection();使用这个好像connection()方法是过时了。
      

  7.   

    借这个再问一个问题呀。。sql 怎样快速的从 已有的几百万条数据中 随机 取2000条记录
      

  8.   

    前些天正好有个批量插入
    SessionFactory sf = hibernateTemplate.getSessionFactory();
    org.hibernate.Session hibernateSession = SessionFactoryUtils.getSession(sf, true);
    //这里的true 和false是是否从当前的事物中获取session  如果为true就是不从当前事物中获取自己开辟一个、false就是必须从当前事物获取
    事物使用注解@Transactional(propagation = Propagation.REQUIRED)
    Connection conn = session.connection();
    使用过后记得关闭事物要设置手动提交 conn.setautocommit(false);
    for(int i=0,n=50000; i < n ; i++){}循环也要优化、关于insert into的语句:我知道的有倆种方式
    1、类似多个这样的多个insert into:
    insert into 表(字段) values(值1);
    insert into 表(字段) values(值2);
    insert into 表(字段) values(值3);2、一句insert into
    insert into 表(字段) values(值1),values(值2),values(值3);
    然后执行一条语句、
    2语句会比1快很多、毕竟是一句话、还有commit,这个要分段提交  速度会很快、
    设置 多少条一提交事物、-----------------------------------------------------
    如果是mysql数据库的话
    还有url设置、
    要加rewriteBatchedStatements参数,并保证5.1.13以上版本的连接驱动,才能实现高性能的批量插入
    url:  jdbc:mysql://127.0.0.1:3306:3306/test?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true参考
    http://www.iteye.com/topic/770032
    -------------------------------------------------------关于你这程序生产出来的数据库的话  可以使用load file  这样会很快、
    生产出来的数据导出到一个文件里、然后在导入这个文件到数据库、会很快、具体使用就百度吧、我暂时能提供给你的资料方向就这么多了、剩下的你自己去探索吧、
      

  9.   


    随机不知道、
    不过取前几千和后几千条到是可以、
    oracle 使用rownum伪行数、
    mysql 使用limit 

    而且查询的时候最好只留下你需要的那几列的数据、其他不需要显示的数据就别查了、也耗性能、
      

  10.   


    昨天无意中发现了随机取多少条的数据、select * from TABLE order by rand() ;不过这样会对数据库造成性能损耗、
    因为数据库不得不去执行rand()函数。
    取随机的数据可以把全表查出、这块是php代码:大概的意思是使用了游标行随机$r = mysql_query("SELECT count(*) FROM user");
    $d = mysql_fetch_row($r);
    $rand = mt_rand(0,$d[0] - 1);$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");具体参见:http://www.iteye.com/topic/1114134    第六条、