﻿<?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-LifeNote -随笔分类-Hibernate</title><link>http://www.blogjava.net/lifenote/category/27920.html</link><description>&amp;nbsp;
Try to find something different in your life and then write it down&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;strong&gt;Java乐园：&lt;a href='http://www.java-bj.cn' target='_blank'&gt;&lt;font color='red' size="+1"&gt;www.java-bj.cn&lt;/font&gt;&lt;/a&gt;  资料下载&lt;/strong&gt;
&lt;div style="float:left"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-4636496036365579";
/* 468x60, 创建于 08-4-23 */
google_ad_slot = "3356926921";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;div style="float:left"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-4636496036365579";
/* 468x60, 创建于 08-4-23 */
google_ad_slot = "5017273295";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 24 Apr 2008 07:51:56 GMT</lastBuildDate><pubDate>Thu, 24 Apr 2008 07:51:56 GMT</pubDate><ttl>60</ttl><item><title>Eclipse下的Java反编译插件：Jode Decompiler</title><link>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 24 Apr 2008 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/195588.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/195588.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/195588.html</trackback:ping><description><![CDATA[这个工具感觉非常方便 介绍给大家<br />
安装方法： <br />
&nbsp;&nbsp;&nbsp;&nbsp;help =&gt; Software Updates =&gt; Find and Install... =&gt; Search for new features to install,单击"New Remote Site..." 在URL栏输入 <a onclick="showLinkBubble(this);return false" href="http://www.technoetic.com/eclipse/update" target="_blank" link="http://www.technoetic.com/eclipse/update">http://www.technoetic.com/eclipse/update</a><wbr>.然后下一步，就可以看到&#8220;jode decompiler plugin *.*&#8221;，选上安装就可以了。 <br />
<br />
安装好后可以看到Window =&gt; Preferences... =&gt; Java =&gt; Jode Decompiler选项卡。 <br />
<br />
配置：Window =&gt; Preferences... =&gt; General =&gt; Editors =&gt; File Associations找到"*.class"在"Associated editors"里面可以看到"Jode class file viewer"选中它再单击Default按钮. <br />
<br />
在Eclipse中展开jar文件,双击class文件即可看到反编译之后的源代码.<br />
<img src ="http://www.blogjava.net/lifenote/aggbug/195588.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-04-24 15:05 <a href="http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java数据库操作基本流程</title><link>http://www.blogjava.net/lifenote/archive/2008/04/24/195431.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 24 Apr 2008 02:36:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/04/24/195431.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/195431.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/04/24/195431.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/195431.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/195431.html</trackback:ping><description><![CDATA[<div class="NewsContent" id="NewsContentLabel"><span class="t18"><span class="a14c" id="zoom"><font face="Times New Roman" size="3">1.Java数据库操作基本流程<br />
a .数据库连接1.Drivermanager 链接数据库<br />
String className,url,uid,pwd;<br />
className="Oracle.jdbc.driver.OracleDriver";<br />
uid="scott";<br />
pwd="tiger";<br />
url="jdbc:oracle:thin:@localhost:1521:ora92";<br />
Class.forName(classname);<br />
Connection conn=DriverManager.getConnection(url,uid,pwd);<br />
2.JNDI链接数据库<br />
String jndi ="jdbc/db"; //&nbsp; e20-040 9L0-609 数据源的名称<br />
//context是一组名称到对象的绑定组成<br />
Hashtable env=new Hashtable ();<br />
Context ctx=(Context)new InitialContext.lookup("env");// 获得数据源所在的上下文点的对象<br />
DataSource ds=(DataSource)ctx.lookup(jndi);//找到数据源</font>
<p class="Ltw305"></p>
<p>&nbsp;</p>
<font face="Times New Roman" size="3">
<p><br />
Connection conn=ds.getConnection();//<br />
b.执行 sql语句<br />
String sql;<br />
StateMent stat=conn.createStatement();<br />
ResultSet rs=stat.executeQuery(sql);//执行数据的查询语句(select);<br />
stat.executeUpdate(sql);//执行数据的更新语句(inset into ,delete ,update ,drop)<br />
stat.close();<br />
c.用preparedStatement 来执行sql语句<br />
String sql="inset into table(id,name) values(?,?)";<br />
PreparedStatement ps=conn.prepareStatement(sql);<br />
ps.setInt(1,001);<br />
ps.setString(2,"zhangmanli"); <font color="#ffffff"></font></p>
<p>ps.executeQuery();<br />
int count=ps.executeUpdate();<br />
d.处理执行结果<br />
查询语句，返回记录集ResultSet对象<br />
更新语句，返回数字，表示该更新影响的记录数<br />
javax.sql.*<br />
javax.naming.*;<br />
数据处理：<br />
1关闭connection 的自动提交<br />
conn.setAutoCommit(false);<br />
2执行一系列sql 语句，<br />
Statement sm;<br />
sm=conn.createStatement(sql);<br />
sm.executeUpdate();<br />
sm.close(); </p>
<p>3.提交： <br />
conn.commit();<br />
4.回滚机制；<br />
conn.rollback();<br />
e:线程处理：<br />
D：jndi和dataSource 来获得数据库的链接：<br />
import java.sql.ResultSet ;<br />
import java.sql.*;<br />
import javax.sql.DataSource;<br />
import javax.naming.Context;<br />
import javax.naming.InitialContext;<br />
import java.util.Hashtable;<br />
import java.util.Properties;<br />
import java.io.*;<br />
public class BasicExample{<br />
&nbsp;public static void main(String args[]){<br />
&nbsp; Connection conn=null;<br />
&nbsp; try{<br />
&nbsp;&nbsp; Properties prop =new Properties();<br />
&nbsp;&nbsp; prop.load(new FileInputStream("simple.properties"));<br />
&nbsp;&nbsp; Hashtable env =new Hashtable();<br />
&nbsp;&nbsp; env.put(Context.INITIAL_CONTEXT_FACTORY,prop.getProperty("INITIAL_CONTEXT_FACTORY"));<br />
&nbsp;&nbsp; env.put(Context.PROVIDER_URL,prop.getProperty("PROVIDER_URL"));<br />
&nbsp;&nbsp; InitialContext ctx=new InitialContext(env);<br />
&nbsp; DataSource ds=(DataSource)ctx.lookup("Book");
<p class="Ltw305"></p>
<br />
&nbsp;&nbsp; Conn=ds.getConnection();<br />
&nbsp;&nbsp; Statement stat=conn.createStatement();;<br />
&nbsp;&nbsp; ResultSet rs=stmt.executeQuery(sql);<br />
&nbsp;&nbsp; while(rs.next()){<br />
&nbsp;&nbsp;&nbsp; int id=Integer.parseInt(rs.getString("userId"));<br />
&nbsp;&nbsp;&nbsp; String userName=rs.getString ("username");<br />
<br />
&nbsp;&nbsp; }<br />
&nbsp; }catch(SQLException e){<br />
&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp; }finally{<br />
&nbsp;&nbsp; try{<br />
&nbsp;&nbsp;&nbsp; if(conn!=null){<br />
&nbsp;&nbsp;&nbsp;&nbsp; conn.close();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; }catch(SQLException e){<br />
&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />
&nbsp;&nbsp; }<br />
&nbsp; }<br />
&nbsp;}<br />
}; </font></span></span></div>
<img src ="http://www.blogjava.net/lifenote/aggbug/195431.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-04-24 10:36 <a href="http://www.blogjava.net/lifenote/archive/2008/04/24/195431.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中Criteria的完整用法 </title><link>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Wed, 12 Mar 2008 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/185708.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/185708.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/185708.html</trackback:ping><description><![CDATA[最近在项目中使用 Spring 和 Hibernate 进行开发，有感于 Criteria 比较好用，在查询方法<br />
<br />
<font face="Times New Roman" size="4">设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结：</font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp; Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口，下面提供了 Criteria和DetachedCriteria </font>。 <br />
&nbsp;&nbsp; Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样， Criteria 是在线的，所</font><br />
<font face="Times New Roman" size="4">以它是由 Hibernate Session 进行创建的；而 DetachedCriteria 是离线的，创建时无需 </font><br />
<font face="Times New Roman" size="4">Session，DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name) </font><br />
<font face="Times New Roman" size="4">进行DetachedCriteria 实例的创建。 Spring 的框架提供了getHibernateTemplate</font><br />
<font face="Times New Roman" size="4">().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结</font><br />
<font face="Times New Roman" size="4">果。 <br />
&nbsp;&nbsp; Criteria 和 DetachedCriteria 均可使用 Criterion 和 Projection 设置查询条件。可以设</font><br />
<font face="Times New Roman" size="4">置 FetchMode( 联合查询抓取的模式 ) ，设置排序方式。对于 Criteria 还可以设置 FlushModel </font><br />
<font face="Times New Roman" size="4">（冲刷 Session 的方式）和 LockMode （数据库锁模式）。 </font><br />
<font face="Times New Roman" size="4">下面对 Criterion 和 Projection 进行详细说明。</font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp;&nbsp;&nbsp; Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来</font><br />
<font face="Times New Roman" size="4">添加查询条件。<br />
&nbsp;&nbsp;&nbsp;&nbsp; Criterion 接口的主要实现包括： Example 、 Junction 和 SimpleExpression 。而 </font><br />
<font face="Times New Roman" size="4">Junction 的实际使用是它的两个子类 conjunction 和 disjunction ，分别是使用 AND 和 OR 操</font><br />
<font face="Times New Roman" size="4">作符进行来联结查询条件集合。<br />
&nbsp;&nbsp;&nbsp;&nbsp; Criterion 的实例可以通过 Restrictions 工具类来创建，Restrictions 提供了大量的静态</font><br />
<font face="Times New Roman" size="4">方法，如 eq （等于）、 ge （大于等于）、 between 等来方法的创建 Criterion 查询条件 </font><br />
<font face="Times New Roman" size="4">（SimpleExpression 实例）。除此之外， Restrictions 还提供了方法来创建 conjunction 和 </font><br />
<font face="Times New Roman" size="4">disjunction 实例，通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合</font><br />
<font face="Times New Roman" size="4">。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 至于 Example 的创建有所不同， Example 本身提供了一个静态方法 create(Object </font><br />
<font face="Times New Roman" size="4">entity) ，即根据一个对象（实际使用中一般是映射到数据库的对象）来创建。然后可以设置一些</font><br />
<font face="Times New Roman" size="4">过滤条件： <br />
Example exampleUser =Example.create(u) <br />
.ignoreCase() // 忽略大小写 <br />
.enableLike(MatchMode.ANYWHERE); <br />
// 对 String 类型的属性，无论在那里值在那里都匹配。相当于 %value% </font><br />
<font face="Times New Roman" size="4">&nbsp; Project 主要是让 Criteria 能够进行报表查询，并可以实现分组。 Project 主要有 </font><br />
<font face="Times New Roman" size="4">SimpleProjection 、 ProjectionList 和 Property 三个实现。其中 SimpleProjection 和 </font><br />
<font face="Times New Roman" size="4">ProjectionList 的实例化是由内建的 Projections 来完成，如提供的 avg 、 count 、 max 、 </font><br />
<font face="Times New Roman" size="4">min 、 sum 可以让开发者很容易对某个字段进行统计查询。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property 是对某个字段进行查询条件的设置，如通过Porperty.forName(&#8220;color&#8221;).in</font><br />
<font face="Times New Roman" size="4">(new String[]{&#8220;black&#8221;,&#8221;red&#8221;,&#8221;write&#8221;}); 则可以创建一个 Project 实例。通过 </font><br />
<font face="Times New Roman" size="4">criteria 的 add(Project) 方法加入到查询条件中去。 </font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp;&nbsp; 使用 Criteria 进行查询，主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查</font><br />
<font face="Times New Roman" size="4">询条件的创建和组装，下面介绍几种用法：</font><br />
<font face="Times New Roman" size="4">1. 创建一个Criteria 实例<br />
org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。<br />
Criteria crit = sess.createCriteria(Cat.class);<br />
crit.setMaxResults(50);<br />
List cats = crit.list();<br />
&nbsp;<br />
2. 限制结果集内容<br />
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。</font><br />
<br />
<font face="Times New Roman" size="4">org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.between("weight", minWeight, maxWeight) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4">约束可以按逻辑分组。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.or(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Restrictions.eq( "age", new Integer(0) ),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Restrictions.isNull("age")<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.disjunction()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.isNull("age") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(0) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(1) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(2) ) )<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许</font><br />
<br />
<font face="Times New Roman" size="4">你直接使用SQL。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", </font><br />
<br />
<font face="Times New Roman" size="4">Hibernate.STRING) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
{alias}占位符应当被替换为被查询实体的列别名。 <br />
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个</font><br />
<br />
<font face="Times New Roman" size="4">Property。 <br />
&nbsp;<br />
&nbsp; Property age = Property.forName("age");<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.disjunction()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.isNull() )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(0) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(1) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(2) ) )<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
3. 结果集排序<br />
你可以使用org.hibernate.criterion.Order来为查询结果排序。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("name") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("age") )<br />
&nbsp;&nbsp;&nbsp; .setMaxResults(50)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("name").like("F%") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Property.forName("name").asc() )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Property.forName("age").desc() )<br />
&nbsp;&nbsp;&nbsp; .setMaxResults(50)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
4. 关联<br />
你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .createCriteria("kittens")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
注意第二个 createCriteria()返回一个新的 Criteria实例，该实例引用kittens 集合中的元素。 <br />
接下来，替换形态在某些情况下也是很有用的。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .createAlias("kittens", "kt")<br />
&nbsp;&nbsp;&nbsp; .createAlias("mate", "mt")<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eqProperty("kt.name", "mt.name") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
(createAlias()并不创建一个新的 Criteria实例。) <br />
Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得</font><br />
<br />
<font face="Times New Roman" size="4">符合条件的kittens， 你必须使用returnMaps()。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .createCriteria("kittens", "kt")<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("name", "F%") )<br />
&nbsp;&nbsp;&nbsp; .returnMaps()<br />
&nbsp;&nbsp;&nbsp; .list();<br />
Iterator iter = cats.iterator();<br />
while ( iter.hasNext() ) {<br />
&nbsp;&nbsp;&nbsp; Map map = (Map) iter.next();<br />
&nbsp;&nbsp;&nbsp; Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);<br />
&nbsp;&nbsp;&nbsp; Cat kitten = (Cat) map.get("kt");<br />
}</font><br />
<br />
<font face="Times New Roman" size="4">5. 动态关联抓取<br />
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .setFetchMode("mate", FetchMode.EAGER)<br />
&nbsp;&nbsp;&nbsp; .setFetchMode("kittens", FetchMode.EAGER)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
这个查询可以通过外连接抓取mate和kittens。<br />
&nbsp;<br />
6. 查询示例<br />
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。<br />
&nbsp;<br />
Cat cat = new Cat();<br />
cat.setSex('F');<br />
cat.setColor(Color.BLACK);<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Example.create(cat) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。 <br />
可以自行调整Example使之更实用。 <br />
&nbsp;<br />
Example example = Example.create(cat)<br />
&nbsp;&nbsp;&nbsp; .excludeZeroes()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //exclude zero valued properties<br />
&nbsp;&nbsp;&nbsp; .excludeProperty("color")&nbsp; //exclude the property named "color"<br />
&nbsp;&nbsp;&nbsp; .ignoreCase()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //perform case insensitive string comparisons<br />
&nbsp;&nbsp;&nbsp; .enableLike();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //use like for string comparisons<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add(example)<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
甚至可以使用examples在关联对象上放置条件。<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Example.create(cat) )<br />
&nbsp;&nbsp;&nbsp; .createCriteria("mate")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Example.create( cat.getMate() ) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
7. 投影(Projections)、聚合（aggregation）和分组（grouping）<br />
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用 </font><br />
<br />
<font face="Times New Roman" size="4">setProjection()应用投影到一个查询。 <br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.rowCount() )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("color", Color.BLACK) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount() )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.avg("weight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.max("weight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.groupProperty("color") )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />

