﻿<?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>C++博客-brent's hut-随笔分类-Java</title><link>http://www.cppblog.com/aqazero/category/2881.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 11:57:31 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 11:57:31 GMT</pubDate><ttl>60</ttl><item><title>CLASSPATH杂记</title><link>http://www.cppblog.com/aqazero/archive/2005/12/19/14209.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Mon, 19 Dec 2005 01:25:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/12/19/14209.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14209.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/12/19/14209.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14209.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14209.html</trackback:ping><description><![CDATA[
		<img height="1" src="http://www.cnitblog.com/Raistlin/aggbug/5576.html" width="1" />
		<br />
		<p>本来java虚拟机是这么运行的<br />D:\java -classpath D:\hibernate-3.0\eg org.hibernate.auction.Main </p>
		<p>这个命令行将告诉java虚拟机的类装载器从D:\hibernate-3.0\eg\org\hibernate\auction处装载Main.class。<br />如果省略"-classpath D:\hibernate-3.0\eg"，即D:\java org.hibernate.auction.Main 则类装载器将会从系统环境变量CLASSPATH指定的位置寻找符合条件的Main.class。</p>
		<p>
				<br />如果CLASSPATH为.;D:\jdk150\lib\tools.jar;D:\jdk150\jre\lib\rt.jar;D:\hibernate-3.0\eg<br />则类装载器先查找当前运行目录(.表示当前目录)，此处为D:\，如果D:\下面有D:\org\hibernate\auction\Main.class，则装载这个文件。如果没有，继续在D:\jdk150\lib\tools.jar文件中寻找是否有路径为org\hibernate\auction\Main.class的文件,如果没有则寻找D:\hibernate-3.0\eg\org\hibernate\auction\Main.class。如果在这些路径中都没找到，就会提示一个鸟错误。注意D:\hibernate-3.0\eg只表示将在此路径下寻找D:\hibernate-3.0\eg\org\hibernate\auction\Main.class文件，不会在此路径下的.jar文件中继续寻找。</p>
		<p>
				<br />据说很多开发环境往往不去读系统路径，直接就java -classpath .....，这也就是在外面运行的东东挺溜的进了开发环境就死菜的原因喽。</p>
