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();
这下终于可以了!