﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-笑着生活-随笔分类-Hibernate</title><link>http://www.blogjava.net/yzzh9/category/35039.html</link><description>惟仁者为能以大事小,惟智者为能以小事大：
Java之路——专注，研究，思考，总结
</description><language>zh-cn</language><lastBuildDate>Mon, 13 Oct 2008 15:15:33 GMT</lastBuildDate><pubDate>Mon, 13 Oct 2008 15:15:33 GMT</pubDate><ttl>60</ttl><item><title>林信良：Hibernate之 多对多</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/13/234116.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Mon, 13 Oct 2008 14:21:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/13/234116.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/234116.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/13/234116.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/234116.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/234116.html</trackback:ping><description><![CDATA[在资料库表格上要进行多对多对应，可以藉由一个中介表格来完成，也就是藉由多对一、一对多来完成多对多关联。<br /><img title="多对多" style="WIDTH: 498px; HEIGHT: 131px" alt="多对多" src="http://caterpillar.onlyfun.net/GossipCN/HibernateGossip/images/ManyToMany-1.jpg" /><br /><br />多对多由于使用了中介表格，在查询效率不彰，且在程式的物件模式上，多对多会使得物件与物件之间彼此依赖，并不是一个很好的设计方式，在设计上应避免使用多对多关系。<br /><br />如果一定要使用多对多关系的话，在表格上先如下建立：<br /><div style="MARGIN-LEFT: 40px; FONT-FAMILY: Courier New,Courier,monospace"><small><font size="3"><span style="FONT-WEIGHT: bold">    create table server (<br />        id integer not null auto_increment,<br />        address varchar(255),<br />        primary key (id)<br />    )<br /><br />    create table user (<br />        id integer not null auto_increment,<br />        name varchar(255),<br />        primary key (id)<br />    )<br /><br />    create table user_server (<br />        user_id integer not null,<br />        server_id integer not null,<br />        primary key (user_id, server_id)<br />    )</span><span style="FONT-WEIGHT: bold"></span><br /></font></small></div><small><br /><font size="3">先设计User类别如下：</font></small><br /><ul><li>User.java </li></ul><pre>package onlyfun.caterpillar;<br /><br />import java.util.Set;<br /><br />public class User {<br />    private Integer id;<br />    private String name;<br /><span style="FONT-WEIGHT: bold">private Set servers;</span><br /><br />    public User() {}<br /><br />    public Integer getId() {<br />        return id;<br />    }<br /><br />    public void setId(Integer id) {<br />        this.id = id;<br />    }<br /><br />    public String getName() {<br />        return name;<br />    }<br /><br />    public void setName(String name) {<br />        this.name = name;<br />    }<br /><br />    public Set getServers() {<br />        return servers;<br />    }<br /><br />    public void setServers(Set servers) {<br />        this.servers = servers;<br />    }<br />}</pre><br /><font size="3"><small>再来设计Server类别如下：</small><br /></font><ul><li>Server.java </li></ul><pre>package onlyfun.caterpillar;<br /><br />import java.util.Set;<br /><br />public class Server {<br />    private Integer id;<br />    private String address;<br /><span style="FONT-WEIGHT: bold">private Set users;</span><br /><br />    public String getAddress() {<br />        return address;<br />    }<br /><br />    public void setAddress(String address) {<br />        this.address = address;<br />    }<br /><br />    public Integer getId() {<br />        return id;<br />    }<br /><br />    public void setId(Integer id) {<br />        this.id = id;<br />    }<br /><br />    public Set getUsers() {<br />        return users;<br />    }<br /><br />    public void setUsers(Set users) {<br />        this.users = users;<br />    }<br />}</pre><br /><font size="3"><small>在映射文件上，使用&lt;many-to-many&gt;标签来完成映射关系：</small><br /></font><ul><li>User.hbm.xml </li></ul><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt; <br />&lt;!DOCTYPE hibernate-mapping <br /> PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <br /> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt; <br /><br />&lt;hibernate-mapping&gt; <br /><br />    &lt;class name="onlyfun.caterpillar.User" table="user"&gt; <br />        &lt;id name="id" column="id"&gt; <br />            &lt;generator class="native"/&gt; <br />        &lt;/id&gt; <br /><br />        &lt;property name="name" column="name"/&gt; <br /><br /><span style="FONT-WEIGHT: bold">        &lt;set name="servers" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             table="user_server" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             cascade="save-update"&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold"></span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">            &lt;key column="user_id"/&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">            &lt;many-to-many class="onlyfun.caterpillar.Server"</span><span style="FONT-WEIGHT: bold"></span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                          column="server_id"/&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">        &lt;/set&gt; </span><br />    &lt;/class&gt; <br /><br />&lt;/hibernate-mapping&gt;</pre><br /><font size="3"><small>注意到cascade是设定为save-update，因为在多对多的关系中，很少因为删除其中之一，而所关联的实体都要一并删除的，所以设定save- update，表示在save或update时，一并对关联的物件进行对应的save或update。<br /><br />Server.hbm.xml的定义如下：</small><br /></font><ul><li>Server.hbm.xml </li></ul><pre>&lt;?xml version="1.0" encoding="utf-8"?&gt; <br />&lt;!DOCTYPE hibernate-mapping <br /> PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <br /> "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt; <br /><br />&lt;hibernate-mapping&gt; <br /><br />    &lt;class name="onlyfun.caterpillar.Server" table="server"&gt; <br /><br />        &lt;id name="id" column="id"&gt; <br />            &lt;generator class="native"/&gt; <br />        &lt;/id&gt; <br /><br />        &lt;property name="address"/&gt; <br /><br /><span style="FONT-WEIGHT: bold">        &lt;set name="users" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             table="user_server" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             inverse="true" </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             cascade="save-update"&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold"></span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             &lt;key column="server_id"/&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">             &lt;many-to-many class="onlyfun.caterpillar.User" </span><span style="FONT-WEIGHT: bold"></span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">                           column="user_id"/&gt; </span><br style="FONT-WEIGHT: bold" /><span style="FONT-WEIGHT: bold">        &lt;/set&gt; </span><br />    &lt;/class&gt; <br /><br />&lt;/hibernate-mapping&gt; </pre><br /><small><font size="3">一个储存时的例子如下：<br /></font></small><div style="MARGIN-LEFT: 40px"><small><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Server server1 = new Server();</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server1.setAddress("PC-219"); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server1.setUsers(new HashSet());</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Server server2 = new Server(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server2.setAddress("PC-220"); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server2.setUsers(new HashSet());</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Server server3 = new Server(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server3.setAddress("PC-221");</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server3.setUsers(new HashSet());</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user1 = new User(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setName("caterpillar");</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setServers(new HashSet());</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user2 = new User(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user2.setName("momor");</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user2.setServers(new HashSet());</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">// 多对多，互相参考</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.getServers().add(server1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.getServers().add(server2); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.getServers().add(server3); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server1.getUsers().add(user1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server2.getUsers().add(user1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server3.getUsers().add(user1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user2.getServers().add(server1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user2.getServers().add(server3); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server1.getUsers().add(user2); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">server3.getUsers().add(user2); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = HibernateUtil.getSessionFactory().openSession(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx= session.beginTransaction(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.save(user1); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.save(user2); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">        </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span><br /></font></small></div><img src ="http://www.blogjava.net/yzzh9/aggbug/234116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-13 22:21 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/13/234116.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>林信良：Hibernate之DetchedCriteria</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/09/233449.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Thu, 09 Oct 2008 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/09/233449.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233449.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/09/233449.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233449.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233449.html</trackback:ping><description><![CDATA[Criteria与Session绑定，其生命周期跟随着Session结束而结束，使用Criteria时进行查询时，每次都要于执行时期动态建立物件，并加入各种查询条件，随着Session的回收，Criteria也跟着回收。<br /><br />为了能够重复使用Criteria物件，在Hibernate 3中新增了org.hibernate.criterion.DetchedCriteria，您可以先建立DetchedCriteria实例，并加入各种查询条件，并于需要查询时再与Session绑定，获得一个绑定Session的Criteria物件，例如：<br /><div style="MARGIN-LEFT: 40px"><font size="3"><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">// 先建立DetchedCriteria物件</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">DetachedCriteria detchedCriteria =</small><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"> DetachedCriteria.forClass(User.class);</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">// 加入查询条件</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">detchedCriteria.add(Restrictions.ge("age",new Integer(25)));</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">       </small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">// 绑定Session并返回一个Criteria实例</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = </small><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">detchedCriteria.getExecutableCriteria(session);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">       </small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><img src ="http://www.blogjava.net/yzzh9/aggbug/233449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-09 21:50 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/09/233449.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>林信良：Hibernate之Criteria 进阶查询</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/09/233447.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Thu, 09 Oct 2008 13:47:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/09/233447.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233447.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/09/233447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233447.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233447.html</trackback:ping><description><![CDATA[使用Criteria进行查询时，不仅仅能组合出SQL中where子句的功能，还可以组合出如排序、统计、分组等的查询功能。<br /><ul><li><font size="3"><small>排序</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>您可以使用Criteria进行查询，并使用org.hibernate.criterion.Order对结果进行排序，例如使用Oder.asc()，指定根据”age”由小到大排序（反之则使用desc()）：</small><br /></font></div><small></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.addOrder(Order.asc("age"));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>注意在加入Order条件时，使用的是addOrder()方法，而不是add()方法，在产生SQL语句时，会使用order by与asc（desc）来进行排序指定：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ <span style="FONT-WEIGHT: bold">order by this_.age asc</span></small><br style="FONT-WEIGHT: bold" /></font></div><small><br /></small><ul><li><font size="3"><small>限定查询笔数</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>Criteria的setMaxResults()方法可以限定查询回来的笔数，如果配合setFirstResult()设定传回查询结果第一笔资料的位置，就可以实现简单的分页，例如传回第51笔之后的50笔资料（如果有的话）：</small><br /></font></div><small></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.setFirstResult(51);</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.setMaxResults(50);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>根据您所指定得资料库，Hibernate将自动产生与资料库相依的限定笔数查询子句，例如在MySQL中，将使用limit产生以下的SQL语句：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><small style="FONT-FAMILY: Courier New,Courier,monospace"><font size="3">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ <span style="FONT-WEIGHT: bold">limit</span> ?, ?<br /><br /></font></small></div><ul><li><font size="3"><small>统计动作</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>您可以对查询结果进行统计动作，使用 org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min ()、 countDistinct()等方法，再搭配Criteria的setProjection()方法加入条件设定，例如对查询结果的"age"作平均：</small><br /></font></div><small></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.setProjection(Projections.avg("age"));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>上面的程式将由Hibernate自动产生SQL的avg函数进行平均计算：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select <span style="FONT-WEIGHT: bold">avg(this_.age)</span> as y0_ from T_USER this_</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>分组</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>还可以配合Projections的groupProperty()来对结果进行分组，例如以"age"进行分组，也就是如果资料中"age"如果有 20、20、25、30，则以下会显示20、25、30：</small><br /></font></div><small></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.setProjection(Projections.groupProperty("age"));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>上面的程式将由Hibernate自动产生SQL的group by子句进行分组计算：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.age as y0_ from T_USER this_ <span style="FONT-WEIGHT: bold">group by</span> this_.age</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>如果想同时结合统计与分组功能，则可以使用org.hibernate.criterion.ProjectionList，例如下面的程式会计算每个年龄各有多少个人：</small><br /></font></div><small></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">ProjectionList projectionList = Projections.projectionList();</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">projectionList.add(Projections.groupProperty("age"));</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">projectionList.add(Projections.rowCount());</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.setProjection(projectionList);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>观察所产生的SQL语句，将使用group by先进行分组，再针对每个分组进行count函数的计数，</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.age as y0_, <span style="FONT-WEIGHT: bold">count(*)</span> as y1_ from T_USER this_ <span style="FONT-WEIGHT: bold">group by</span> this_.age</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>根据已知物件进行查询</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>设定查询条件并非一定要使用Restrictions，如果属性条件很多，使用Restrictions也不方便，如果有一个已知的物件，则可以根据这个物件作为查询的依据，看看是否有属性与之类似的物件，例如：</small><br /></font></div><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">User user = new User();</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">user.setAge(new Integer(30));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">criteria.add(<span style="FONT-WEIGHT: bold">Example.create(user)</span>);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><small><font size="3">您可以透过 org.hibernate.criterion.Example的create()方法来建立Example实例，Example实作了 Criteria介面，因此可以使用add()方法加入至Criteria条件设定之中，Hibernate将自动过滤掉空属性，根据已知物件上已设定的属性，判定是否产生于where子句之中：<br /><br /></font></small></div><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ <span style="FONT-WEIGHT: bold">where (this_.age=?)</span></small><br /></font></div><small><br /></small><ul><li><font size="3"><small>设定SQL范本</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>如果您了解如何撰写SQL语句，想要设定一些Hibernate产生SQL时的范本，您也可以使用Restrictions的sqlRestriction()方法，提供SQL语法范本作限定查询，例如查询name以cater开头的资料：</small><br /></font></div><div style="MARGIN-LEFT: 40px"><div style="MARGIN-LEFT: 40px; FONT-FAMILY: Courier New,Courier,monospace"><font size="3"><small>Criteria criteria = session.createCriteria(User.class)<span style="FONT-WEIGHT: bold">;</span></small><br style="FONT-WEIGHT: bold" /><small style="FONT-WEIGHT: bold">criteria.add(Restrictions.sqlRestriction(</small><br style="FONT-WEIGHT: bold" /><small style="FONT-WEIGHT: bold">              "{alias}.name LIKE (?)", "cater%", Hibernate.STRING));</small><br /><small>List users = criteria.list();</small><br /></font></div><br /></div><div style="MARGIN-LEFT: 40px"><font size="3"><small>其中alias将被替换为与User类别相关的名称，而? 将被替换为cater%，也就是第二个参数所提供的值，sqlRestriction()方法第一个参数所设定的是where子句的部份，所以在SQL撰写时，不必再写where，观察所产生的SQL语句，将使用您所设定的SQL范本作为基础，来完成SQL的条件查询：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where <span style="FONT-WEIGHT: bold">this_.name LIKE (?)</span></small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>如果有多个查询条件，例如between子句的查询，则可以如下：</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /></font></div><small style="FONT-FAMILY: Courier New,Courier,monospace"></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">Integer[] ages = {new Integer(20), new Integer(40)};</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.add(Restrictions.sqlRestriction(</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">               "{alias}.age BETWEEN (?) AND (?)", ages, types));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>观察所产生的SQL语句如下：</small><br /></font></div><small><br /></small><div style="MARGIN-LEFT: 80px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where <span style="FONT-WEIGHT: bold">this_.age BETWEEN (?) AND (?)</span></small><br /></font></div><img src ="http://www.blogjava.net/yzzh9/aggbug/233447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-09 21:47 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/09/233447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>林信良：Hibernate之Criteria 基本查询</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/08/233236.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Wed, 08 Oct 2008 14:27:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/08/233236.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233236.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/08/233236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233236.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233236.html</trackback:ping><description><![CDATA[要对资料库管理系统进行操作，最基本的就是使用SQL（Standard Query Language）语句，大部份的资料库都支援标准的SQL语句，然而也有一些特定于资料库的SQL语句，应用程式配合SQL语句进行资料库查询时，若使用到特定于资料库的SQL语句，程式本身会有相依于特定资料库的问题。<br /><br />使用Hibernate时，即使您不了解SQL的使用与撰写，也可以使用它所提供的API来进行SQL语句查询， org.hibernate.Criteria对SQL进行封装，您可以从Java物件的观点来组合各种查询条件，由Hibernate自动为您产生 SQL语句，而不用特别管理SQL与资料库相依的问题，就某个程度的意涵来看，这就像是在编译时期也可以得到对SQL语法的检查与验证。<br /><br />以最基本的查询来说，如果您想要查询某个物件所对应的资料表中所有的内容，您可以如下进行查询：<br /><div style="MARGIN-LEFT: 40px"><font size="3"><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">        </small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">for(Iterator it = users.iterator(); it.hasNext(); ) {</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">    User user = (User) it.next();</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">    System.out.println(user.getId() +</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">                             " \t " + user.getName() +</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">                          "/" + user.getAge());    </small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">} </small><br /></font></div><small><br /><font size="3">Criteria建立后，若不给予任何的条件，预设是查询物件所对应表格之所有资料，如果您执行以上的程式片段，并于设定档中设定了了Hibernate的”show_sql”属性，则可以在主控下看到以下的SQL语句之产生：<br /><br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: </span><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">select</span><span style="FONT-FAMILY: Courier New,Courier,monospace"> this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ </span><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">from</span><span style="FONT-FAMILY: Courier New,Courier,monospace"> T_USER this_</span></small><br /></font></div><small><br /></small><small><font size="3">org.hibernate.Criteria实际上是个条件附加的容器，如果想要设定查询条件，则要使用 org.hibernate.criterion.Restrictions的各种静态方法传回 org.hibernate.criterion.Criteria实例，传回的每个org.hibernate.criterion.Criteria 实例代表着一个条件，您要使用org.hibernate.Criteria的add()方法加入这些条件实例，例如查询” age”大于20且小于40的资料：<br style="FONT-WEIGHT: bold" /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</span></small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold"><span style="FONT-FAMILY: Courier New,Courier,monospace">criteria.add(Restrictions.gt("age", new Integer(20)));</span></small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold"><span style="FONT-FAMILY: Courier New,Courier,monospace">criteria.add(Restrictions.lt("age", new Integer(40)));</span></small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold"><span style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">        </span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">for(Iterator it = users.iterator(); it.hasNext(); ) {</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">    User user = (User) it.next();</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">    System.out.println(user.getId() +</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">                              " \t " + user.getName() +</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">                             "/" + user.getAge());    </span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-FAMILY: Courier New,Courier,monospace">}</span></small><br style="FONT-FAMILY: Courier New,Courier,monospace" /></font></div><small><br /><font size="3">Restrictions的gt()方法表示大于（great than）的条件，而lt表示小于（less than）的条件，执行以上程式片段，观察所产生的SQL语句，将使用where与and子句产来完成SQL的条件查询：<br /><br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ </span><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">where this_.age&gt;? and this_.age&lt;?</span></small><br /></font></div><small><br /><font size="3">使用add()方法加入条件时，预设是使用and来组合条件，如果要用or的方式来组合条件，则可以使用Restrictions.or()方法，例如结合age等于（eq）20或（or）age为空（isNull）的条件：<br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">criteria.add(Restrictions.or(</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">                   Restrictions.eq("age", new Integer(20)),</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">                   Restrictions.isNull("age")</small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">               ));</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /><font size="3">观察所产生的SQL语句，将使用where与or子句完成SQL的条件查询：<br /><br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ <span style="FONT-WEIGHT: bold">where (this_.age=? or this_.age is null)</span></small><br /></font></div><small><br /><font size="3">您也可以使用Restrictions.like()方法来进行SQL中like子句的功能，例如查询”name”中名称为”just”开头的资料：<br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small style="FONT-FAMILY: Courier New,Courier,monospace">Criteria criteria = session.createCriteria(User.class);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">criteria.add(<span style="FONT-WEIGHT: bold">Restrictions.like("name", "just%")</span>);</small><br style="FONT-FAMILY: Courier New,Courier,monospace" /><small style="FONT-FAMILY: Courier New,Courier,monospace">List users = criteria.list();</small><br /></font></div><small><br /><font size="3">观察所产生的SQL语句如下：<br /><br /></font></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ <span style="FONT-WEIGHT: bold">where this_.name like ?</span></small><br /></font></div><small><br /><font size="3">Restrictions的几个常用限定查询方法如下表所示：<br /></font></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><small></small><table style="WIDTH: 100%; TEXT-ALIGN: left" cellspacing="2" cellpadding="2" border="1"><tbody><tr><td style="BACKGROUND-COLOR: rgb(204,204,204)"><small><font size="3">方法</font></small></td><td style="BACKGROUND-COLOR: rgb(204,204,204)"><small><font size="3">说明</font></small></td></tr><tr><td><small><font size="3">Restrictions.eq</font></small></td><td><small><font size="3">等于</font></small></td></tr><tr><td><small><font size="3">Restrictions.allEq</font></small></td><td><small><font size="3">使用Map，使用key/value进行多个等于的比对</font></small></td></tr><tr><td><small><font size="3">Restrictions.gt</font></small></td><td><small><font size="3">大于 &gt;</font></small></td></tr><tr><td><small><font size="3">Restrictions.ge</font></small></td><td><small><font size="3">大于等于 &gt;=</font></small></td></tr><tr><td><small><font size="3">Restrictions.lt</font></small></td><td><small><font size="3">小于 &lt;</font></small></td></tr><tr><td><small><font size="3">Restrictions.le</font></small></td><td><small><font size="3">小于等于 &lt;=</font></small></td></tr><tr><td><small><font size="3">Restrictions.between</font></small></td><td><small><font size="3">对应SQL的BETWEEN子句</font></small></td></tr><tr><td><small><font size="3">Restrictions.like</font></small></td><td><small><font size="3">对应SQL的LIKE子句</font></small></td></tr><tr><td><small><font size="3">Restrictions.in</font></small></td><td><small><font size="3">对应SQL的in子句</font></small></td></tr><tr><td><small><font size="3">Restrictions.and</font></small></td><td><small><font size="3">and关系</font></small></td></tr><tr><td><small><font size="3">Restrictions.or</font></small></td><td><small><font size="3">or关系</font></small></td></tr><tr><td><small><font size="3">Restrictions.sqlRestriction</font></small></td><td><small><font size="3">SQL限定查询</font></small></td></tr></tbody></table><small><br /></small><img src ="http://www.blogjava.net/yzzh9/aggbug/233236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-08 22:27 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/08/233236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>林信良：Hibernate之实体物件生命周期</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/08/233230.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Wed, 08 Oct 2008 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/08/233230.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233230.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/08/233230.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233230.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233230.html</trackback:ping><description><![CDATA[Hibernate中的实体物件可以分为四种状态：<span style="FONT-WEIGHT: bold">Transient、 Persistent、Detached</span>、<span style="FONT-WEIGHT: bold">Removed</span>。<br /><ul><li><font size="3"><small>Transient</small></font></li></ul><div style="MARGIN-LEFT: 40px"><small><font size="3">当您直接使用new创建出物件，例如在之前的例子中， User类别所衍生出之物件，在还没有使用save()之前都是Transient物件，这些物件还没有与资料库发生任何的关系，不对应于资料库中的任一笔资料。 <br /><br /></font></small></div><ul><li><font size="3"><small>Persistent</small></font></li></ul><div style="MARGIN-LEFT: 40px"><small><font size="3">当物件与资料库中的资料有对应关系，并且与Session 实例有关联而Session 实例尚未关闭（close），则它是在Persistent状态，具体而言，如果您将Transient状态的物件使用Session的save()方法加以储存，或是使用Hibernate从资料库载入资料并封装为物件（例如使用get()、load()等查询物件的相关方法），则该物件为Persistent状态。<br /><br />Persistent状态的物件对应于资料库中的一笔资料，物件的id值与资料的主键值相同，并且Session实例尚未失效，在这期间您对物件的任何状态变动，在Session实例关闭（close）或Transaction实例执行commit()之后，资料库中对应的资料也会跟着更新。<br /><br />如果您将Session实例关闭（close），则Persistent状态的物件会成为Detached状态。<br /><br />如果您使用Session的实例delete()方法删除资料，Persistent状态的物件由于失去了对应的资料，则它会成为Transient状态。<br /></font></small></div><ul><li><font size="3"><small>Detached</small></font></li></ul><div style="MARGIN-LEFT: 40px"><small><font size="3">Detached状态的物件，其id与资料库的主键值对应，但脱离Session实例的管理，例如在使用load()方法查询到资料并封装为物件之后，将Session实例关闭，则物件由Persistent状态变为Detached状态，Detached状态的物件之任何属性变动，不会对资料库中的资料造成任何的影响。<br /><br />Detached状态的物件可以使用update()方法使之与资料库中的对应资料再度发生关联，此时Detached状态的物件会变为 Persistent状态。<br /><br />Detached物件，若不再被任何名称参考，则在适当的时候将被垃圾收集所回收。<br /><br /></font></small></div><ul><li><font size="3"><small>Removed</small></font></li></ul><div style="MARGIN-LEFT: 40px"><small><font size="3">如果您使用Session的实例delete()或remove()方法删除资料，Persistent状态的物件由于失去了对应的资料，则它会成为Removed状态，一个成为Removed状态的物件不应该被继续重用，您应该释放任何参考至它的名称，让该物件在适当的时候被垃圾回收。</font></small></div><div style="MARGIN-LEFT: 40px"><small><br /></small></div><small><font size="3">简单的说，Transient与Detached状态的物件未受Hibernate持久层管理员管理，对这两个状态的物件作任何属性变动，不会对资料库中的资料有任何的影响，<font color="#ff3333">Detached状态物件可以读取数据库数据。</font>而Persistent状态的物件受Hibernate持久层管理，对物件的属性变动，在Session实例关闭（close）或 Transaction实例执行commit()之后，资料库中对应的资料也会跟着更新。<br /><br />Transient与Detached状态的物件是<span style="FONT-WEIGHT: bold">非管理状态</span>，而Persistent状态的物件是<span style="FONT-WEIGHT: bold">管理状态</span>，又称为Persistent Object，其与一个</font><a href="http://caterpillar.onlyfun.net/GossipCN/HibernateGossip/PersistenceContext.html"><font size="3">Persistence Context </font></a><font size="3">关联。<br /><br />在物件为Persistent时，如果物件的属性发生变化，并且尚未提交之前，物件所携带的资料称之为Dirty Data，Hibernate会在Persistence Context维护物件的最近读取版本，并在资料提交时检查两个版本的属性是否有变化，如果有的话，则将资料库中的资料进行更新</font></small>。<br /><br /><img style="WIDTH: 563px; HEIGHT: 522px" alt="" src="http://caterpillar.onlyfun.net/GossipCN/HibernateGossip/images/EntityObjectLifeCycle-1.jpg" /><img src ="http://www.blogjava.net/yzzh9/aggbug/233230.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-08 21:32 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/08/233230.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Session管理类</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/07/233006.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Tue, 07 Oct 2008 13:50:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/07/233006.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233006.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/07/233006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233006.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233006.html</trackback:ping><description><![CDATA[public class HibernateUtils {<br /> <br /> private static SessionFactory factory;<br /> <br /> private HibernateUtils() {}<br /> <br /> static {<br />  Configuration cfg = new Configuration().configure();<br />  factory = cfg.buildSessionFactory();<br /> }<br /> <br /> public static SessionFactory getSessionFactory() {<br />  return factory;<br /> }<br /> <br /> public static Session getSession() {<br />  return factory.openSession();<br /> }<br /> <br /> public static void closeSession(Session session) {<br />  if (session != null) {<br />   if (session.isOpen()) {<br />    session.close();<br />   }<br />  }<br /> }<br /> <br />}<img src ="http://www.blogjava.net/yzzh9/aggbug/233006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-07 21:50 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/07/233006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>林信良：Hibernate之session</title><link>http://www.blogjava.net/yzzh9/archive/2008/10/07/233002.html</link><dc:creator>999</dc:creator><author>999</author><pubDate>Tue, 07 Oct 2008 13:40:00 GMT</pubDate><guid>http://www.blogjava.net/yzzh9/archive/2008/10/07/233002.html</guid><wfw:comment>http://www.blogjava.net/yzzh9/comments/233002.html</wfw:comment><comments>http://www.blogjava.net/yzzh9/archive/2008/10/07/233002.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yzzh9/comments/commentRss/233002.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yzzh9/services/trackbacks/233002.html</trackback:ping><description><![CDATA[Hibernate在对资料库进行操作之前，必须先取得Session实例，相当于JDBC在对资料库操作之前，必须先取得Connection实例， Session是Hibernate操作的基础，它不是设计为执行绪安全（Thread-safe），一个Session由一个执行绪来使用。<br /><br /><ul><li><font size="3"><small>开启Session</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>Session实例由SessionFactory开启获得，例如：</small><br /><small></small></font></div><div style="MARGIN-LEFT: 80px"><small><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Configuration config = new Configuration().configure();</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">SessionFactory sessionFactory = config.buildSessionFactory();</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /></font><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">Session session = sessionFactory.openSession();<br /></font></span></small><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /></font><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">....<br />tx.commit();<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /></span><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span><br /></font></small></div><div style="MARGIN-LEFT: 40px"><small></small><br /><small></small><font size="3"><small>开启Session不会马上取得Connection，而是在最后真正需要连接资料库进行更新或查询时才会取得Connection，如果有设定Connection pool，则从Connection pool中取得Connection，而关闭Session时，如果有设定Connection pool，则是将Connection归还给Connection pool，而不是直接关闭Connection。</small><br /><small></small><br /><small>在Hibernate中，开启一个Session会建立一个<a href="http://caterpillar.onlyfun.net/GossipCN/HibernateGossip/PersistenceContext.html">Persistence context</a>，它可以进行快取管理、dirty check等，而所有的读取、更新、插入等动作，则是在Transaction中完成。</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>储存资料</small></font></li></ul><small></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>透过Session，可以对资料库进行新增、删除、更新，例如使用save()新增一笔资料：</small><br /><small></small></font></div><div style="MARGIN-LEFT: 80px"><small><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user = new User(); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user.setName("momor"); </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /></font><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">user.setAge(new Integer(26));<br /><br /></font></span></small><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span></small><br /></font><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">Transaction tx = session.beginTransaction();<br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /></font></span><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">session.save(user); <br />tx.commit();<br />session.close();<br /></font></span></small></div><div style="MARGIN-LEFT: 40px"><small></small><br /><font size="3"><small>save()之后，不会马上对资料库进行更新，而是在Transaction的commit()之后才会对资料库进行更新，在Transaction之间的操作要就全部成功，要就全部失败，如果更新失败，则在资料库层面会撤消所有更新操作，然而记忆体中的持久物件是不会回复原有状态的，事实上，当 Transaction失败，这一次的Session就要马上跟着失效，放弃所有记忆体中的物件，而不是尝试以原物件再进行更新的动作。</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>取得资料</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>您使用get()或load()方法取得id为1的资料：</small><br /><small></small></font></div><div style="MARGIN-LEFT: 80px"><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br /></font></div><div style="MARGIN-LEFT: 80px"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">User user = (User) session.get(User.class, new Integer(1));<br /></font></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"><font size="3">tx.commit();<br />session.close();<br /></font></span></small></div><div style="MARGIN-LEFT: 40px"><small></small><br /><font size="3"><small><span id="LblContent">如果未能发现相符合的资料，则get()方法会返回null，而load()方法会丢出ObjectNotFoundException，在进阶的应用中，load()方法可以返回代理（proxy）物件，在必要时才真正查询资料库取得对应资料，并可充分利用快取机制。</span></small><br /><small></small><br /><small>在Hibernate 3中，取消了find()方法，您必须透过Query或Criteria来进行资料查询。</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>删除资料</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>接下来看看使用Session删除资料，可使用delete()删除资料：</small><br /><small></small></font><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user = (User) session.get(User.class, new Integer(1));</span></small><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.delete(user);</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small></font></div></div><div style="MARGIN-LEFT: 40px"><small></small></div><small></small><ul><li><font size="3"><small>更新资料</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>当您在同一个Session中取出资料并封装为Persistence Object，接着更新物件状态，而后将Transaction commit，则物件上的状态更新将反应至资料库中，您无需额外进行任何的更新操作。<br /><br />如果您开启了一个Session，从资料表中取出资料显示到使用者介面上，之后关闭Session，当使用者在介面上操作完毕并按下储存时，这时您要重新开启一个Session，使用update()方法将物件中的资料更新至对应的资料表中：</small><br /><small></small></font></div><div style="MARGIN-LEFT: 80px"><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();<br /></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br /></font><small><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user = (User) session.get(User.class, new Integer(2));<br />tx.commit();<br />session.close();<br />....<br style="FONT-WEIGHT: bold" />user.setAge(new Integer(27));<br />session = sessionFactory.openSession();    <br />tx= session.beginTransaction(); <br style="FONT-WEIGHT: bold" />session.update(user);<br />tx.commit();<br />session.close();</span></font><span style="FONT-WEIGHT: bold; FONT-STYLE: italic"><br /></span></small></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>Session提供了一个saveOrUpdate()方法，为资料的储存或更新提供了一个统一的操作介面，藉由定义映射文件时，设定&lt; id&gt;标签的unsaved-value来决定什么是新的值必需，什么是已有的值必须更新： </small><br /><small></small></font></div><div style="MARGIN-LEFT: 80px"><small><font size="3"><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">&lt;id name="id" column="id" type="java.lang.Integer" unsaved-value="null"&gt;</span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">    &lt;generator class="native"/&gt; </span><br style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace" /><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">&lt;/id&gt; </span><br /></font></small></div><div style="MARGIN-LEFT: 40px"><small></small><br /><font size="3"><small>unsaved-value可以设定的值包括： </small><br /><small></small></font></div><ul style="MARGIN-LEFT: 40px"><li><small><font size="3">any：总是储存 </font></small></li><li><small><font size="3">none：总是更新 </font></small></li><li><small><font size="3">null：id为null时储存（预设） </font></small></li><li><small><font size="3">valid：id为null或是指定值时储存 </font></small></li></ul><div style="MARGIN-LEFT: 40px"><small></small><br /><font size="3"><small>这样设定之后，您可以使用Session的saveOrUpdate()方法来取代update()方法。</small><br /></font></div><small><br /></small><ul><li><font size="3"><small>合并状态</small></font></li></ul><div style="MARGIN-LEFT: 40px"><font size="3"><small>以这边的例子来说：</small><br /></font><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user1 = (User) session.get(User.class, new Integer(2));</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">....</span></small><br style="FONT-WEIGHT: bold" /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setAge(new Integer(27));</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session = sessionFactory.openSession();    </span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx= session.beginTransaction(); </span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user2 = </span></small></font><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">(User) session.get(User.class, new Integer(2)); // 同一个id<br />// user1 == user2 为 false<br style="FONT-WEIGHT: bold" /></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.update(user1); // 丢出NonUniqueObjectException</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span></small></font></div></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>在进行update()之前，您就先从资料库中取得另一笔资料，之后再尝试更新user1，由于目前的Persistence context已载入一笔资料，并有同一个id的User 实例了，同一个Persistence context不会有两个相同id的物件实例，因此丢出NonUniqueObjectException。</small><br /><br /><small>就这边的例子来说，您应该使用merge()而不是update()：</small><br /></font><div style="MARGIN-LEFT: 40px"><font size="3"><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">Transaction tx = session.beginTransaction();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user1 = (User) session.get(User.class, new Integer(2));</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">....</span></small><br style="FONT-WEIGHT: bold" /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">user1.setAge(new Integer(27));</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session = sessionFactory.openSession();    </span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx= session.beginTransaction(); </span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user2 = </span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">(User) session.get(User.class, new Integer(2)); // 同一个id</span></small><br style="FONT-WEIGHT: bold" /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">User user3 = (User) session.merge(user1);</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">// user1 == user2 为 false</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">// user2 == user3 为 true</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace"></span></small><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">tx.commit();</span></small><br /><small><span style="FONT-WEIGHT: bold; FONT-FAMILY: Courier New,Courier,monospace">session.close();</span></small><br /></font></div></div><small><br /></small><div style="MARGIN-LEFT: 40px"><font size="3"><small>merge()会将user1与user2的状态合并，传回的物件实例就是user2原先所参考的实例。</small><br /></font></div><img src ="http://www.blogjava.net/yzzh9/aggbug/233002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yzzh9/" target="_blank">999</a> 2008-10-07 21:40 <a href="http://www.blogjava.net/yzzh9/archive/2008/10/07/233002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>