【问题标题】:Multivalue Mysql Inserts using HibernateTemplate使用 HibernateTemplate 的多值 Mysql 插入
【发布时间】:2010-05-20 18:53:00
【问题描述】:

我正在使用 Spring HibernateTemplate,并且需要每秒向 mysql 数据库中插入数百条记录。

不确定什么是最高效的方法,但我想看看多值 mysql 插入是如何使用休眠的。

String query = "insert into user(age, name, birth_date) values(24, 'Joe', '2010-05-19 14:33:14'), (25, 'Joe1', '2010-05-19 14:33:14')"

getHibernateTemplate().execute(new HibernateCallback(){
 public Object doInHibernate(Session session) throws HibernateException, SQLException {
      return session.createSQLQuery(query).executeUpdate();
 }
});

但我收到此错误: '无法执行本机批量操作查询。'请检查您的查询.....

知道我可以通过 Hibernate 使用多值 mysql 插入吗?还是我的查询不正确?

还有其他方法可以提高性能吗?我确实尝试了 saveOrUpdateAll() 方法,但还不够好!

【问题讨论】:

  • 您找到解决方案了吗?
  • 我确信您的真实代码不会这样做,而是使用准备好的语句,否则您会将查询缓存从水中吹走......并且您将自己敞开心扉到处都是sql注入。 cf 小鲍比桌。 (xkcd.com/327)
  • +1 用于 Bobby Tables 参考
  • 以各种可能的方式生气。谢谢。
  • 如果您想删除一个问题,只需将其删除即可。不要简单地编辑内容;无论如何都会保留问题历史记录。

标签: hibernate spring java


【解决方案1】:

来自 Hibernate 文档的 section 14.1

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
    session.save(customer);

    if ( i % 20 == 0 ) { //20, same as the JDBC batch size

        //flush a batch of inserts and release memory:

        session.flush();

        session.clear();
    }
}
tx.commit();
session.close();

因此,您需要能够传入您尝试持久化的元组集合,将它们构造为持久化对象,然后保存并以某个所需的时间间隔刷新。

如果这还不够,我会建议 Hibernate 是一个糟糕的解决方案来解决你正在尝试做的事情。

【讨论】:

    【解决方案2】:

    我倾向于只将 Hibernate 用于单个对象操作。

    对于中等数量的数据,比如报表,我喜欢 Spring JdbcTemplate。

    对于非常大的批量插入,我将生成一个带有制表符分隔值的输入文件(在从数据中过滤制表符之后)并使用数据库为批量输入提供的任何 shell 程序,例如 MySql 的 mysqlimport。这两个步骤可以由不同的机器执行,以扩展大量导入的数据。

    【讨论】:

    • 运行 mysqlimport 是我们发现的将数据导入数据库的最快方法。准备输入文件的时间花在了另一台机器上,因此该解决方案更适合多个导入作业。
    【解决方案3】:

    我们使用 iBatis 在 mySQL 上获得高性能 DML。由于另一个抽象级别,它比 JDBC 更好。 iBatis 有一个批处理操作,其中也包括插入。

    只需为这种情况创建另一个 DAO 接口,并使用 iBatis(实现 FooDAO 的 FooSQLMap)实现它。您可以从您的服务中调用新的 FooDAO,这使其对您的服务调用者不可见。

    【讨论】:

      【解决方案4】:

      我同意马修·弗林的观点。如果您还是要直接使用 JDBC,那么使用 Hibernate 没有多大意义。如果您将对象映射为实体,则可以使用 session.save() 批量保存它们,不时刷新和清除会话,以免内存不足。

      【讨论】:

        【解决方案5】:

        HibernateTemplate 有一个 bulkUpdate 方法应该适用于此

        【讨论】:

        • 这是使用 HQL,Langali 正在通过 SQL 进行尝试。请阅读文档。
        猜你喜欢
        • 1970-01-01
        • 2011-01-21
        • 1970-01-01
        • 2019-03-24
        • 1970-01-01
        • 1970-01-01
        • 2014-02-25
        • 2012-01-04
        • 1970-01-01
        相关资源
        最近更新 更多