【问题标题】:Hibernate execute update with criteriaHibernate 使用标准执行更新
【发布时间】:2014-11-07 04:56:33
【问题描述】:

Hibernate 中使用Criteria 时是否可以执行更新?例如:

Session session = getSession();
Criteria crit = session.createCriteria(User.class);
crit.add(Restrictions.eq("token", sessionToken));

User user= new User();
Transaction tx = session.getTransaction();
try 
{
    tx.begin();
    session.updateWithCriteria(user, crit); //my imaginary function 
    tx.commit();
}
catch (Exception e) 
{
    e.printStackTrace();
    tx.rollback();
}

session.close();

【问题讨论】:

    标签: java sql hibernate orm


    【解决方案1】:

    有一个非常强大的功能叫做:

    15.4. DML-style operations

    来自文档的小引用:

    ...但是,Hibernate 提供了通过 Hibernate 查询语言执行的批量 SQL 样式 DML 语句执行的方法...

    所以,虽然这不是关于 criteria - 我们仍然可以使用我们的域模型进行查询,因为它是关于 HQL。这是一个显示力量的sn-p:

    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
    // or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
    int updatedEntities = s.createQuery( hqlUpdate )
            .setString( "newName", newName )
            .setString( "oldName", oldName )
            .executeUpdate();
    tx.commit();
    session.close();
    

    总结:准备好:

    • 我们可以使用查询来过滤结果
    • 我们可以对其应用批量更新
    • 我们不需要将这些行在内存中加载到会话中...

    【讨论】:

    • 总结:不可能使用 Criteria 运行 DML
    • 什么是变量s?
    【解决方案2】:

    首先你应该得到对象然后修改和更新:

       Query q = session.createQuery("from StockTransaction where tranId = :tranId ");
       q.setParameter("tranId", 11);
       StockTransaction stockTran = (StockTransaction)q.list().get(0);
    
       stockTran.setVolume(4000000L);
       session.update(stockTran);
    

    如果你想使用部分/动态更新功能然后放

    @org.hibernate.annotations.Entity(
            dynamicUpdate = true
    )
    

    dao 类之上的注解。

    示例来自:http://www.mkyong.com/hibernate/hibernate-dynamic-update-attribute-example/

    注意:问题是“有条件”,但接受的答案不是“有条件”而是 SQL。

    【讨论】:

      【解决方案3】:

      现在我们可以做这样的事情来批量更新和删除。为 criteriaUpdate 和 CriteriaDelete 发布了新的 api

      CriteriaBuilder cb = this.em.getCriteriaBuilder();
      // create update
      CriteriaUpdate<Order> update = cb.createCriteriaUpdate(Order.class);
      // set the root class
      Root e = update.from(Order.class);
      // set update and where clause
      update.set("amount", newAmount);
      update.where(cb.greaterThanOrEqualTo(e.get("amount"), oldAmount));
      // perform update
      this.em.createQuery(update).executeUpdate();
      

      【讨论】:

      • 您能否更清楚地解释一下此查询如何转换为普通 SQL 查询以供参考
      • 在调用executeUpdate()之前是否需要启动事务?还是不是?
      猜你喜欢
      • 2021-05-04
      • 2013-08-14
      • 2011-09-15
      • 2014-02-20
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      相关资源
      最近更新 更多