<img src ="http://www.cppblog.com/aqazero/aggbug/14209.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-12-19 09:25 <a href="http://www.cppblog.com/aqazero/archive/2005/12/19/14209.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Hibernate的记录</title><link>http://www.cppblog.com/aqazero/archive/2005/12/19/14210.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Mon, 19 Dec 2005 01:23:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/12/19/14210.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14210.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/12/19/14210.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14210.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14210.html</trackback:ping><description><![CDATA[
		<strong>我和hibernate的第一次亲密：<br /><br /></strong>我用的数据库是mssql，用middlegen稀里哗啦生成一堆文件。编译运行，hibernate报告一堆异常，大概是说，MSSQL JDBC抗议说他不能读取已经读过的字段，所以hibernate不能生成需要的collection。最后icepeak传给我一个JSQLConnect，终于把这个问题解决了。<br /><br /><strong>设置hibernate生成定制的主键ID</strong>：<br /><p>在和hibernate亲密接触之后,我想按照自己的想法来设计组织机构.对于Organ,Department,Post和Stuff.我希望这样设计主键的ID,类型都是char,格式为:<br />Organ0000000001<br />Dept0000000001<br />Post0000000001<br />Stuff0000000002</p><p>修改middlegen产生的.hbm.xml文件:</p><p>......<br />&lt;class<br />    name="com.abcdefg.hibernate.Organ"<br />    table="Organ"<br />&gt;<br />    &lt;id<br />        name="organId"<br />        type="java.lang.String"<br />        column="OrganId"<br />    &gt;<br />        &lt;generator class="hbtest.PkGenerator"&gt;<br />            &lt;param name="table"&gt;PKGenerator_table&lt;/param&gt;<br />            &lt;param name="column"&gt;NextOrganId&lt;/param&gt;<br />            &lt;param name="max_lo"&gt;0&lt;/param&gt;<br /> &lt;/generator&gt;<br />    &lt;/id&gt;<br />......<br />&lt;/class&gt;</p><p>找到的资料说:"如果需要采用定制的主键产生算法，则在此处配置主键生成器，主键生成器必须实现net.sf.hibernate.id.IdentifierGenerator 接口".我找了半天都没找到net.sf.hibernate.id.IdentifierGenerator.其实只要从hibernate自身提供的一些主键生成器继承就可以,从hibernate的源文件可以看到这些主键生成器实现的接口是org.hibernate.id</p><p>我的PkGenerator.java文件:<br />package hbtest;</p><p>import org.hibernate.id.TableHiLoGenerator;<br />import java.io.Serializable;<br />import java.util.Properties;</p><p>import org.apache.commons.logging.Log;<br />import org.apache.commons.logging.LogFactory;<br />import org.hibernate.HibernateException;<br />import org.hibernate.dialect.Dialect;<br />import org.hibernate.engine.SessionImplementor;<br />import org.hibernate.type.Type;<br />import org.hibernate.type.IntegerType;<br />import org.hibernate.util.PropertiesHelper;</p><p>public class PkGenerator<br />    extends TableHiLoGenerator {</p><p>  private String columnName;</p><p>  public void configure(Type type, Properties params, Dialect d) {<br />    super.configure(new IntegerType(), params, d);<br />    this.columnName = PropertiesHelper.getString(COLUMN, params,<br />                                                 DEFAULT_COLUMN_NAME);<br />  }</p><p>  public synchronized Serializable generate(SessionImplementor session,<br />                                            Object obj) throws<br />      HibernateException {<br />    Object result = super.generate(session, obj);<br />    String strNumber = result.toString();<br />    StringBuffer strResult = new StringBuffer("");<br />    if (columnName.compareToIgnoreCase("NextOrganId") == 0) {<br />      strResult.append("Organ");<br />    }<br />    else if(columnName.compareToIgnoreCase("NextDeptId") == 0){<br />      strResult.append("Dept");<br />    }<br />    ......</p><p>    if (strNumber.length() &gt; 10)<br />      throw new HibernateException("The generated " + strResult +<br />                                   "Id is too long!");<br />    else if (strNumber.length() == 10) {<br />      strResult.append(strNumber);<br />    }<br />    else {<br />        int count = 10 - strNumber.length();<br />        while (count &gt; 0) {<br />        strResult.append("0");<br />        count--;<br />      }<br />      strResult.append(strNumber);<br />    }<br />    return strResult.toString();<br />  }<br />}</p><p>实现了以后发现在这些主键前面添加"Organ","Dept"之类的并不是特别有用,而且我开始的出发点还是错的.也许我应该建立更多的映射表...?</p><p><a href="http://www.cnitblog.com/Files/Raistlin/lifeapplet.rar" rel="nofollow"><font color="#003399">Hibernate的初级指南<br /></font></a><br /><strong>hibernate贴心的地方</strong>：<br /></p><div>验证了一下，我的担心终于被证实是多余的了，我担心的是hibernate会为同一条记录产生一堆不同的对象。</div><div>我觉得使hibernate真正实用的条件：为同一条记录产生的多个对象是同一个对象。当然前提是设置了主键。</div><div>hibernate也许是将当前读出的对象保存在一个哈希表，在读一个新对象的时候会先从这个哈希表中查找。好像这并不是多困难的事情。</div><div> </div><div>但多线程情况下就有所不同了..</div><div>因为Hibernate说(对于Session)：</div><div>It is not intended that implementors be threadsafe. Instead each thread/transaction should obtain its own instance from a SessionFactory</div><div> </div><div>Session并没有要求是线程安全的，而通过实验表明记录和对象的一一对应只存在于同一个Session中。这也是hibernate的文档中HibernateUtil类使用ThreadLocal的原因吧。</div><div>所以对于多线程的情况，在不同的线程中，对应同一条记录的对象是不同的。<br /><br />(另hibernate有二级缓存，是全局的缓存，可以用来减少数据库负载，二级缓存的功能需要设置才会启用)<br /><br /><strong>Hibernate中修改多对多关系的属性：</strong><br /><p>&lt;middlegen&gt;项中有如下&lt;table&gt;配置:<br />   &lt;table generate="true" name="Post"/&gt;<br />   &lt;table generate="true" name="Stuff"/&gt;<br />   &lt;many2many&gt;<br />      &lt;tablea generate="true" name="Post" /&gt; <br />      &lt;jointable name="PostStuff" generate="true" /&gt; <br />      &lt;tableb generate="true" name="Stuff" /&gt; <br />   &lt;/many2many&gt;<br />即表Post与Stuff的关系是多对多，而且表PostStuff中一个字段时JoinDate:员工加入部门的时间。</p><p>我现在想加入一条Post记录，一条Stuff记录，然后设置Stuff加入Post的时间。经过多次尝试，代码如下：<br />   ...<br />   Dept dept = ....<br />   Post post = new Post("third post1",dept,new HashSet(),new HashSet());<br />   Stuff stuff = new Stuff("third stuff",new HashSet(),new HashSet());<br />   session.save(stuff);<br />   session.save(post);<br />   post.getStuffs().add(stuff);<br />   //stuff.getPosts().add(post);/*不能与上一行并存，会有异常，因为是一个死循环？*/<br />   PostStuff postStuff = (PostStuff)session.createQuery("from PostStuff where PostId = '" + post.getPostId() + "' AND StuffId = '" + stuff.getStuffId() + "'").iterate().next();<br />   postStuff.setJoinDate(new java.util.Date());<br />   tx.commit();<br />   HibernateUtil.closeSession();<br />   ...</p><p>post.getStuffs().add(stuff);在两个Save()之后，而且没有调用session.flush()，但是createQuery能够得到PostStuff说明HQL是先从内存中查询数据的。不需要调用session.flush()来写入数据库，因为tx.commit()会自动调用。</p><p>可以用session.persist(stuff)来替换session.save(stuff)，我晕，明明save有说明会创建id，而persist没有说明会创建id的(但实际上是创建了)。</p><p>试图用以下替代post.getStuffs().add(stuff):<br />   PostStuff postStuff = new PostStuff();<br />   postStuff.setPost(post);<br />   postStuff.setStuff(stuff);<br />   postStuff.setJoinDate(new java.util.Date());<br />   postStuff.setComp_id(new PostStuffPK(post.getPostId(),stuff.getStuffId()));<br />   post.getPostStuffs().add(postStuff);<br />结果是虽然没有异常，但并不会添加一条关系。</p><p>或者</p><p>   session.flush();<br />   session.refresh(stuff);<br />   ((PostStuff)(stuff.getPostStuffs().iterator().next())).setJoinDate(new java.util.Date());<br />注意这些代码只是用来作试验用的</p></div><img src ="http://www.cppblog.com/aqazero/aggbug/14210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-12-19 09:23 <a href="http://www.cppblog.com/aqazero/archive/2005/12/19/14210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate启动过慢的问题以及我的批处理</title><link>http://www.cppblog.com/aqazero/archive/2005/12/19/14212.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Mon, 19 Dec 2005 00:43:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/12/19/14212.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14212.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/12/19/14212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14212.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14212.html</trackback:ping><description><![CDATA[
		<p>icepeak:<br /> hibernate肯定没什么问题的 <br /> 我也遇到启动很慢的情况，都是我的问题 <br /> 你把你的映射文件发给我看看<br />icepeak:<br /> &lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "<a href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</a>" &gt;<br /> 你用h3，但是却写h2的配置文件，h就傻了 把2变成3就好 <br />icepeak:<br /> 我想你得不到id也许和映射文档有问题也有关系 <br /> 什么都不用改，就用identity，再试试看 <br /> 我觉得是映射文件配置错误导致了不能读取 <br /> 就是2.0和3.0的错误 <br /> <br />So...问题解决了.</p>
		<p>俺用了三个批处理来自动生成hibernate的文件。<br /> <br />execant.bat:<br />d:<br />cd D:\hibernate-3.0\middlegen-2.1\samples\<br />rem 打开build.xml修改middlegen配置<br />editplus.exe build.xml<br />ant<br /> <br />myant.bat:<br />call execant.bat<br />pause<br />rem 复制hbm和java文件到工程目录<br />xcopy .\build\gen-src\com\glacierbbs\hibernate\*.java E:\eclipse\workspace\JGlacier\src\com\glacierbbs\hibernate\ /Y /D<br />xcopy .\build\gen-src\com\glacierbbs\hibernate\*.xml E:\eclipse\workspace\JGlacier\src\ /Y /D<br />rem 替换掉hbm中的字符串<br />call E:\eclipse\workspace\JGlacier\cutter.bat<br />pause<br /> <br />cutter.bat:<br />e:<br />cd E:\eclipse\workspace\JGlacier\src<br />dir *.xml /d /b /a-d &gt;hbmfiles.txt<br />rem 将版本2.0改成3.0<br />for /f %%i in (hbmfiles.txt) do strrpc /s:%%i 2.0 3.0 /c<br />rem 将hi/lo的max_lo由100改成0...我只需要简单的数字<br />for /f %%i in (hbmfiles.txt) do strrpc /s:%%i 100 0 /c<br />del hbmfiles.txt&gt;nul<br />rem 所有hi/lo算法读的是同一个表中的不同字段<br />strrpc /s:Board.hbm.xml next_value next_boardid /c<br />strrpc /s:Post.hbm.xml next_value next_postid /c<br />strrpc /s:Topic.hbm.xml next_value next_topicid /c<br />strrpc /s:UserBasic.hbm.xml next_value next_userid /c<br />strrpc /s:Vote.hbm.xml next_value next_voteid /c<br />strrpc /s:VoteOption.hbm.xml next_value next_voteoptionid /c<br />strrpc /s:VoteParticipant.hbm.xml next_value next_voteparticipantid /c<br />cd ..<br />pause<br /> <br />然后，为每个hibernate生成的java类写个Adapter类...从此世界就安静了.... </p>
