数据库中的更新时十分常见的操作,Hibernate 默认生成的更新代码是全局更新,即无论用户更改了多少内容,都会更新整个持久化对象,这严重影响着程序的效率,特别是数据库中存有论文、图像等大型数据时,此时我们需要实现点对点更新,即更改多少就更新多少。
实现点对点更新的操作有多种:
方法一
在不参与更新的域上面加 @Column(updatable=false) 注解:
1: @Column(updatable=false) 2: private String locale; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }加上 @Column(updatable=false) 之后这个域将不会再参与 update 操作,即无法通过 update 来更新这个数据域,故此方法不灵活,所以用的不多。方法二
使用 HQL(EJBQL) 语句实现点对点更新:
1: Session session = sessionFactory.getCurrentSession(); 2: session.beginTransaction(); 3: Query query = session.createQuery("update Apple a set a.color='Red' where id=13 and size=13"); 4: query.executeUpdate(); 5: session.getTransaction().commit(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }需要注意的是,这里的 Query 是 org.hibernate.Query ,HQL 语句里面的 Apple 是类名,所以是区分大小写的。
这种有程序员指定语句的方法十分灵活,故使用的较多。
方法三
还有一种仅适用于 XML 中的方法。在 Apple.hbm.xml 文件中 标签中指明 dynamic-update 属性值为 true:
1: <class name="cn.cdp.hibernate.Apple" dynamic-update="true"> 2: <id name="id"> 3: <generator class="uuid"> generator> 4: id> 5: <property name="color" /> 6: <property name="locale" /> 7: class> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }此时当我们运用一般方法更新数据时候,就可以进行点对点更新了:
1: Session session = sessionFactory.getCurrentSession(); 2: session.beginTransaction(); 3: Apple apple = (Apple)session.get(Apple.class, "40280e812e1ed1f5012e1ed1f8a00013"); 4: apple.setLocale("US"); 5: session.update(apple); 6: session.getTransaction().commit(); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }这个更新不会涉及到 color 属性的更新。
常见的用法是方法二。
