Hibernate 中的点对点更新

来源:互联网 发布:mac不能上网 编辑:程序博客网 时间:2024/06/05 22:03

数据库中的更新时十分常见的操作,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 属性的更新。


常见的用法是方法二。