<p><font face="Times New Roman" size="4"><br />
在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为 分组投影，他</font><br />
<br />
<font face="Times New Roman" size="4">们也出现在SQL的group by子句中。 </font><br />
<br />
<font face="Times New Roman" size="4">可以选择把一个别名指派给一个投影，这样可以使投影值被约束或排序所引用。下面是两种不同的</font><br />
<br />
<font face="Times New Roman" size="4">实现方式：<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp;&nbsp;&nbsp; .list();</font></p>
<br />

<p><font face="Times New Roman" size="4">List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.groupProperty("color").as("colr") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之，</font><br />
<br />
<font face="Times New Roman" size="4">当你添加一个投影到一个投影列表中时 你可以为它指定一个别名： <br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount(), "catCountByColor" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.avg("weight"), "avgWeight" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.max("weight"), "maxWeight" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.groupProperty("color"), "color" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
List results = session.createCriteria(Domestic.class, "cat")<br />
&nbsp;&nbsp;&nbsp; .createAlias("kittens", "kit")<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.property("cat.name"), "catName" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.property("kit.name"), "kitName" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("catName") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("kitName") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
也可以使用Property.forName()来表示投影：<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("name") )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("color").eq(Color.BLACK) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4">List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount().as("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("weight").avg().as("avgWeight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("weight").max().as("maxWeight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("color").group().as("color" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
8. 离线(detached)查询和子查询<br />
DetachedCriteria类使你在一个session范围之外创建一个查询，并且可以使用任意的 Session来</font><br />
<br />
<font face="Times New Roman" size="4">执行它。<br />
&nbsp;<br />
DetachedCriteria query = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("sex").eq('F') );<br />
//创建一个Session<br />
Session session = .;<br />
Transaction txn = session.beginTransaction();<br />
List results = query.getExecutableCriteria(session).setMaxResults(100).list();<br />
txn.commit();<br />
session.close();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者</font><br />
<font face="Times New Roman" size="4">Property获得。<br />
&nbsp;<br />
DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight").avg() );<br />
session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("weight).gt(avgWeight) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4">DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight") );<br />
session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Subqueries.geAll("weight", weights) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4"><br />
相互关联的子查询也是有可能的：<br />
&nbsp;<br />
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight").avg() )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("cat2.sex").eqProperty("cat.sex") );<br />
session.createCriteria(Cat.class, "cat")<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("weight).gt(avgWeightForSex) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
</font></p>
<img src ="http://www.blogjava.net/lifenote/aggbug/185708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-03-12 15:24 <a href="http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入理解Tapestry的Rewind</title><link>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Sat, 08 Mar 2008 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/184695.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/184695.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/184695.html</trackback:ping><description><![CDATA[Tapestry的rewind一直是学习和使用Tapestry的难点，rewind是用来处理表单提交的，表单默认使用的是DirectService来提交。在详细介绍之前，先说明下此文中需要用到的一些概念，首先是表单组件，我这里指的是指继承自AbstractFormComponent类的组件，例如：TextField、TextArea、Checkbox等，而不是具体的Form组件，表单组件使用时必须在Form组件中，这些组件在rewind时调用继承自AbstractFormComponent的rewindFormComponent来读取数据，并将数据赋值给容器或者页面。 <br />
我们来看一下最简单的TextField组件，组件定义如下 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;input&nbsp;&nbsp;jwcid=</span><span class="string">"price@TextField"</span><span>&nbsp;type=</span><span class="string">"text"</span><span>&nbsp;value=</span><span class="string">"ognl:picture.price"</span><span>&nbsp;&nbsp;translator=</span><span class="string">"translator:number,pattern=##.##"</span><span>&nbsp;&nbsp;validators=</span><span class="string">"validators:min=0"</span><span>&nbsp;displayName=</span><span class="string">"价格"</span><span>&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"input_text"</span><span>/&gt;&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<pre class="java" style="display: none" name="code">&lt;input  jwcid="price@TextField" type="text" value="ognl:picture.price"  translator="translator:number,pattern=##.##"  validators="validators:min=0" displayName="价格" class="input_text"/&gt;</pre>
<br />
再看一下TextField中的rewindFormComponent组件方法 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;rewindFormComponent(IMarkupWriter&nbsp;writer,&nbsp;IRequestCycle&nbsp;cycle)&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//从请求中得到参数值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;cycle.getParameter(getName()); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//用translator来转换值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;object&nbsp;=&nbsp;getTranslatedFieldSupport().parse(</span><span class="keyword">this</span><span>,&nbsp;value); &nbsp;&nbsp;</span></span>
    <li><span class="comment">//用validators来验证值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getValidatableFieldSupport().validate(</span><span class="keyword">this</span><span>,&nbsp;writer,&nbsp;cycle,&nbsp;object); &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//赋值给容器或者页面 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setValue(object); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(ValidatorException&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getForm().getDelegate().record(e); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<pre class="java" style="display: none" name="code">protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) {
//从请求中得到参数值
String value = cycle.getParameter(getName());
try {
//用translator来转换值
Object object = getTranslatedFieldSupport().parse(this, value);
//用validators来验证值
getValidatableFieldSupport().validate(this, writer, cycle, object);
//赋值给容器或者页面
setValue(object);
} catch (ValidatorException e) {
getForm().getDelegate().record(e);
}
}</pre>
<br />
可以看到在rewindFormComponent中，主要是从请求中取得用户输入的值，然后进行处理，最后赋值给容器或者页面，上面的例子中会调用页面类的getPicture().setPrice(&#8220;用户输入的值&#8221;)来进行赋值。这样整个表单的提交就可以理解为所有的表单组件读取用户输入的值并赋值给页面的过程。 <br />
整个表单提交的详细处理过程如下： <br />
<ul>* initialize():页面初始化 <br />
    * pageBeginRender() ("rewind"):getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为true <br />
    * rewind of the form / setting of properties:所有表单组件调用rewindFormComponent来取值赋值 <br />
    * Deferred listeners (for Submit components):调用Submit组件的listener <br />
    * Form's listener：调用Form组件的listener <br />
    * pageEndRender() ("rewind"): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为true <br />
    * pageBeginRender() (normal): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为false <br />
    * pageEndRender() (normal): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为false</ul>
    我们可以看到pageBeginRender和pageEndRender被调用了两次，两次中的区别为RequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>，因为我们在使用时经常利用pageBeginRender的初始化值，所以这里有很多使用上的误区，如果在pageBeginRender中从数据库读取数据来初始化跟表单提交无关的变量的话，就可能被调用两次，这个是应该避免的。什么叫跟表单提交无关的变量呢，就是表单组件中跟赋值无关的，例如上边提到的value="ognl:picture.price",这时picture就是与表单提交相关的变量，如果你没有初始化，那么在赋值时调用getPicture().setPrice()就会出现空指针异常，因为这是的picture为null。我们举个例子来看一下表单无关的变量，假如这个picture页面会显示一个创建picture的表单和所有picture的列表，那这个picture的列表就是与表单提交无关的变量，如果你在pageBeginRender中初始化的话，就需要区分是否rewind，否则表单提交时就会被初始化两次，让我们看一下代码： <br />
    <div class="dp-highlighter">
    <div class="bar">
    <div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
    </div>
    <ol class="dp-j">
        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPictures(List&lt;Picture&gt;&nbsp;pictures); &nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPictureInList();</span><span class="comment">//用于For中的value </span><span>&nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPicture(Picture&nbsp;picture);</span><span class="comment">//用于表单创建 </span><span>&nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;Picture&nbsp;getPicture(); &nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;pageBeginRender(PageEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span class="keyword">if</span><span>(getPicture()==</span><span class="keyword">null</span><span>){ &nbsp;&nbsp;</span></span>
        <li><span>setPicture(</span><span class="keyword">new</span><span>&nbsp;Picture()); &nbsp;&nbsp;</span></span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span>setPictures(getPictureService().findAll()); &nbsp;&nbsp;</span>
        <li><span>}&nbsp;&nbsp;</span> </li>
    </ol>
    </div>
    <pre class="java" style="display: none" name="code">public abstract void setPictures(List&lt;Picture&gt; pictures);
    public abstract void setPictureInList();//用于For中的value
    public abstract void setPicture(Picture picture);//用于表单创建
    public abstract Picture getPicture();
    public void pageBeginRender(PageEvent event) {
    if(getPicture()==null){
    setPicture(new Picture());
    }
    setPictures(getPictureService().findAll());
    }</pre>
    判断picture是否为null并赋值在页面显示和rewind中都是需要的，因为页面显示时，需要调用getPicture().getPrice(),页面rewind时，需要调用getPicture().setPrice(),这两个阶段中的picture都不能为null。但setPictures会在表单提交时被调用两次，在rewind阶段初始化它是没有用处的，所以这时就要对是否rewind进行判断。修改后的代码如下： <br />
    <div class="dp-highlighter">
    <div class="bar">
    <div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
    </div>
    <ol class="dp-j">
        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;pageBeginRender(PageEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span class="keyword">if</span><span>(getPicture()==</span><span class="keyword">null</span><span>){ &nbsp;&nbsp;</span></span>
        <li><span>setPicture(</span><span class="keyword">new</span><span>&nbsp;Picture()); &nbsp;&nbsp;</span></span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span class="keyword">if</span><span>&nbsp;(!event.getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>())&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span>setPictures(getPictureService().findAll()); &nbsp;&nbsp;</span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span>}&nbsp;&nbsp;</span> </li>
    </ol>
    </div>
    <pre class="java" style="display: none" name="code">public void pageBeginRender(PageEvent event) {
    if(getPicture()==null){
    setPicture(new Picture());
    }
    if (!event.getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()) {
    setPictures(getPictureService().findAll());
    }
    }</pre>
    这样就可以避免在rewind时对pictures进行不必要的赋值。这里还要提到的一点是页面显示和提交后的页面很可能不是同一个页面类的实例，大家都知道页面类的实例是从实例池取到的，用户打开页面显示表单完后的页面类实例和用户提交表单时的用来rewind的页面类实例不一定是同一个，即使是一个实例，也是被重新初始化过的，不要想当然的认为显示表单后再提交那个实例应该保存原来显示的东西，这个应该理清楚。 <br />
    <br />
    原文地址：http://www.javaeye.com/article/41724
<img src ="http://www.blogjava.net/lifenote/aggbug/184695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-03-08 16:03 <a href="http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《J2EE核心模式》(DAO模式)</title><link>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 15 Feb 2008 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/180110.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/180110.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/180110.html</trackback:ping><description><![CDATA[<p>很多的J2EE应用程序需要使用持久性数据(数据库、文件等)。不同的程序，持久性存储是各不相同的，并且用来访问这些不同的持久性存储机制的API也有很大的不同。如果应用程序要在不同的持久性存储间迁移，这些访问特定持久存储层的代码将面临重写。<br />
如何解决这个问题?且看"DAO模式"</p>
<p>数据访问对象(Data&nbsp;Acess&nbsp;Object)&nbsp;模式<br />
一.环境<br />
根据数据源不同，数据访问也不同。根据存储的类型(关系数据库、面向对象数据库、文件等等)和供应商实现不同，持久性存储(比如数据库)的访问差别也很大</p>
<p>二.问题<br />
许多真是的J2EE应用程序需要在一定程度上使用持久性数据。对于许多应用程序，持久性存储是使用不同的机制实现的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。<br />
比如，应用程序使用实体bean(这里应该是指BMP的bean，CMP的bean已大大降低了与RDBMS的耦合)的分布式组件来表示持久性数据，或者使用JDBC&nbsp;API来访问驻留在某关系数据库管理系统(RDBMS)中的数据，这些组件中包含连接性性和数据访问代码会引入这些组件与数据源实现之间的紧密耦合。组件中这类代码依赖性使应用程序从某种数据源迁移到其他种类的数据源将变得非常麻烦和困难。当数据源变化时，组件也需要改变，以便于能够处理新类型的数据源</p>
<p>(举个例子来说，我们UPTEL系统是使用JDBC&nbsp;API对&nbsp;ORACLE数据库进行连接和数据访问的，这些JDBC&nbsp;API与SQL语句散布在系统中，当我们需要将UPTEL迁移到其他RDBMS时，比如曾经迁移到INFORMIX，就面临重写数据库连接和访问数据的模块。)</p>
<p>三.作用力<br />
1.诸如bean管理的实体bean、会话bean、servlet等组件往往需要从持久性存储数据源中检索数据，以及进行数据存储等操作。<br />
2.根据产品供应商的不同，持久性存储API差别也很大，这些API和其能力同样根据存储的类型不同也有差别，这样存在以下缺点，即访问这些独立系统的API很不统一。<br />
3.组件需要透明于实际的持久性存储或者数据源实现，以便于提供到不同供应商产品、不同存储类型和不同数据源类型的更容易的移植性。</p>
<p>四.解决方案<br />
使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便检索和存储数据。<br />
DAO实现了用来操作数据源的访问机制。数据源可以时RDBMS,LDAP,File等。依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时，DAO向客户端提供的接口不会变化，所有该模式允许DAO调整到不同的存储模式，而不会影响其客户端或者业务组件。重要的是,DAO充当组件和数据源之间的适配器。</p>
<p>(按照这个理论，如果我们UPTEL系统使用了DAO模式,就可以无缝的从ORACLE迁移到任何一个RDBMS了。梦想总是很完美的，且看看DAO模式如何实现)</p>
 <img src ="http://www.blogjava.net/lifenote/aggbug/180110.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-02-15 17:09 <a href="http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF中文输入乱码问题解决方法</title><link>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 31 Jan 2008 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/178680.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/178680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/178680.html</trackback:ping><description><![CDATA[<p class="content">该方法已知适用的版本tomact5.0.18,tomcat5.0.9。<br />
已知不适用的版本为tomcat5.0.28。<br />
问题描述：<br />
在inputtext中输入中文，然后在输出，显示为乱码。<br />
解决方法：<br />
1、自定义转器<br />
package util;<br />
import java.util.Map;<br />
import javax.faces.component.UIComponent;<br />
import javax.faces.convert.Converter;<br />
import javax.faces.context.FacesContext;<br />
import javax.faces.convert.ConverterException; </p>
<p class="content">public class StringConverter implements Converter {<br />
&nbsp;public Object getAsObject(FacesContext context, UIComponent component,<br />
&nbsp;&nbsp;&nbsp;String newValues) throws ConverterException {<br />
&nbsp;&nbsp;String newstr = "";<br />
&nbsp;&nbsp;if (newValues == null) {<br />
&nbsp;&nbsp;&nbsp;newValues = "";<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;byte[] byte1 = null;<br />
&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;byte1 = newValues.getBytes("ISO-8859-1");<br />
&nbsp;&nbsp;&nbsp;newstr = new String(byte1, "GB2312");<br />
&nbsp;&nbsp;&nbsp;UIInput input=(UIInput)component;//<br />
&nbsp;&nbsp;&nbsp;input.setSubmittedValue(newstr);<br />
&nbsp;&nbsp;} catch (UnsupportedEncodingException e) {<br />
&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;}</p>
<p class="content">&nbsp;&nbsp;return newstr;</p>
<p class="content">&nbsp;}</p>
<p class="content">&nbsp;public String getAsString(FacesContext context, UIComponent component,<br />
&nbsp;&nbsp;&nbsp;Object Values) throws ConverterException {&nbsp;<br />
&nbsp;&nbsp;return (String) Values;<br />
&nbsp;}<br />
}</p>
<p class="content">2、注册转换器<br />
faces-config.xml片段<br />
&lt;converter&gt;<br />
&nbsp; &lt;converter-id&gt;util.stringconverter&lt;/converter-id&gt;<br />
&nbsp; &lt;converter-class&gt;util.StringConverter&lt;/converter-class&gt;<br />
&lt;/converter&gt;</p>
<p class="content">3、在页面使用转换器<br />
&lt;h:inputText id="account" value="#{util.account}" required="true" styleClass="input" &gt;&nbsp;<br />
&nbsp;&lt;f:converter converterId="utilstringconverter"/&gt;</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/178680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-31 15:05 <a href="http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat,Weblogic 等服务器  SSL 安全登陆的例子---附证书文件生成器</title><link>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Tue, 15 Jan 2008 04:32:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/175432.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/175432.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/175432.html</trackback:ping><description><![CDATA[<p>公司今天一个登陆的地方要修改，需要加一个SSL安全登陆,于是查些资料并总结如下，希望对有用的着的朋友有帮助<br />
文件打包地址：http://www.blogjava.net/Files/lifenote/tomcat配置ssl.rar<br />
一下为帮助说明：<br />
<br />
1.1.&nbsp;安全登录 SSL<br />
1.1.1&nbsp;&nbsp;WebLogic下面SSL配置：<br />
1．生成 keystoreFile：<br />
&nbsp;* keystoreFile 文件的生成：<br />
%Java_Home%\bin\keytool -genkey -alias localhost-weblogic -keyalg RSA -validity 365 -keystore ./testKey.jks</p>
<p>&nbsp;* csr 文件的生成：<br />
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks</p>
<p>&nbsp;* 注意： http 的默认端口是80，https 的默认端口是433，ftp 的默认端口是21。<br />
2．部署keystore 文件<br />
在 &lt;http://hostname:7001/console&gt;&nbsp; 中配置刚才生成的 testKey.jks 文件。</p>
<p>1.1.2&nbsp;Tomcat 下面SSL配置</p>
<p><br />
1．生成 keystoreFile：<br />
&nbsp;* keystoreFile 文件的生成：<br />
%Java_Home%\bin\keytool -genkey -alias localhost-weblogic -keyalg RSA -validity 365 -keystore ./testKey.jks</p>
<p>Example for inner test：<br />
[root@localhost ~]# <br />
/home/tomcat/jdk1.5.0_12/bin/keytool -genkey -alias localhost-tomcat -keyalg RSA -validity 365 -keystore /home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks<br />
Enter keystore password:&nbsp; someday2007<br />
What is your first and last name?<br />
&nbsp; [Unknown]:&nbsp; lifenote<br />
What is the name of your organizational unit?<br />
&nbsp; [Unknown]:&nbsp; Java<br />
What is the name of your organization?<br />
&nbsp; [Unknown]:&nbsp; Sunxc<br />
What is the name of your City or Locality?<br />
&nbsp; [Unknown]:&nbsp; Beijing<br />
What is the name of your State or Province?<br />
&nbsp; [Unknown]:&nbsp; Beijing<br />
What is the two-letter country code for this unit?<br />
&nbsp; [Unknown]:&nbsp; ZH<br />
Is CN=lifenote, OU=Java, O=Sunxc, L=Beijing, ST=Beijing, C=ZH correct?<br />
&nbsp; [no]:&nbsp; y</p>
<p>Enter key password for &lt;localhost-tomcat&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RETURN if same as keystore password):&nbsp; someday2007<br />
[root@localhost ~]#</p>
<p>&nbsp;</p>
<p>&nbsp;* csr 文件的生成：<br />
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks</p>
<p>&nbsp;* 注意： http 的默认端口是80，https 的默认端口是433，ftp 的默认端口是21。</p>
<p><br />
2．部署keystore 文件<br />
&nbsp; 打开 server.xml 文件，修改内容如下：<br />
&nbsp;<br />
&nbsp;* 只需去掉 server.xml 中对SSL定义的注释，在加上 keystoreFile、keystorePass 这两个属性即可。<br />
&nbsp; &lt;Service<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Catalina"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;Connector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port="8080"<br />
&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&lt;!-- Define a SSL HTTP/1.1 Connector on port 8443 --------------------- 要加入的内容在这里 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;Connector port="8443" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" disableUploadTimeout="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount="100" scheme="https" secure="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientAuth="false" sslProtocol="TLS" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystoreFile="e:/temp_E/ssl/testKey.jks" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystorePass="aaaaaa"/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Connector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port="8009"<br />
&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />
&nbsp;...<br />
Example for inner test：<br />
&nbsp;&nbsp;&nbsp; &lt;Connector port="443" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" disableUploadTimeout="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount="100" scheme="https" secure="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientAuth="false" sslProtocol="TLS" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystoreFile="/home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystorePass="password"/&gt;</p>
<p><br />
&nbsp;注意需默认要使用 443 而不是 8443，要使用8443要在apache中配置，保证从apache请求tomcat 采用 &lt;https://ip:8443/&gt;... 的格式。</p>
<p><br />
1.1.3&nbsp;使用http访问WebService s的客户端配置<br />
Servlet服务器配置好SSL之后，客户端可以使用https访问了。<br />
对于用户使用浏览器访问https的方式，浏览器会弹出安装证书的对话框，确认之后可以正常使用https访问。<br />
&nbsp;对于WebService 通过https方式访问，按照一下步骤：<br />
1．&nbsp;WebService客户端要先取得keyStore文件；<br />
2．&nbsp;虚拟机系统使用 System.setProperties(&#8230;) 设置keyStore信息；<br />
3．&nbsp;使用 url=&lt;https://ip:port/...&gt; 访问WebService服务</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/175432.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-15 12:32 <a href="http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个Struts的上传下载文件的程序</title><link>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Mon, 14 Jan 2008 13:24:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/175299.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/175299.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/175299.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 参看了一些资料实现了一个Struts的上传下载文件的程序，提供下载学习，有什么不好的地方请留言多多指教<br />
为了节省空间，文件中没有导入java包，导入eclipse后请自行加入java包<br />
<a href="http://www.blogjava.net/Files/lifenote/"><br />
http://www.blogjava.net/Files/lifenote/</a>使用struts实现文件上传下载.rar<br />
<br />
要把上面的地址都复制哦
<img src ="http://www.blogjava.net/lifenote/aggbug/175299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-14 21:24 <a href="http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.lang.OutOfMemoryError 的解决办法</title><link>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Wed, 09 Jan 2008 05:27:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/173982.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/173982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/173982.html</trackback:ping><description><![CDATA[最近在使用Tomcat +Tapestry的时候遇见一个问题，由于Tapestry修改些内容后要重新启动（即使配置了一下那参数有时候也要重启）当我修改了页面的内容 需要调试不断刷新，发现页面显示的速度越来越慢 最后就出现了 500错误java.lang.OutOfMemoryError&nbsp; 内存溢出，在网上查了一下资料<br />
最后总结如下希望可以帮你解决同样的问题<br />
解决java.lang.OutOfMemoryError的方法有如下几种：<br />
1。增加jvm的内存大小。方法有：&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）在执行某个class文件时候，可以使用java&nbsp;-Xmx256M&nbsp;aa.class来设置运行aa.class时jvm所允许占用的最大内存为256M。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）对tomcat容器，可以在启动时对jvm设置内存限度。对tomcat，可以在catalina.bat中添加：<br />
&nbsp;&nbsp;set&nbsp;CATALINA_OPTS=-Xms128M&nbsp;-Xmx256M<br />
&nbsp;&nbsp;&nbsp;set&nbsp;JAVA_OPTS=-Xms128M&nbsp;-Xmx256M<br />
或者把%CATALINA_OPTS%和%JAVA_OPTS%代替为-Xms128M&nbsp;-Xmx256M
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3）对resin容器，同样可以在启动时对jvm设置内存限度。在bin文件夹下创建一个startup.bat文件，内容如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@echo&nbsp;off<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;"httpd.exe"&nbsp;&nbsp;"-Xms128M"&nbsp;"-Xmx256M"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:end&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中"-Xms128M"为最小内存，"-Xmx256M"为最大内存。</p>
<p>&nbsp;2.&nbsp;&nbsp;&nbsp;&nbsp;优化程序，释放垃圾。</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/173982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-09 13:27 <a href="http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多模块Struts应用程序的几个问题（及部分解决方法）</title><link>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 04 Jan 2008 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/172726.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/172726.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/172726.html</trackback:ping><description><![CDATA[<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">Struts</a>从1.1版本开始支持把应用程序分为多个模块，每个模块可以看作独立的应用程序，在带来方便的同时，我也发现了一些问题。比如有一个<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>应用程序分了大约十个模块，现在有以下问题不知道大家一般是怎么解决的：<br />
<div&nbsp;class=posttext><br />
<p>1、因为要进行验证，所以在每个模块对应的资源文件里都要有&#8220;errors.required={0}&nbsp;is&nbsp;required.&#8221;等资源，有没有只用在一个文件里定义的方法？</p>
<br />
<p>2、用tiles的时候，要在每个模块对应的tiles-defs.xml里定义几乎相同的definition，有没有只用在一个文件里定义的方法？（我试过在缺省模块里定义一个definition，然后在模块里extends它，但不行，extends似乎只找当前模块）</p>
<br />
<p>3、使用ExceptionHandler的时候，为什么在exception标签里指定了bundle属性还是只在当前模块里找资源？我希望把一些重复使用的异常处理声明在一个文件里，例如NotLoginException、NoSuchObjectException等等，并且它们对应的key也指向同一个资源文件里的资源（利用bundle属性），怎么实现？</p>
<br />
<p>经过一段时间的摸索，第一个和第三个问题基本上解决了，其实它们可以看作同一类问题，就是资源的问题。在<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>-config-xxx.xml里定义资源文件时，可以指定一个factory属性，不指定时使用缺省的&#8220;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.PropertyMessageResourcesFactory&#8221;类。我的解决方法是自定义一个CustomMessageResourcesFactory类，将多个资源文件以逗号分隔的形式作为参数（即message-resources的parameter属性）传给它，在需要资源的地方会遍历它们进行查找。同时还要自定义一个CustomMessageResources类，它的getMessage()方法里是查找资源的关键代码，而factory只是解析逗号分隔的参数构造并返回CustomMessageResources实例。</p>
<br />
<p>CustomMessageResourcesFactory的代码比较简单，如下所示：</p>
<br />
<DIV&NBSP;STYLE="BACKGROUND:&NBSP;#E6E6E6;&NBSP;BORDER-BOTTOM:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-LEFT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-RIGHT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-TOP:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;PADDING-BOTTOM:&NBSP;4PX;&NBSP;PADDING-LEFT:&NBSP;5.4PT;&NBSP;PADDING-RIGHT:&NBSP;5.4PT;&NBSP;PADDING-TOP:&NBSP;4PX;&NBSP;WIDTH:&NBSP;98%;&NBSP;WORD-BREAK:&NBSP;BREAK-ALL"><br />
<div><IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">package&nbsp;eg;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;java.util.Arrays;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.MessageResources;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.MessageResourcesFactory;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />public&nbsp;class&nbsp;CustomMessageResourcesFactory&nbsp;extends&nbsp;MessageResourcesFactory{<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;MessageResources&nbsp;createResources(String&nbsp;config)&nbsp;{<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">return</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">new</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">&nbsp;CustomMessageResources(Arrays.asList(config.split(</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">,</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">)));<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />}<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /></span>&nbsp;</div>
<br />
<p>&nbsp;</p>
<br />
<p>CustomMessageResources就稍微复杂一些，不过很幸运，我在网上找到了一个完全符合自己要求的类，下载地址在<A&NBSP;HREF="HTTP: javaboutique.internet.com tutorials Dynaform source.zip?><br />
<div><IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">&lt;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#800000">message-resources&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">factory</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">="eg.CustomMessageResourcesFactory"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">&nbsp;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;parameter</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">="eg.ApplicationResources,eg.ErrorResources"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">/&gt;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /></span>&nbsp;</div>
<br />
<p>&nbsp;</p>
<br />
<p>上面参考了这篇文章</SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#800000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></DIV&NBSP;STYLE="BACKGROUND:&NBSP;#E6E6E6;&NBSP;BORDER-BOTTOM:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-LEFT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-RIGHT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-TOP:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;PADDING-BOTTOM:&NBSP;4PX;&NBSP;PADDING-LEFT:&NBSP;5.4PT;&NBSP;PADDING-RIGHT:&NBSP;5.4PT;&NBSP;PADDING-TOP:&NBSP;4PX;&NBSP;WIDTH:&NBSP;98%;&NBSP;WORD-BREAK:&NBSP;BREAK-ALL">
</SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></p>
<img src ="http://www.blogjava.net/lifenote/aggbug/172726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-04 13:35 <a href="http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>博客搬家程序是如何实现的</title><link>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 27 Dec 2007 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/170914.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/170914.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/170914.html</trackback:ping><description><![CDATA[如题，找有开发过这样功能的朋友介绍一下，是分析html代码么&nbsp; 那比如sina 的和163的 代码肯定不一样的 那不是要写很多这样的程序 疑惑中。。。
<img src ="http://www.blogjava.net/lifenote/aggbug/170914.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-27 16:28 <a href="http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate3 的DetachedCriteria 学习</title><link>http://www.blogjava.net/lifenote/archive/2007/12/22/169494.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 21 Dec 2007 18:44:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/22/169494.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/169494.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/22/169494.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/169494.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/169494.html</trackback:ping><description><![CDATA[<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hibernate一直都认为比较简单 就那么影射一下：）但最近项目当中遇见很多问题，今天看见别人在项目当中使用了　</span><a href="http://dev.21tx.com/java/struts/" target="_blank"><span style="color: #000000">Hibernate</span></a><span style="color: #000000">3的DetachedCriteria，感觉真的是太好了，于是就花了点时间研究了一下，希望和大家分享一下吧<br />
　　针对这种需求，对于分层应用程序来说，Web层需要传递一个查询的条件列表给业务层对象，业务层对象获得这个条件列表之后，然后依次取出条件，构造查询语句。这里的一个难点是条件列表用什么来构造？传统上使用Map，但是这种方式缺陷很大，Map可以传递的信息非常有限，只能传递name和value，无法传递究竟要做怎样的条件运算，究竟是大于，小于，like，还是其它的什么，业务层对象必须确切掌握每条entry的隐含条件。因此一旦隐含条件改变，业务层对象的查询构造算法必须相应修改，但是这种查询条件的改变是隐式约定的，而不是程序代码约束的，因此非常容易出错。 <br />
<br />
　　DetachedCriteria可以解决这个问题，即在web层，程序员使用DetachedCriteria来构造查询条件，然后将这个DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后，可以在session范围内直接构造Criteria，进行查询。就此，查询语句的构造完全被搬离到web层实现，而业务层则只负责完成持久化和查询的封装即可，与查询条件构造完全解耦，非常完美！这恐怕也是以前很多企图在web层代码中构造HQL语句的人想实现的梦想吧！ <br />
<br />
　　示例代码片段如下： <br />
<br />
　　web层程序构造查询条件： <br />
<br />
　　</span><a href="http://dev.21tx.com/java/" target="_blank"><span style="color: #000000">Java</span></a><span style="color: #000000">代码: <br />
<span style="color: #000000">DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); <br />
detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));</span><br />
</span><br />
<span style="color: #000000">　　Department和Employee是一对多关联，查询条件为： <br />
<br />
　　名称是&#8220;department&#8221;开发部门； <br />
　　部门里面的雇员年龄大于20岁； <br />
<br />
　　业务层对象使用该条件执行查询： <br />
<br />
　　java代码: <span style="color: #000000">detachedCriteria.getExecutableCriteria(session).list();</span></span><br />
<span style="color: #000000">　　最大的意义在于，业务层代码是固定不变的，所有查询条件的构造都在web层完成，业务层只负责在session内执行之。这样代码就可放之四海而皆准，都无须修改了。<br />
<br />
　　然而Spring和Hibernate3的DetachedCriteria有不兼容的问题，因此在Spring环境下面使用Hibernate3需要注意： <br />
<br />
　　Spring的HibernateTemplate提供了Hibernate的完美封装，即通过匿名类实现回调，来保证Session的自动资源管理和事务的管理。其中核心方法是： <br />
<br />
　　java代码: <br />
<span style="color: #000000">HibernateTemplate.execute(new HibernateCallback() { <br />
　public Object doInHibernate(Session session) throws HibernateException { <br />
　　.... <br />
　} <br />
}</span></span><br />
<span style="color: #000000">　　回调方法提供了session作为参数，有了session，就可以自由的使用Hibernate API编程了。使用了spring的之后，代码修改如下： <br />
</span><strong><br />
</strong><span style="color: #000000">　　web层代码： <br />
<br />
　　java代码: <br />
</span><span style="color: #000000">DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class); <br />
detachedCriteria.createAlias("employees", "e").add(Restrictions.eq("name", "department")).add(Restrictions.gt(("e.age"), new Integer(20))); <br />
departmentManager.findByCriteria(detachedCriteria);</span><br />
<span style="color: #000000">　　构造detachedCriteria，作为参数传递给departmentManager <br />
<br />
　　业务层代码使用spring，DepartmentManager的findByCriteria如下： <br />
<br />
　　java代码: <br />
<br />
</span><span style="color: #000000">public List findByCriteria(final DetachedCriteria detachedCriteria) { <br />
　return (List) getHibernateTemplate().execute(new HibernateCallback() { <br />
　　public Object doInHibernate(Session session) throws HibernateException { <br />
　　　Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br />
　　　return criteria.list(); <br />
　　} <br />
　}); <br />
}</span><br />
<span style="color: #000000">　　实际上也就是： <br />
<br />
　　java代码: <br />
</span><span style="color: #000000">Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br />
return criteria.list(); </span><br />
<span style="color: #000000">　　而已 <br />
<br />
　　但是该程序代码执行，会抛出强制类型转换异常！ <br />
<br />
　　我跟踪了一下spring和Hibernate源代码，原因如下： <br />
<br />
　　spring的HibernateTemplate的execute方法提供的回调接口具有Session作为参数，但是实际上，默认情况下，HibernateTemplate传递给回调接口的session并不是org.hibernate.impl.SessionImpl类，而是SessionImpl类的一个Proxy类。之所以替换成为一个Proxy类，HibernateTemplate的注释说明，Proxy提供了一些额外的功能，包括自动设置Cachable，Transaction的超时时间，Session资源的更积极的关闭等等。 <br />
<br />
　　java代码: <br />
</span><span style="color: #000000">private boolean exposeNativeSession = false; <br />
... </span><br />
<span style="color: #000000">　　execute方法内部： </span>
<table class="txcode" cellspacing="0" cellpadding="0" align="center" border="0">
    <tbody>
        <tr>
            <td><span style="color: #000000">Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));</span></td>
        </tr>
    </tbody>
</table>
<br />
<span style="color: #000000">　　但是遗憾的是，Hibernate的DetachedCriteria的setExecutableCriteria方法却要求将session参数强制转为SessionImpl，但是spring传过来的却是一个Proxy类，因此就报错了。 <br />
<br />
　　java代码: </span>
<table class="txcode" cellspacing="0" cellpadding="0" align="center" border="0">
    <tbody>
        <tr>
            <td><span style="color: #000000">public Criteria getExecutableCriteria(Session session) { <br />
            　impl.setSession( (SessionImpl) session ); // 要求SessionImpl，Spring传递的是Proxy <br />
            　return impl; <br />
            }</span></td>
        </tr>
    </tbody>
</table>
<br />
<span style="color: #000000">　　解决方法，禁止Spring的HibernateTemplate传递Proxy类，强制要求它传递真实的SessionImpl类，即给exexute方法增加一个参数，提供参数为true，如下： <br />
<br />
　　java代码: </span>
<table class="txcode" cellspacing="0" cellpadding="0" align="center" border="0">
    <tbody>
        <tr>
            <td><span style="color: #000000">public List findByCriteria(final DetachedCriteria detachedCriteria) { <br />
            　return (List) getHibernateTemplate().execute(new HibernateCallback() { <br />
            　　public Object doInHibernate(Session session) throws HibernateException { <br />
            　　　Criteria criteria = detachedCriteria.getExecutableCriteria(session); <br />
            　　　return criteria.list(); <br />
            　　} <br />
            　}, true); <br />
            }</span></td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/lifenote/aggbug/169494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-22 02:44 <a href="http://www.blogjava.net/lifenote/archive/2007/12/22/169494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>★★oracle易忘函数用法★★</title><link>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 14 Dec 2007 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/167677.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/167677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/167677.html</trackback:ping><description><![CDATA[<p>===================★★oracle易忘函数用法★★=====================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;开发积累资料<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:SunXianchao<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2006年于湖南长沙<br />
==============================================================================<br />
一般的to_char是这样用的to_char(sysdate,'YYYY-MM-DD hh:mi:ss AM') ，也有几个突出点的用法：</p>
<p>to_char(sysdate, 'dd') 查看今天是几号to_char(sysdate, 'ww') 查看这是这个月第几个星期</p>
<p>to_char(sysdate, 'mm')&nbsp; 查看这是一年中第几个月</p>
<p>to_char(sysdate, 'yyyy') 查看年份last_day(to_date('2007-02-01','YYYY-MM-DD'))查看一个月的最后一天，add_months(sysdate,10)查看若干个月后的今天，next_day(sysdate,'星期五')给个日期查看后面的最近的星期几的日期，不过这个星期五要是换成英文居然有问题，第2个参数可以是数字1-7，分别表示周日到周六。</p>
<p>下面贴个全的，需要的时候顺便查一下。</p>
<p>一、PL/SQL单行函数和组函数详解</p>
<p>函数是一种有零个或多个参数并且有一个返回值的程序。在SQL中Oracle内建了一系列函数，这些函数都可被称为SQL或PL/SQL语句，函数主要分为两大类：单行函数和组函数。</p>
<p>本文将讨论如何利用单行函数以及使用规则。<br />
1、SQL中的单行函数</p>
<p>SQL和PL/SQL中自带很多类型的函数，有字符、数字、日期、转换、和混合型等多种函数用于处理单行数据，因此这些都可被统称为单行函数。这些函数均可用于SELECT,WHERE、ORDER BY等子句中，例如下面的例子中就包含了TO_CHAR,UPPER,SOUNDEX等单行函数。</p>
<p>SELECT ename,TO_CHAR(hiredate,'day,DD-Mon-YYYY')FROM empWhere UPPER(ename) Like 'AL%'ORDER BY SOUNDEX(ename) </p>
<p><br />
单行函数也可以在其他语句中使用，如update的SET子句，INSERT的VALUES子句，DELET的WHERE子句,认证考试特别注意在SELECT语句中使用这些函数，所以我们的注意力也集中在SELECT语句中。</p>
<p>2、NULL和单行函数</p>
<p>在如何理解NULL上开始是很困难的，就算是一个很有经验的人依然对此感到困惑。NULL值表示一个未知数据或者一个空值，算术操作符的任何一个操作数为NULL值，结果均为提个NULL值,这个规则也适合很多函数，只有CONCAT,DECODE,DUMP,NVL,REPLACE在调用了NULL参数时能够返回非NULL值。在这些中NVL函数时最重要的，因为他能直接处理NULL值，NVL有两个参数:NVL(x1,x2),x1和x2都式表达式，当x1为null时返回X2,否则返回x1。</p>
<p>下面我们看看emp数据表它包含了薪水、奖金两项，需要计算总的补偿。</p>
<p>column name emp_id salary bonuskey type pk nulls/unique nn,u nnfk table datatype number number numberlength 11.2 11.2 </p>
<p><br />
不是简单的将薪水和奖金加起来就可以了，如果某一行是null值那么结果就将是null，比如下面的例子：</p>
<p>update empset salary=(salary+bonus)*1.1 </p>
<p><br />
这个语句中，雇员的工资和奖金都将更新为一个新的值，但是如果没有奖金，即 salary + null,那么就会得出错误的结论，这个时候就要使用nvl函数来排除null值的影响。</p>
<p>所以正确的语句是：</p>
<p>update empset salary=(salary+nvl(bonus,0)*1.1 </p>
<p><br />
3、单行字符串函数</p>
<p>单行字符串函数用于操作字符串数据，他们大多数有一个或多个参数，其中绝大多数返回字符串。</p>
<p>ASCII()</p>
<p>c1是一字符串，返回c1第一个字母的ASCII码，他的逆函数是CHR()</p>
<p>SELECT ASCII('A') BIG_A,ASCII('z') BIG_z FROM empBIG_A BIG_z65 122 </p>
<p><br />
CHR()[NCHAR_CS]</p>
<p>i是一个数字，函数返回十进制表示的字符。</p>
<p>select CHR(65),CHR(122),CHR(223) FROM empCHR65 CHR122 CHR223A z B </p>
<p><br />
CONCAT(,)</p>
<p>c1,c2均为字符串，函数将c2连接到c1的后面，如果c1为null,将返回c2.如果c2为null,则返回c1，如果c1、c2都为null，则返回null。他和操作符||返回的结果相同</p>
<p>select concat('slobo ','Svoboda') username from dualusernameslobo Syoboda <br />
INITCAP()</p>
<p>c1为一字符串。函数将每个单词的第一个字母大写其它字母小写返回。单词由空格，控制字符，标点符号限制。</p>
<p>select INITCAP('veni,vedi,vici') Ceasar from dualCeasarVeni,Vedi,Vici </p>
<p><br />
INSTR(,[,[,]])</p>
<p>c1,c2均为字符串，i,j为整数。函数返回c2在c1中第j次出现的位置，搜索从c1的第i个字符开始。当没有发现需要的字符时返回0,如果i为负数，那么搜索将从右到左进行，但是位置的计算还是从左到右，i和j的缺省值为1。</p>
<p>select INSTR('Mississippi','i',3,3) from dualINSTR('MISSISSIPPI','I',3,3)11select INSTR('Mississippi','i',-2,3) from dualINSTR('MISSISSIPPI','I',3,3)2 </p>
<p><br />
INSTRB(,[,i[,j])</p>
<p>与INSTR()函数一样，只是他返回的是字节，对于单字节INSTRB()等于INSTR()。</p>
<p>LENGTH()</p>
<p>c1为字符串，返回c1的长度，如果c1为null，那么将返回null值。</p>
<p>select LENGTH('Ipso Facto') ergo from dualergo10 </p>
<p><br />
LENGTHb()</p>
<p>与LENGTH()一样，返回字节。</p>
<p>lower()</p>
<p>返回c的小写字符，经常出现在where子串中。</p>
<p>select LOWER(colorname) from itemdetail WHERE LOWER(colorname) LIKE '%white%'COLORNAMEWinterwhite </p>
<p><br />
LPAD(,[,])</p>
<p>c1,c2均为字符串，i为整数。在c1的左侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格，参见RPAD。</p>
<p>select LPAD(answer,7,'') padded,answer unpadded from question;PADDED UNPADDED Yes YesNO NOMaybe maybe </p>
<p><br />
LTRIM(,)</p>
<p>把c1中最左边的字符去掉，使其第一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
<p>select LTRIM('Mississippi','Mis') from dualLTRppi </p>
<p><br />
RPAD(,[,])</p>
<p>在c1的右侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格,其他与LPAD相似。</p>
<p>RTRIM(,)</p>
<p>把c1中最右边的字符去掉，使其第后一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
<p>REPLACE(,[,])</p>
<p>c1,c2,c3都是字符串，函数用c3代替出现在c1中的c2后返回。</p>
<p>select REPLACE('uptown','up','down') from dualREPLACEdowntown </p>
<p><br />
STBSTR(,[,])</p>
<p>c1为一字符串，i,j为整数，从c1的第i位开始返回长度为j的子字符串，如果j为空，则直到串的尾部。</p>
<p>select SUBSTR('Message',1,4) from dualSUBSMess </p>
<p><br />
SUBSTRB(,[,])</p>
<p>与SUBSTR大致相同，只是I,J是以字节计算。</p>
<p>SOUNDEX()</p>
<p>返回与c1发音相似的词。</p>
<p>select SOUNDEX('dawes') Dawes SOUNDEX('daws') Daws, SOUNDEX('dawson') from dualDawes Daws DawsonD200 D200 D250 </p>
<p><br />
TRANSLATE(,,)</p>
<p>将c1中与c2相同的字符以c3代替</p>
<p>select TRANSLATE('fumble','uf','ar') test from dualTEXTramble </p>
<p><br />
TRIM([[]] from c3)</p>
<p>将c3串中的第一个，最后一个，或者都删除。</p>
<p>select TRIM(' space padded ') trim from dual TRIMspace padded </p>
<p><br />
UPPER()</p>
<p>返回c1的大写，常出现where子串中</p>
<p>select name from dual where UPPER(name) LIKE 'KI%'NAMEKING </p>
<p><br />
4、单行数字函数</p>
<p>单行数字函数操作数字数据，执行数学和算术运算。所有函数都有数字参数并返回数字值。所有三角函数的操作数和值都是弧度而不是角度，oracle没有提供内建的弧度和角度的转换函数。</p>
<p>ABS()</p>
<p>返回n的绝对值</p>
<p>ACOS()</p>
<p>反余弦函数，返回-1到1之间的数。n表示弧度</p>
<p>select ACOS(-1) pi,ACOS(1) ZERO FROM dualPI ZERO3.14159265 0 </p>
<p><br />
ASIN()</p>
<p>反正弦函数，返回-1到1，n表示弧度</p>
<p>ATAN()</p>
<p>反正切函数，返回n的反正切值，n表示弧度。</p>
<p>CEIL()</p>
<p>返回大于或等于n的最小整数。</p>
<p>COS()</p>
<p>返回n的余玄值，n为弧度</p>
<p>COSH()</p>
<p>返回n的双曲余玄值，n 为数字。</p>
<p>select COSH(&lt;1.4&gt;) FROM dualCOSH(1.4)2.15089847 </p>
<p><br />
EXP()</p>
<p>返回e的n次幂，e=2.71828183.</p>
<p>FLOOR()</p>
<p>返回小于等于N的最大整数。</p>
<p>LN()</p>
<p>返回N的自然对数，N必须大于0</p>
<p>LOG(,)</p>
<p>返回以n1为底n2的对数</p>
<p>MOD()</p>
<p>返回n1除以n2的余数<br />
POWER(,)</p>
<p>返回n1的n2次方</p>
<p>ROUND(,)</p>
<p>返回舍入小数点右边n2位的n1的值，n2的缺省值为0，这回将小数点最接近的整数，如果n2为负数就舍入到小数点左边相应的位上，n2必须是整数。</p>
<p>select ROUND(12345,-2),ROUND(12345.54321,2) FROM dualROUND(12345,-2) ROUND(12345.54321,2)12300 12345.54 </p>
<p><br />
SIGN()</p>
<p>如果n为负数，返回-1,如果n为正数，返回1，如果n=0返回0</p>
<p>SIN()</p>
<p>返回n的正玄值,n为弧度。</p>
<p>SINH()</p>
<p>返回n的双曲正玄值,n为弧度。</p>
<p>SQRT()</p>
<p>返回n的平方根,n为弧度</p>
<p>TAN()</p>
<p>返回n的正切值,n为弧度</p>
<p>TANH()</p>
<p>返回n的双曲正切值,n为弧度</p>
<p>TRUNC(,)</p>
<p>返回截尾到n2位小数的n1的值，n2缺省设置为0，当n2为缺省设置时会将n1截尾为整数，如果n2为负值，就截尾在小数点左边相应的位上。</p>
<p>5、单行日期函数</p>
<p>单行日期函数操作DATA数据类型，绝大多数都有DATA数据类型的参数，绝大多数返回的也是DATA数据类型的值。</p>
<p>ADD_MONTHS(,)</p>
<p>返回日期d加上i个月后的结果。i可以使任意整数。如果i是一个小数，那么数据库将隐式的他转换成整数，将会截去小数点后面的部分。</p>
<p>LAST_DAY()</p>
<p>函数返回包含日期d的月份的最后一天</p>
<p>MONTHS_BETWEEN(,)</p>
<p>返回d1和d2之间月的数目,如果d1和d2的日的日期都相同，或者都使该月的最后一天，那么将返回一个整数，否则会返回的结果将包含一个分数。</p>
<p>NEW_TIME(,,)</p>
<p>d1是一个日期数据类型，当时区tz1中的日期和时间是d时，返回时区tz2中的日期和时间。tz1和tz2时字符串。</p>
<p>NEXT_DAY(,)</p>
<p>返回日期d后由dow给出的条件的第一天，dow使用当前会话中给出的语言指定了一周中的某一天，返回的时间分量与d的时间分量相同。</p>
<p>select NEXT_DAY('01-Jan-2000','Monday') "1st Monday",NEXT_DAY('01-Nov-2004','Tuesday')+7 "2nd Tuesday") from dual;1st Monday 2nd Tuesday03-Jan-2000 09-Nov-2004 </p>
<p><br />
ROUND([,])</p>
<p>将日期d按照fmt指定的格式舍入，fmt为字符串。</p>
<p>SYADATE</p>
<p>函数没有参数，返回当前日期和时间。</p>
<p>TRUNC([,])</p>
<p>返回由fmt指定的单位的日期d<br />
6、单行转换函数</p>
<p>单行转换函数用于操作多数据类型，在数据类型之间进行转换。</p>
<p>CHARTORWID()</p>
<p>c 使一个字符串，函数将c转换为RWID数据类型。</p>
<p>SELECT test_id from test_case where rowid=CHARTORWID('AAAA0SAACAAAALiAAA') </p>
<p><br />
CONVERT(,[,])</p>
<p>c尾字符串，dset、sset是两个字符集，函数将字符串c由sset字符集转换为dset字符集，sset的缺省设置为数据库的字符集。</p>
<p>HEXTORAW()</p>
<p>x为16进制的字符串，函数将16进制的x转换为RAW数据类型。</p>
<p>RAWTOHEX()</p>
<p>x是RAW数据类型字符串，函数将RAW数据类转换为16进制的数据类型。</p>
<p>ROWIDTOCHAR()</p>
<p>函数将ROWID数据类型转换为CHAR数据类型。</p>
<p>TO_CHAR([[,)</p>
<p>x是一个data或number数据类型，函数将x转换成fmt指定格式的char数据类型，如果x为日期nlsparm=NLS_DATE_LANGUAGE 控制返回的月份和日份所使用的语言。如果x为数字nlsparm=NLS_NUMERIC_CHARACTERS 用来指定小数位和千分位的分隔符，以及货币符号。</p>
<p>NLS_NUMERIC_CHARACTERS ="dg", NLS_CURRENCY="string" </p>
<p><br />
TO_DATE([,[,)</p>
<p>c表示字符串，fmt表示一种特殊格式的字符串。返回按照fmt格式显示的c,nlsparm表示使用的语言。函数将字符串c转换成date数据类型。</p>
<p>TO_MULTI_BYTE()</p>
<p>c表示一个字符串，函数将c的担子截字符转换成多字节字符。</p>
<p>TO_NUMBER([,[,)</p>
<p>c表示字符串，fmt表示一个特殊格式的字符串，函数返回值按照fmt指定的格式显示。nlsparm表示语言，函数将返回c代表的数字。</p>
<p>TO_SINGLE_BYTE()</p>
<p>将字符串c中得多字节字符转化成等价的单字节字符。该函数仅当数据库字符集同时包含单字节和多字节字符时才使用</p>
<p>7、其它单行函数</p>
<p>BFILENAME(,) </p>
<p><br />
dir是一个directory类型的对象，file为一文件名。函数返回一个空的BFILE位置值指示符，函数用于初始化BFILE变量或者是BFILE列。</p>
<p>DECODE(,,[,,,[])</p>
<p>x是一个表达式，m1是一个匹配表达式，x与m1比较，如果m1等于x，那么返回r1,否则,x与m2比较，依次类推m3,m4,m5....直到有返回结果。</p>
<p>DUMP(,[,[,[,]]])</p>
<p>x是一个表达式或字符，fmt表示8进制、10进制、16进制、或则单字符。函数返回包含了有关x的内部表示信息的VARCHAR2类型的值。如果指定了n1,n2那么从n1开始的长度为n2的字节将被返回。</p>
<p>EMPTY_BLOB()</p>
<p>该函数没有参数，函数返回 一个空的BLOB位置指示符。函数用于初始化一个BLOB变量或BLOB列。</p>
<p>EMPTY_CLOB()</p>
<p>该函数没有参数，函数返回 一个空的CLOB位置指示符。函数用于初始化一个CLOB变量或CLOB列。</p>
<p>GREATEST()</p>
<p>exp_list是一列表达式，返回其中最大的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，那么返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。<br />
LEAST()</p>
<p>exp_list是一列表达式，返回其中最小的表达式，每个表达式都被隐含的转换第一个表达式的数据类型，如果第一个表达式是字符串数据类型中的任何一个，将返回的结果是varchar2数据类型，同时使用的比较是非填充空格类型的比较。</p>
<p>UID</p>
<p>该函数没有参数，返回唯一标示当前数据库用户的整数。</p>
<p>USER</p>
<p>返回当前用户的用户名</p>
<p>USERENV()</p>
<p>基于opt返回包含当前会话信息。opt的可选值为：</p>
<p>ISDBA　 会话中SYSDBA脚色响应，返回TRUE</p>
<p>SESSIONID 　返回审计会话标示符</p>
<p>ENTRYID 返回可用的审计项标示符</p>
<p>INSTANCE在会话连接后，返回实例标示符。该值只用于运行Parallel 服务器并且有 多个实例的情况下使用。</p>
<p>LANGUAGE返回语言、地域、数据库设置的字符集。</p>
<p>LANG返回语言名称的ISO缩写。</p>
<p>TERMINAL为当前会话使用的终端或计算机返回操作系统的标示符。</p>
<p>VSIZE()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x是一个表达式。返回x内部表示的字节数。</p>
<p>二、SQL中的组函数</p>
<p>组函数也叫集合函数，返回基于多个行的单一结果，行的准确数量无法确定，除非查询被执行并且所有的结果都被包含在内。与单行函数不同的是，在解析时所有的行都是已知的。由于这种差别使组函数与单行函数有在要求和行为上有微小的差异.</p>
<p>1、组(多行)函数</p>
<p>与单行函数相比，oracle提供了丰富的基于组的，多行的函数。这些函数可以在select或select的having子句中使用，当用于select子串时常常都和GROUP BY一起使用。</p>
<p>AVG([{DISYINCT|ALL}])</p>
<p>返回数值的平均值。缺省设置为ALL</p>
<p>SELECT AVG(sal),AVG(ALL sal),AVG(DISTINCT sal) FROM scott.empAVG(SAL) AVG(ALL SAL) AVG(DISTINCT SAL)1877.94118 1877.94118 1916.071413 </p>
<p><br />
COUNT({*|DISTINCT|ALL} )</p>
<p>返回查询中行的数目，缺省设置是ALL,*表示返回所有的行。</p>
<p>MAX([{DISTINCT|ALL}])</p>
<p>返回选择列表项目的最大值，如果x是字符串数据类型，他返回一个VARCHAR2数据类型，如果X是一个DATA数据类型，返回一个日期，如果X是numeric数据类型，返回一个数字。注意distinct和all不起作用，应为最大值与这两种设置是相同的。</p>
<p>MIN([{DISTINCT|ALL}])</p>
<p>返回选择列表项目的最小值。</p>
<p>STDDEV([{DISTINCT|ALL}])</p>
<p>返回选者的列表项目的标准差，所谓标准差是方差的平方根。</p>
<p>SUM([{DISTINCT|ALL}])</p>
<p>返回选择列表项目的数值的总和。</p>
<p>VARIANCE([{DISTINCT|ALL}])</p>
<p>返回选择列表项目的统计方差。</p>
<p>2、用GROUP BY给数据分组</p>
<p>正如题目暗示的那样组函数就是操作那些已经分好组的数据，我们告诉数据库用GROUP BY怎样给数据分组或者分类，当我们在SELECT语句的SELECT子句中使用组函数时，我们必须把为分组或非常数列放置在GROUP BY子句中，如果没有用group by进行专门处理，那么缺省的分类是将整个结果设为一类。</p>
<p>select stat,counter(*) zip_count from zip_codes GROUP BY state;ST ZIP_COUNT-- ---------AK 360AL 1212AR 1309AZ 768CA 3982 </p>
<p><br />
在这个例子中，我们用state字段分类;如果我们要将结果按照zip_codes排序,可以用ORDER BY语句，ORDER BY子句可以使用列或组函数。</p>
<p>select stat,counter(*) zip_count from zip_codes GROUP BY state ORDER BY COUNT(*) DESC;ST COUNT(*)-- --------NY 4312PA 4297TX 4123CA 3982 </p>
<p><br />
3、用HAVING子句限制分组数据</p>
<p>现在你已经知道了在查询的SELECT语句和ORDER BY子句中使用主函数，组函数只能用于两个子串中，组函数不能用于WHERE子串中，例如下面的查询是错误的：</p>
<p>错误SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' AND SUM(sale_amount)&gt;10000 GROUP BY sales_clerk</p>
<p>这个语句中数据库不知道SUM()是什么，当我们需要指示数据库对行分组，然后限制分组后的行的输出时，正确的方法是使用HAVING语句：</p>
<p>SELECT sales_clerk,SUN(sale_amount) FROM gross_sales WHERE sales_dept='OUTSIDE' GROUP BY sales_clerkHAVING SUM(sale_amount)&gt;10000; </p>
<p><br />
4、嵌套函数</p>
<p>函数可以嵌套。一个函数的输出可以是另一个函数的输入。操作数有一个可继承的执行过程。但函数的优先权只是基于位置，函数遵循由内到外，由左到右的原则。嵌套技术一般用于象DECODE这样的能被用于逻辑判断语句IF....THEN...ELSE的函数。</p>
<p>嵌套函数可以包括在组函数中嵌套单行函数，或者组函数嵌套入单行函数或组函数中。比如下面的例子：</p>
<p>SELECT deptno, GREATEST(COUNT(DISTINCT job),COUNT(DISTINCT mgr) cnt,COUNT(DISTINCT job) jobs,COUNT(DISTINCT mgr) mgrsFROM empGROUP BY deptno;DEPTNO CNT JOBS MGRS------ --- ---- ----10 4 4 220 4 3 430 3 3 2 </p>
<p><br />
&nbsp;</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/167677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-14 10:02 <a href="http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 软件空间</title><link>http://www.blogjava.net/lifenote/archive/2007/12/14/167656.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 14 Dec 2007 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/14/167656.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/167656.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/14/167656.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/167656.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/167656.html</trackback:ping><description><![CDATA[<a href="http://web.99081.com/sysweb/RegTrans.aspx?CodeProvider=sunxian99">注册了一个网站，使用的是下面的这个空间，常来网，无限空间大小完全免费，上传速度很不错，感觉挺好推荐给大家，来注册一个空间上传资料使用<br />
http://web.99081.com/sysweb/RegTrans.aspx?CodeProvider=sunxian99</a><br />
  <img src ="http://www.blogjava.net/lifenote/aggbug/167656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-14 09:23 <a href="http://www.blogjava.net/lifenote/archive/2007/12/14/167656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tapestry 开发笔记（积累）</title><link>http://www.blogjava.net/lifenote/archive/2007/12/13/167528.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 13 Dec 2007 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/13/167528.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/167528.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/13/167528.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/167528.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/167528.html</trackback:ping><description><![CDATA[<p>====================================================================================<br />
'&nbsp;说明：Tapestry 开发笔记<br />
'&nbsp;Note Author:&nbsp;Sunxianchao<br />
'&nbsp;阅读日期：&nbsp;2007-9-18(北京.七彩谷)<br />
'====================================================================================<br />
<br />
<br />
<br />
'先做个小广告 免费的无限空间还可以就是要积分 下面是我的注册地址 直接注册就可以了 奖励10个积分<br />
http://web.99081.com/sysweb/RegTrans.aspx?CodeProvider=sunxian99<br />
麻烦帮忙顶一个 多谢<br />
<br />
<br />
【各种组建使用】<br />
说明：只是说明一些需要注意的东西，更多的学习参考Tapestry官方文档<br />
1、For<br />
source:是对应的java类里的List 对象或者是个数组 需要抽象 或者提供set get方法<br />
value:是循环这个source对象代表当前的一个 ，需要在page文件中设置问一个属性，可以不在对应的java类里有这个属性<br />
index:是循环的索引值 同value一样 在page文件中设置一个属性即可 &lt;property name="index"/&gt;<br />
在循环的时候 会自动为vlaue和index赋当前的值</p>
<p>2、Foreach 和For一样使用</p>
<p>3、Hidden组件 总是多余S的处理<br />
&nbsp;&lt;input jwcid="@Hidden" type="hidden" value="ognl:blahblah" encode="false"/&gt;</p>
<p><br />
4、 Insert 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" jwcid="name@Insert" value="ognl:user.name"/&gt; <br />
&nbsp;&nbsp;&nbsp; 页面表现时,将会到页面类中寻找getUser().getName()方法获取初值并输出 <br />
&nbsp;&nbsp;&nbsp; 相当于在页面上显示数据.</p>
<p>5、 TextField 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;input type="text" jwcid="username@TextField" value="ognl:username"/&gt; <br />
&nbsp;&nbsp;&nbsp; 页面表现时,将会到页面类中寻找getUsername()方法获取初值 <br />
&nbsp;&nbsp;&nbsp; *如果是修改信息页面,通常初始值要在页面表现之前由setUsername()手动设置从数据库中读取出来的值 <br />
&nbsp;&nbsp;&nbsp; 表单提交时,通过setUsername()写入新值(即用户输入值),在类中通过getUsername()获取新值 <br />
&nbsp;&nbsp;&nbsp; 相当于在修改个人信息时,首先读出用户名赋予文本框(用户名)初值,用户修改时填入新值,后台获取之 <br />
&nbsp;&nbsp;&nbsp; *Hidden属性区分是普通文本输入框(默认false)和密码输入框(hidden="ognl:true") <br />
&nbsp;&nbsp;&nbsp; readonly属性设置只读 readonly="true"为只读(后台可读取) <br />
&nbsp;&nbsp;&nbsp; *disabled属性设置是否可写 diabled="true"为不可写(后台也不可读取)</p>
<p>6、 TextArea 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;textarea jwcid="content@TextArea" value="ognl:content" cols="40" rows="10"&gt;&lt;/textarea&gt; <br />
&nbsp;&nbsp;&nbsp; 页面表现时,将会到页面类中寻找getContent()方法获取初值 <br />
&nbsp;&nbsp;&nbsp; 工作原理同TextField</p>
<p>7、 RadioGroup/Radio 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="headImage@RadioGroup" selected="ognl:headImage"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="1"/&gt;头像1 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="2"/&gt;头像2 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="3"/&gt;头像3 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="4"/&gt;头像4 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="5"/&gt;头像5 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input jwcid="@Radio" type="radio" value="6"/&gt;头像6 <br />
&nbsp;&nbsp;&nbsp; &lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; RadioGroup为每一个Radio提供一个唯一的ID。RadioGroup跟踪当前被选中的属性值，并且只有一个Radio能够被选中. <br />
&nbsp;&nbsp;&nbsp; 页面提交时，RadioGroup组件就利用OGNL表达式向headImage字段写入被选中的Radio组件的value参数值. <br />
&nbsp;&nbsp;&nbsp; 页面表现时(修改页面),将会到页面类中寻找getHeadImage()方法获取初值,然后寻找@Radio组件中与其相同的组件并勾选上.</p>
<p>8、 PropertySelection 组件 <br />
&nbsp;&nbsp;&nbsp; 使用PropertySelection组件必须要构造一个类来实现IPropertySelectionModel接口，并且重写该接口的5个方法. <br />
&nbsp;&nbsp;&nbsp; public int getOptionCount() //提供下拉菜单的长度 <br />
&nbsp;&nbsp;&nbsp; public Object getOption(int index) //提供select标签的option <br />
&nbsp;&nbsp;&nbsp; public String getLabel(int index) //提供select标签的Label值，也就是下拉菜单显示的内容 <br />
&nbsp;&nbsp;&nbsp; public String getValue(int index) //提供select标签的value值 <br />
&nbsp;&nbsp;&nbsp; public Object translateValue(String value) //selected后的返回值，value值未必就是我们需要的返回值，可以在这个方法里面对返回的value做对应的转换或修改. <br />
e.g.1. 性别下拉框 <br />
&nbsp;&nbsp;&nbsp; &lt;select jwcid="gender@ProPertySelection" name="genderSelect" value="ognl:gender" model="supportedGender"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option selected&gt;先生&lt;/option&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&gt;女士&lt;/option&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/select&gt; </p>
<p><br />
代码<br />
GenderSelectionModel.java&nbsp;&nbsp; <br />
public class GenderSelectionModel implements IPropertySelectionModel {&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public static final String male = "先生";&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public static final String female = "女士";&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public static final String[] genderOptions = { male, female };&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public int getOptionCount() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return genderOptions.length;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Object getOption(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.translateValue(genderOptions[index]);&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getLabel(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return genderOptions[index].toString();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getValue(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return genderOptions[index];&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Object translateValue(String value) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (value.equals("先生")) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "1";&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "0";&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; </p>
<p>&nbsp;</p>
<p>代码<br />
ModUserInfo.java&nbsp;&nbsp; <br />
public IPropertySelectionModel getSupportedGender() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; return new GenderSelectionModel();&nbsp;&nbsp; <br />
}&nbsp; </p>
<p><br />
&nbsp;&nbsp;&nbsp; 存入数据库中"1"代表先生,"0"代表女士,通过translateValue(String value)方法转换 <br />
&nbsp;&nbsp;&nbsp; 页面表现时,通过model属性给出的IPropertySelectionModel获取下拉选项,即getSupportedGender(). <br />
&nbsp;&nbsp;&nbsp; 然后通过getGender()方法获取初值,比如获取"0",则在页面显示时寻找value值为"0"的选项即为"女士",并选择之作为初始选择项.</p>
<p>e.g.2. 日志类型下拉框 <br />
&nbsp;&nbsp;&nbsp; &lt;select jwcid="logType@PropertySelection" name="typeSelect" value="ognl:logType" model="supportedType"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&gt;心情日记&lt;/option&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&gt;情感天地&lt;/option&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&gt;生活感触&lt;/option&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/select&gt; </p>
<p><br />
代码<br />
TypeSelectionModel.java&nbsp;&nbsp; <br />
public class TypeSelectionModel implements IPropertySelectionModel {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private List typeList = new ArrayList();&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public TypeSelectionModel(List typeList) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.typeList = typeList;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public int getOptionCount() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return typeList.size();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Object getOption(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ((LogType)typeList.get(index)).getValue();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getLabel(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ((LogType) typeList.get(index)).getName();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public String getValue(int index) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ((LogType) typeList.get(index)).getValue();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Object translateValue(String value) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; <br />
}&nbsp; </p>
<p>&nbsp;</p>
<p>代码<br />
ModLog.java&nbsp;&nbsp; <br />
public IPropertySelectionModel getSupportedType() {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; TypeSelectionModel typeSelectionModel =&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new TypeSelectionModel(loadType(getUser().getUserId()));&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; return typeSelectionModel;&nbsp;&nbsp; <br />
}&nbsp;&nbsp; <br />
&nbsp; <br />
private List loadType(int userid) {&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ...//从数据库载入该用户的日志类型列表&nbsp;&nbsp; <br />
}&nbsp; </p>
<p><br />
&nbsp;&nbsp;&nbsp; 页面表现时,通过model属性给出的IPropertySelectionModel获取下拉选项,即getSupportedType(). <br />
&nbsp;&nbsp;&nbsp; 然后通过value属性给出的初始值即,getLogType()方法获取初值,比如获取"2",则在页面显示时寻找value值为"2"的选项即为"生活感触",并选择之作为初始选择项.</p>
<p>9、 Form组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;form jwcid="logForm@Form"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... <br />
&nbsp;&nbsp;&nbsp; &lt;/form&gt; <br />
&nbsp;&nbsp;&nbsp; Form的监听(listener)方法可以有两种方式: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 在Form组件中声明. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;form jwcid="logForm@Form" listener="ognl:listener:onLogin"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/form&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. 在submit类型组件中声明. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;input type="submit" jwcid="onLogin@Submit" listener="listener:onLogin" value="发表"/&gt;或者 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;span jwcid="@ImageSubmit" image="..." listener="listener:onLogin"&gt;&lt;img src="..." width="" height=""/&gt;&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 前一种方式当Form中只要有submit就会触发监听方法,后一种方式是Form中有多个submit,各自实现不同的监听方法.</p>
<p>G) Foreach 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@Foreach" source="ognl:logList" value="ognl:item"&gt; <br />
&nbsp;&nbsp;&nbsp; 循环组件,遍历source参数,在表现其内容前更新value参数,将Foreach组件所包含的内容重复表现,其中可以通过value参数获取所需显示内容. <br />
&nbsp;&nbsp;&nbsp; 本例中,页面表现时通过getLogList()方法获取日志列表,循环取出其中数据更新item(日志对象)并予以显示.其中item需要在页面规范(.page)文件中声明: <br />
&nbsp;&nbsp;&nbsp; &lt;property name="item"/&gt; <br />
&nbsp;&nbsp;&nbsp; *class参数用来寻找类似CSS的文件对Foreach进行修饰. <br />
&nbsp;&nbsp;&nbsp; Foreach组件: class="ognl:beans.evenOdd.next" <br />
&nbsp;&nbsp;&nbsp; Page文件: &lt;bean name="evenOdd" class="org.apache.tapestry.bean.EvenOdd"/&gt; <br />
&nbsp;&nbsp;&nbsp; CSS文件: tr.odd{background-color: #ffffff;}tr.even{background-color: #eeeeee;}</p>
<p>10、 Conditional 组件 <br />
e.g. <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@Conditional" condition='ognl:item.sex.equals("1")'&gt;先生&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@Conditional" condition='ognl:item.sex.equals("0")'&gt;女士&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; conditional参数为true时运行Conditional组件中的HTML模板内容. <br />
&nbsp;&nbsp;&nbsp; 在Tapestry4.0以后就不支持该组件了, 可以使用其他组件来实现: <br />
&nbsp;&nbsp;&nbsp; 1. Contrib:Choose和Contrib:When <br />
&nbsp;&nbsp;&nbsp; &lt;library id="contrib" specification-path="classpath:/org/apache/tapestry/contrib/Contrib.library"/&gt;(.application文件中引入Contrib类包) <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@contrib:Choose"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;span jwcid="@contrib:When" condition='ognl:user.gender.equals("1")'&gt;先生&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;span jwcid="@contrib:When" condition='ognl:user.gender.equals("0")'&gt;女士&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; 2. If组件 <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@If" condition='ognl:item.sex.equals("1")'&gt;先生&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@If" condition='ognl:item.sex.equals("0")'&gt;女士&lt;/span&gt; <br />
&nbsp;&nbsp;&nbsp; 3. Else组件<br />
&nbsp;&nbsp;&nbsp; &lt;span jwcid="@Else"&gt;man&lt;/span&gt; </p>
<p>【============================ts的函数执行顺序========================================】<br />
对之前的该文章进行了一些修正，主要是针对finishLoad()方法。 <br />
我觉得对初学者会有一些帮助。 <br />
下面这几个函数是我在使用的，它们的执行顺序依次从上到下。 <br />
1.protected void finishLoad() {} *** <br />
2.public void pageValidate(PageEvent event) {} <br />
3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {} <br />
4.public void pageBeginRender(PageEvent event) {} <br />
// 如果有表单提交，则将form中的各字段的值赋给页面类 <br />
5. ...... 赋值 <br />
6.public void submit() // 表单提交等用listenter:调用的方法 <br />
7.protected void prepareForRender(IRequestCycle cycle) {} <br />
---------------------------------------------------- <br />
1.protected void finishLoad() {} <br />
这个函数最先执行，但是它实际上没有什么用处（我感觉）。因为： <br />
　　这个函数只在页面池中没有某一个页面类、需要生成一个新的页面对象时才调用。这里就有一个陷阱：如果你的tomcat启动时使用了-Dorg.apache.tapestry.disable-caching=true(为了调试方便而设)，那么你每次刷新页面时，它都会执行（因为每个request都会新生成一个页面类对象），造成了它总是执行的假象。在实际的部署时，会使用caching，则这个函数执行的机会很少。所以要注意。 <br />
　　初始化的代码放在4 pageBeginRender()中 <br />
2.public void pageValidate(PageEvent event) {} <br />
如果实现了PageValidateListener接口，则可以在这里进行验证，比如访问权限等。执行完1后，它就开始执行。 <br />
3.public void activateExternalPage(Object[] parameters, IRequestCycle cycle) {} <br />
如果实现了IExternalPage接口，则可以从这里取得由外面传过来的参数。执行2后，执行到这里。在这里可以把那些参数取出，赋给页面类。 <br />
4.public void pageBeginRender(PageEvent event) {} <br />
执行完3后，将执行本函数。但是这时从客户端传过来的参数还没有被赋值(如果提交了表单的话)。这里可以进行一些初始化操作。 <br />
5.执行完4后，如果有表单提交，在这里将会取出那些值，赋给对应的字段。(注意：只是将表单中有的值赋过来) <br />
6.public void submit() <br />
如果有表单提交的话，在这里将进行对应的操作。因为此时各字段已经取好值了，所以可以拿来直接用。 <br />
7.protected void prepareForRender(IRequestCycle cycle) {} <br />
最后才执行这个方法。我们可以在其中进行为了在页面上显示数据而进行的操作，比如取得什么对象什么的，因为这里页面类的属性赋值已经结束，可以直接拿来使用了。 <br />
注意：如果执行了6，则还要执行4，再执行7。如果没有6，4完了就直接是7。 <br />
以上是我所总结的执行顺序，不当之处请指出。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>----------------------------------------------------- <br />
最开始学tapestry的时候，觉得&#8220;怎么有这么多地方需要持久啊&#8221;。原来以前只知道pageBeginRender这个函数，什么初始化操作都放在它里面。可是它是在赋值之前执行，所以拿到的字段多都是空的，却都以为是没有持久化的缘故。所以在客户端里放了一大堆的@Hidden，或者session中持久，非常麻烦，，，对tapestry也产生的怀疑。现在才知道那些需要取得客户端传来的参数的代码，最好放在prepareForRender里，很多不必要的持久都可以省掉了</p>
 <img src ="http://www.blogjava.net/lifenote/aggbug/167528.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-13 16:21 <a href="http://www.blogjava.net/lifenote/archive/2007/12/13/167528.html#Feedback" target="_blank" style