<img src ="http://www.cppblog.com/aqazero/aggbug/14212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-12-19 08:43 <a href="http://www.cppblog.com/aqazero/archive/2005/12/19/14212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat jsp errorpage记录</title><link>http://www.cppblog.com/aqazero/archive/2005/12/19/14224.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Mon, 19 Dec 2005 00:39:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/12/19/14224.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14224.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/12/19/14224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14224.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14224.html</trackback:ping><description><![CDATA[
		<p>直接设置Tomcat路径到当前项目路径(虚拟路径):<br />D:\Tomcat55\conf\Catalina\localhost\GlacierBBS.xml:<br />&lt;Context docBase="E:/eclipse/GlacierBBS/GlacierBBS" path="GlacierBBS"<br />         privileged="true" antiResourceLocking="false" antiJARLocking="false" reloadable="true"&gt;<br />&lt;/Context&gt;<br /><br />Eclipse + WTP (web tools platform) 很强...<br />jsp文件和servlet类文件的编码方式<br />和在jsp和servlet中指定(response.setCharacterEncoding("UTF-8");)的编码方式的不同。<br />一个是文件内部的编码，另一个是把文件内部编码发送到客户端后，客户端以什么编码方式来阅读。jsp和servlet生成客户端html的时候，并不会自动进行编码的转换。</p>
		<p>errorpage路径设置错误产生异常:<br />java.lang.NullPointerException<br />org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:690)<br />org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:657)<br />org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:805)<br />org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:778)<br />org.apache.jsp.index_jsp._jspSer...</p>
		<p>从文件路径错误到NullPointerException...需要很强的想象力<br /><br />书籍memo:《Tomcat 与 Java Web 开发技术详解》</p>
