hibernate一对一关系中知道维护端主键去更新被维护端部分字段数据

下面举的例子不是我项目中的真实例子,但是从我的项目简化出来的一个模型。

User(id, name, cardId)用户

Card(id, money)用户的卡信息

public class User {
      private String id;
      private String name;
      private Card card;
      //还有其他很多属性
      //省略了get和set方法
}
public class Card {
      private int id;
      private float money;
      private User user;
      //还有其他很多属性
      //省略get和set方法
}

User和Card的设置是一对一双向关系的,然后User是维护端,由于考虑到面向对象,所以没有把用户的Card的信息保存到User中,而是分成两个实体类进行编写。现在有一个需求:知道员工的id,要更新其Card里面的money,如果一般情况下,是可以按下面写代码的

User user = userService.find(userId);  //根据userid找到具体的User信息
Card card = user.getCard();
card.setMoney(money);  //设置新的数据
cardService.update(card);  //保存到数据库中

好了,一般很多人会按上面的代码进行编写,但上面的效率太低了,只修改了一个数据,就要把整个User和Card的全部信息都拿了出来,于是就可能用HQL来进行操作,如下:

Query query = session.createQuery("update Card c set c.money=? where c.user.id=?");
query.setParameter(0, 100f).setParameter(1, 1);
query.executeUpdate();

 上面的代码,被Hibernate解释成了如下的代码

 update
        card,  
    set
        money=? 
    where
        id=?

 card后面居然多了一个“,”,并且where后面的字句也不正确,我怀疑这应该是一个bug吧,但没办法,问题总是要解决的,但又不想用上面说的第一种方式,效率不高,难道要具体的数据库编写sql代码,这样兼容性不好,还是用hql语句实现好了,于是写出了下面一段代码:

Query query = session.createQuery("update Card c set c.name=? where c.id = (select u.card.id from User u where u.id=?)");
query.setParameter(0, 100f).setParameter(1, 1);
query.executeUpdate();

这下终于可以了!酷

猜你喜欢

转载自jasperzxy.iteye.com/blog/1937971