merger的基本用法:
用来合并UPDATE和INSERT语句。通过MERGE语句,根据一张表(原数据表,source table)或子查询的连接条件对另外一张(目标表,target table)表进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT+UPDATE
在Hibernate中可以通过merge(特定对象)的方法去修改一组数据,如果这个对象中的成员变量包含主键,那么如果在数据库中这个主键值存在的时候,则可以直接修改该条数据,但是当你的这个对象的成员变量不包含主键时,那么恭喜你,你用merge去修改某条数据的时候就成了添加一条数据了,
我就是犯了这个非常低级的错误,我的主键是id,但是在通过Hibernate反转的时候生成的pojo类的构造函数中默认是不会将自增长的id字段放到构造函数中的,所以当你通过merge(特定对象)去修改一组数据时变成了添加这条数据了
解决方案:
要修改的时候,先将id拿到,然后保存在需要修改的对象的id属性中;
public boolean updateGoods(Goodsinfo goods) {
boolean flag = false;
Session session = null;
try {
session = HibernateSessionFactory.getSession();
Transaction ts = session.beginTransaction();
// 保存订单
System.out.println(goods);
//因为id是主键,在使用merge修改的时候需要先获得该id,否则的话,就不是修改,而是添加
String sql = "select id from goodsinfo where goodsid = ?";
Object idObject = session.createSQLQuery(sql)
.setParameter(0,goods.getGoodsId())
.uniqueResult();
int id = Integer.parseInt(idObject.toString());
goods.setId(id);
session.merge(goods);
ts.commit();
flag = true;
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
HibernateSessionFactory.closeSession();
}
return flag;
}
这样的低级错误以后不能再犯了,在此记录一下。