<img src ="http://www.cppblog.com/aqazero/aggbug/14224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-12-19 08:39 <a href="http://www.cppblog.com/aqazero/archive/2005/12/19/14224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>菜鸟学用middlegen</title><link>http://www.cppblog.com/aqazero/archive/2005/09/14/14213.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Wed, 14 Sep 2005 03:25:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/09/14/14213.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14213.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/09/14/14213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14213.html</trackback:ping><description><![CDATA[
		<div>俺是java和hibernate和ant的绝对的三料菜鸟。hibernate似乎很好用，但是写表对应的类和.hbm.xml文件实在头大。所以俺想找一款可以自动生成这些文件的工具。</div>
		<div>
				<br />俺找到了middlegen。它的主页地址是<a href="http://boss.bekk.no/boss/middlegen/index.html"><font color="#003399">http://boss.bekk.no/boss/middlegen/index.html</font></a>。我google了一些中文网页，提供的地址没有一个不失效的。-_-。光有middlegen还不够，因为它使用ant来配置它的build。它的一个bulid生成的东西就是一堆的你可以用的.java,.hbm.xml,.class,.war文件。真是够贴心的。可是俺觉得它的配置可是一点都不贴心。</div>
		<div>
				<br />你要是没有ant，请先下载ant。俺一直打不开官方的地址，所以从pchome下载<a href="http://dlfjgwbn.pchome.net:8080/development/java/apacheant161.zip"><font color="#003399">http://dlfjgwbn.pchome.net:8080/development/java/apacheant161.zip</font></a>。解压文件后就可以用了，但等等，你需要安装了jdk，设置了CLASSPATH，JAVA_HOME。然后把ant的目录下的bin文件夹添加到path环境变量，设置ANT_HOME。<br />我的机器上的设置：<br />CLASSPATH .;D:\jdk150\lib\tools.jar;D:\jdk150\jre\lib\rt.jar<br />JAVA_HOME D:\jdk150<br />Path  D:\apache-ant-1.6.1\bin;<br />ANT_HOME D:\apache-ant-1.6.1</div>
		<div> </div>
		<div>然后下载并解压middlegen。我解压到了D:\hibernate-3.0\middlegen-2.1。好了，现在可以开始build hibernate需要的文件了，有个D:\hibernate-3.0\middlegen-2.1samples的文件夹，它存放了一个build的例子，我决定修改这个例子然后使用。</div>
		<div> </div>
		<div>但是再等等。middlegen需要你提供一些必要的配置。它需要连接到你的数据库，所以你需要给它提供数据库的连接信息和驱动库。各种数据库的配置信息在目录D:\hibernate-3.0\middlegen-2.1\samples\config\database 下面。俺的数据库是mssql，所以俺打开了mssql.xml文件，配置了信息如下：</div>
		<div>   &lt;property name="database.script.file"           value=""/&gt;<br />   &lt;property name="database.driver.file"           value="${lib.dir}/mssqlserver.jar"/&gt;<br />   &lt;property name="database.driver"                value="com.microsoft.jdbc.sqlserver.SQLServerDriver"/&gt;<br />   &lt;property name="database.url"                   value="jdbc:microsoft:sqlserver://localhost:1433"/&gt;<br />   &lt;property name="database.userid"                value="sa"/&gt;<br />   &lt;property name="database.password"              value="haha"/&gt;<br />   &lt;property name="database.schema"                value="dbo"/&gt;<br />   &lt;property name="database.catalog"               value="aljoin_info"/&gt;<br />   &lt;property name="jboss.datasource.mapping"       value="MS SQLSERVER"/&gt;</div>
		<div>aljoin_info是俺的数据库名称。并把msbase.jar，mssqlserver.jar，msutil.jar拷贝到D:\hibernate-3.0\middlegen-2.1\samples\lib目录。</div>
		<div>然后编辑D:\hibernate-3.0\middlegen-2.1\samples\build.xml文件，将"ENTITY database SYSTEM"的值改成"file:./config/database/mssql.xml"</div>
		<div> </div>
		<div>更改这个build的其它属性。build.xml中更改project的属性:<br />&lt;project name="Middlegen aljoni_info" default="hbm2java" basedir="."&gt;<br /> ...<br /> &lt;property name="name"                           value="com.aljoin.gas"/&gt;</div>
		<div>
				<br />删除D:\hibernate-3.0\middlegen-2.1\samples\build下的所有文件。然后打开命令行，<br />cd D:\hibernate-3.0\middlegen-2.1\samples<br />ant<br />这时候ant会自动读build.xml文件，找到project，运行名为"hbm2java"及其依赖的target.因为俺是菜鸟,什么ejb,jbo俺通通用不到.如果你不是菜鸟,可以设置成default="all",而且如果您的系统没有安装jboss之类的会出错,但我想如果您不是菜鸟应该也不会看到这里了hoho :p</div>
		<div> </div>
		<div>在跳出的程序界面上按generate。等待结束，然后关闭程序界面。在命令行窗口看到正在生成.java文件的信息。</div>
		<div>查看D:\hibernate-3.0\middlegen-2.1\samples\build目录。上帝保佑你会看到一些你需要的文件。</div>
		<div> </div>
		<div>到写完这篇烂文，一个早上已经过去，俺又把青春贡献给了党-_-||</div>
<img src ="http://www.cppblog.com/aqazero/aggbug/14213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-09-14 11:25 <a href="http://www.cppblog.com/aqazero/archive/2005/09/14/14213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LifeApplet 阅读笔记</title><link>http://www.cppblog.com/aqazero/archive/2005/08/11/14206.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Thu, 11 Aug 2005 09:32:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/08/11/14206.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14206.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/08/11/14206.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14206.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14206.html</trackback:ping><description><![CDATA[
		<p>关于“生命”游戏<a href="http://www.cnitblog.com/raistlin/archive/2005/07/13/922.html">由此进</a>。<br />关于LifeApplet<a href="http://www.cnitblog.com/raistlin/archive/2005/07/22/1099.html">由此进</a>，源文件<a href="http://www.cnitblog.com/Files/Raistlin/lifeapplet.rar">下载</a>。<br /><br />本来想自己用wtl写个CA(细胞自动机)程序，阅读了LifeApplet后打消了念头。写这篇笔记像初中时一个月语文作业没写最后滥竽充数几篇交上去，算是给自己一个交待。</p>
		<p>怎么写一个CA程序和想写怎样的一个CA程序有关。刚看完《上帝与新物理学》，我按照书上的规则和图案写了一个世界只有20*20大小的CA，细胞的运算是一个个计算的，计算一代就刷新显示一次，一个细胞用一个字节来保存，可以原谅的是我当时连规则都不清楚，目的只是验证一下规则。</p>
		<p>看了Alan Hensel的代码后，可能大部分写过CA程序的人都会觉得汗颜。-_-|||。体验过Alan Hensel 的LifeApplet的人就会看到:他的世界真大，实际上有2^20 * 2^20个像素；速度真快，可以设置fps(每秒刷新次数)，Generations/Frame(每次刷新间隔生产多少代)，如果设置为warp，CPU就会撒开腿跑起来...还可以设置规则，CA的规则不止Conway的那个，其它的也很有趣。</p>
		<p>数据结构：<br />LifeCell:<br />Alan Hensel将世界分成一个个16*16的单元，用LifeCell类表示。每个LifeCell包含两个数组表示 p[]，q[] = new short[16]，总共16*16 bits，表示16*16个细胞。并且在这个数组中按照一种奇怪的方式来排列，比如LifeCell中坐标为(1,1)的点在数组中的位置是65(见LifeCell文件)，代表这个点的bit就在p[6](和q[6])的<strong>左起</strong>第5位。为什么要这么表示？我想是作者为了以后unroll算法的方便。他究竟怎么得出这个方法的，我不知道。。</p>
		<p>每个LifeCell需要两个数组是因为CA的算法要求的运算必须是并行的。所以只能p生成q,q生成p，没什么好说的。</p>
		<p>每个LifeCell保存了相邻的东、西、南、北、东南、东北、西南、西北的LifeCell的指针。<br />保存了上一个，下一个LifeCell的指针。所有LifeCell保存在一个链表中。<br />保存了上一个，下一个需要显示的LifeCell的指针，用于显示。<br />保存了一个Down的LifeCell的指针，用于hash查找。<br />保存了坐标x,y。<br />保存了一些状态，qstate,pstate,flags为运算和优化用的。</p>
		<p>LifeHash:<br />因为所有LifeCell都放置于一个链表。而经常要用LifeCell的坐标来查找LifeCell，比如修改某个点的状态：为了在某个点放置一个细胞，需要通过点的坐标运算出LifeCell的坐标，再通过LifeCell的坐标找到LifeCell对象。<br />在链表中查找一个对象的运算复杂度是o(n)。n在此处最大可达2^16 * 2^16(把整个世界都占满，这也相当不容易)，所以对于一些超大的CA来说，查找起来会很浪费时间。。。所以有了LifeHash类。</p>
		<p>LifeHash中保存了一个2^HASHSIZE * 2^HASHSIZE的LifeCell对象指针数组，数组中每个对象维护一个链表，坐标x,y中低HASHSIZE位的值一样的LifeCell放在这个链表中。通过x,y可以快速找到这个链表，然后用上面说到的Down指针，比较(x,y)来找到具体的LifeCell。这样理论上来讲减少了查找时间...(我算不出来，哈)。究竟用多大的HASHSIZE才好？作者的值是6，就是占用了2^12 * sizeof(int) = 16k bytes内存。</p>
		<p>LifeRules：<br />LifeRules的目的在于把用字符串表示的规则转化成一个bool[512]。<br />比如"23/3"表示有2个或3个相邻细胞的细胞继续存活，如果一个位置旁边刚好有3个细胞，这个位置在下一步就要长出一个细胞。<br />由于一个位置有8个相邻的位置，加上自身为9位。把9个位置排序得到一个数，总共512个。比如对于0xC8，表示西北、西有细胞，自身有细胞，根据"23/3" bool[0xC8]的值应该为true。</p>
		<p>算法：<br />为了提高效率，Alan Hensel把LifeCell中每个4*4的运算都unroll了。所以在LifeGen文件中可以看到进一步的setRules(boolean[] Rule)函数，这个函数设置了了crunch(和munch)= new short[65536]。原理和LifeRules中类似，就是不知道这个运算过程怎么得出的，作者数学肯定非常好。。</p>
		<p>因为细胞的运算是以LifeCell为单元来运算的，一个单元的细胞会影响到相邻的单元。如果每次运算的时候都考虑相邻8个LifeCell的话，会造成CPU的浪费。所以在LifeGen中可以看到运算p状态和q状态时，LifeCell的位置是不一样的。从p状态生成q状态时，检查了东、南、东南方向相邻的LifeCell，生成的q状态的位置为p状态往东南各偏移一个细胞。所以如果p状态起始坐标为16x,16y，那么q状态时，起始坐标是16x+1, 16y+1(注意坐标系映射为MM，x在往东方向为正，y在往南方向为正)。在从q状态到p状态时，检查西、北、西北方向相邻的LifeCell，回到p状态的位置。</p>
		<p>其中具体的运算就算了吧，反正我没看明白。看明白的地方也不知道为什么。。作者太强悍了。</p>
		<p>线程：<br />这种程序当然至少要两个线程了，一个UI线程，一个Work线程。UI线程在LifeFrame中，没做什么事，就是把事件发送给Life对象(见Life.Java)，Life收到事件后并没有马上处理，而是放到一个队列中LifeQueue。<br />UI线程一启动，就启动了work线程。<br />在Life的run()中，处理细胞的繁衍LifeGen.generate()，显示，然后处理LifeQueue中的事件。<br />在LifeGen.generate()中控制生成繁衍的次数和显示的速度。<br />为什么两个线程同时对LifeQueue操作却没有声明synchronous呢？对java不熟，不敢妄言。</p>
		<p>有空还可以继续研究。先到此为止。反正作业就这么稀里糊涂交上去了。</p>
<img src ="http://www.cppblog.com/aqazero/aggbug/14206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-08-11 17:32 <a href="http://www.cppblog.com/aqazero/archive/2005/08/11/14206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>About Conway's Game of Life Applet of Alan Hensel</title><link>http://www.cppblog.com/aqazero/archive/2005/07/22/14207.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Fri, 22 Jul 2005 10:15:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/07/22/14207.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14207.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/07/22/14207.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14207.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14207.html</trackback:ping><description><![CDATA[
		<p>
				<a href="http://www.radicaleye.com/lifepage/java.html">
						<img alt="[A Life pattern called the puffer train]" src="http://www.radicaleye.com/lifepage/puftrn.gif" />
				</a>
		</p>
		<p>原文:<a href="http://www.ibiblio.org/lifepatterns/lifeapplet.html">http://www.ibiblio.org/lifepatterns/lifeapplet.html<br /><br /></a> 当前版本0.41d，更新时间2001-1-31，比0.41c版(199-1-22)上提高了些性能。新版本在计划中，只要我的空余时间允许。<br /> 作者:Alan Hensel,</p>
		<p>
				<strong>简介：</strong>
				<br />认识我的人都知道我为什么写这个程序。不是为了学习Java，不是为了提高我的网站的访问量，原因很简单：<br />我收集Life patterns，而且我喜欢展示它们</p>
		<p>当然，这些patterns中的大部分是别人发现的。没人想要从这些Life patterns中获利，所以据我所知这些patterns将留给后代并被赏识，就象国际象棋一样。</p>
		<p>请不要给我写信说：我喜欢你的程序，却忘记提起这些patterns。这听起来会象是恭维集邮爱好者他的邮册如何漂亮，对邮票却只字不提。我的程序只是做了它们该做的事情而已。</p>
		<p>
				<em>计算机软件和硬件只是使用者和他的数据之间的工具</em>。</p>
		<p>这些patterns让人赞叹。如果不信，你可以自己去做一个试试。(我希望这个挑战能促成一些发现。)</p>
		<p>
				<br />
				<strong>给那些写Life程序的学生：</strong>
				<br />我没有可以给你的源代码。这里没有你找的东西。我提供了这个程序的源代码，但它们超出了计算机课程的范围。它们之所以这么复杂是因为速度优化(这样我才能运行"Breeder"或者其它更大的patterns)。当然，你可以试着读读源代码，但不要强迫自己。你写的作业应该比这个程序简单一百倍。</p>
		<p>
				<strong>给来这里学习Java applets的读者:</strong>
				<br />这是我第一个真正意义上的applet。最好别打算把我的代码拷贝到你的程序中。源代码就在这一页的底部，你可以免费下载，当然，你必须为它付出些东西。若非如此，这将会是一个让人相当有学习动力的applet程序。<br /><strong><br />你怎么做到这么快的？</strong><br />好的。没有留心的话也许你不会发现我的程序闪电一样的快。你也许没看到"Warp Speed"按钮，或者你还没用过它，或者你觉得这无所谓。这样的话你可以跳过这个部分。<br />有人问，你究竟是怎么让它跑得这么快的？！对于这些好奇者，或者那些打算写自己的超级细胞自动机程序的人，我会解释的。</p>
		<p>我倾向于把细胞自动机的优化和数据压缩联系起来。这也是一个简单的概念却需要复杂的方法。究竟什么才是最好的方案取决于数据本身。对于康威的Life，倾向于出现点状的图案。</p>
		<p>对于点状分布的世界，我们应该考虑把它分割成近似大小的块。对于Life来说，4x4和8x8都是可取的。我选择了8x8，因为:刚好8比特1字节，我曾经考虑过4x4，但运行起来效果不大好。</p>
		<p>并且请注意：如果pattern长大并超过了块的范围，需要引入新的块。你可以简单的线性搜索，也可折半查找，或者维护某种映射。我的方法是哈希表。这个表只是用来查找一个新块的邻居。每个已存在的块已经有它的邻居的指针，并且会被多次使用。</p>
		<p>必须有高效的算法来处理这些块内部的数据，我选择一次处理块中的所有数据。在处理完整个块之前不需要跳转语句。换句话来说：所有内部循环都被unroll了，并使用了高速的查询表。</p>
		<p>注意：CA(细胞自动机)程序一般性的包含了两个主要循环(加上一个显示循环)，因为CA规则要求对细胞进行并行处理，但微处理器是线性的。这意味着必须有世界的两分拷贝，这样创建下一代的时候本身的信息才不会被破坏掉。通常这两个拷贝是不对称的。这对我来说相当麻烦，因为每次我从这边取出些东西进行优化，不得不在另一边加点别的什么！几乎每次，例外的情况导致了最好的优化。特别的,需要在位操作：位移，屏蔽和重组之间折中来找一个最好的查找表。</p>
		<p>有时块中的细胞会出现稳定的情况，不需要进一步处理。你可以把块从队列中移出，把它设置成“冬眠”状态，只有当邻近的块影响到它。这些块不需要占用处理器的时间，象空白的区域一样。</p>
		<p>检测周期为2的振荡器并把它移出处理队列并不难。这对于Life程序是值得的，因为blinker是最常见的随机的残余物。更复杂的振荡器相对比较少见。检测并模拟滑翔机也是可能的。这些方面的优化会得到递减的效果，除非你做到极致。(如HasLife)。</p>
		<p>同样，死亡状态：空的块不必马上释放并从哈希表中移走。那样会占用更多的处理器时间，尤其是当振荡器在一定空间内移进移出的时候。仅当可用内存已经很少的时候，才从死亡队列中移除最老的死亡的块。</p>
		<p>当程序快到一定程度，必须考虑刷新显示的速度不需要超过人眼可以感知的速度，或者最少不需要超过显示器的刷新频率。特别是在视窗环境，显示时间会是效率的瓶颈。</p>
		<p>
				<br />
				<strong>源代码</strong>
				<br />以下是我的超级快速的Game of Life applet源代码。<br />很抱歉这些不是百分百面向对象的。Game of Life并不适合面向对象技术。面向对象适用于你碰到的大多数问题，除了那些效率第一而且相当复杂的项目，康威的Game of Life正好属于这种情况。<br /><br />以下是16个源文件: </p>
		<p>
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeButton.java" target="_top">LifeButton.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeFrame.java" target="_top">LifeFrame.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/Life.java" target="_top">Life.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeGUI.java" target="_top">LifeGUI.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeGen.java" target="_top">LifeGen.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeCell.java" target="_top">LifeCell.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeHash.java" target="_top">LifeHash.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeCoordinate.java" target="_top">LifeCoordinate.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeRules.java" target="_top">LifeRules.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LoadBox.java" target="_top">LoadBox.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/RuleBox.java" target="_top">RuleBox.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/SpeedBox.java" target="_top">SpeedBox.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/OptionsBox.java" target="_top">OptionsBox.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeQueue.java" target="_top">LifeQueue.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/LifeCallback.java" target="_top">LifeCallback.java</a>
				<br />
				<a href="http://www.ibiblio.org/lifepatterns/src.41d/DescribeBox.java" target="_top">DescribeBox.java</a>
		</p>
<img src ="http://www.cppblog.com/aqazero/aggbug/14207.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-07-22 18:15 <a href="http://www.cppblog.com/aqazero/archive/2005/07/22/14207.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>"生命"游戏</title><link>http://www.cppblog.com/aqazero/archive/2005/07/13/14208.html</link><dc:creator>brent</dc:creator><author>brent</author><pubDate>Wed, 13 Jul 2005 02:06:00 GMT</pubDate><guid>http://www.cppblog.com/aqazero/archive/2005/07/13/14208.html</guid><wfw:comment>http://www.cppblog.com/aqazero/comments/14208.html</wfw:comment><comments>http://www.cppblog.com/aqazero/archive/2005/07/13/14208.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/aqazero/comments/commentRss/14208.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/aqazero/services/trackbacks/14208.html</trackback:ping><description><![CDATA[《上帝与新物理学》是一本谈论新物理学对以前属于宗教的问题产生的影响的书。在书的最后一章，谈到剑桥数学家约翰·康威发明的叫“生命”(life patterns)的游戏，场景是象围棋一样的格子，游戏规则是：<br />1，有2个或者3个邻子的棋子在下一代(下一步)仍然存活 <br />2，没有或只有1个邻近棋子要死(于孤单)，有4个或4个以上的邻子的棋子要死（于拥挤） <br />3，若1个空格正好与3个不空的格为邻，那么，这个空格就要生出一个棋子来<br />根据这些规则，某些起始的图形能够演化出“各种最令人惊讶的美丽图案”。书上有两个例子。<br />我看到这里就想着写个程序来实现这样的“游戏”，并一边兴奋的想象着各种各样的图案，我将会是那些二维生物的上帝！<br />刚好我在学WTL，昨天就用WTL写了个程序，一开始我对规则的理解并不正确，达不到书上程序的效果，程序改得很沮丧，哪天把程序写完整了再上传吧...<img height="19" src="http://www.cnitblog.com/Emoticons/confused_smile.gif" width="19" border="0" /><br />今天早上用google找了一下'生命 约翰 康威'....原来人家已经..原来这个游戏从1970年就被人无数次的写过...甚至都可以找到applet源代码<br /><a href="http://www.ibiblio.org/lifepatterns/">http://www.ibiblio.org/lifepatterns/</a><br /><a href="http://www.radicaleye.com/lifepage/">http://www.radicaleye.com/lifepage/</a><br /><img src ="http://www.cppblog.com/aqazero/aggbug/14208.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/aqazero/" target="_blank">brent</a> 2005-07-13 10:06 <a href="http://www.cppblog.com/aqazero/archive/2005/07/13/14208.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>