﻿<?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-在路上-随笔分类-OpenSource</title><link>http://www.blogjava.net/gumingcn/category/44176.html</link><description>路上有惊慌，路上有理想</description><language>zh-cn</language><lastBuildDate>Sun, 27 Mar 2011 13:56:38 GMT</lastBuildDate><pubDate>Sun, 27 Mar 2011 13:56:38 GMT</pubDate><ttl>60</ttl><item><title>Hibernate Annotation 笔记</title><link>http://www.blogjava.net/gumingcn/archive/2010/10/12/334667.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Tue, 12 Oct 2010 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/10/12/334667.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/334667.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/10/12/334667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/334667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/334667.html</trackback:ping><description><![CDATA[<br />
1.@Entity 标识实体<br />
2.@Table (name = "tableName") //指定物理表<br />
<br />
@Table(name="tbl_sky",<br />
&nbsp;&nbsp;&nbsp; uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})}//唯一性约束<br />
)<br />
<br />
3.@Embeddable 被声明的类可以嵌入其他实体中<br />
public class Address {<br />
&nbsp;&nbsp; private String street1;//persistent<br />
&nbsp;&nbsp; public String getStreet1() { return street1; }<br />
&nbsp;&nbsp; public void setStreet1() { this.street1 = street1; }<br />
&nbsp;&nbsp; private hashCode; //not persistent<br />
}<br />
@Embedded 在实体中嵌入一个类型：常用的像名字，地址之类的<br />
另，使用@AttributeOverrides标识覆盖原类中的属性取值，因为原实体可能引用的是其他字段。<br />
&nbsp;@Embedded<br />
&nbsp;&nbsp;&nbsp; @AttributeOverrides( {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @AttributeOverride(name="name", column = @Column(name="bornCountryName") )<br />
&nbsp;&nbsp;&nbsp; } )<br />
Country bornIn;<br />
<br />
例子：<br />
@Entity<br />
<br />
class User {<br />
&nbsp; @EmbeddedId<br />
&nbsp; @AttributeOverride(name="firstName", column=@Column(name="fld_firstname")<br />
&nbsp; UserId id;<br />
&nbsp; Integer age;<br />
}<br />
@Embeddable<br />
class UserId implements Serializable {//此处Serializable是必须的<br />
&nbsp; String firstName;<br />
&nbsp; String lastName;<br />
}<br />
<br />
4.@Access(AcessType.PROPERTY)<br />
必须定义getter/setter方法才能实现持久化<br />
还有另一种取值：AcessType.FILED,可以不定义getter/setter方法，也能实现持久化<br />
此annotation也可以定义字段。<br />
<br />
5.主键：<br />
&nbsp;&nbsp; A.单键<br />
&nbsp;&nbsp;&nbsp; @Id<br />
&nbsp;&nbsp;&nbsp; @GeneratedValue (generator = "identity")<br />
&nbsp;&nbsp;&nbsp; @GenericGenerator (name = "identity", strategy = "identity")<br />
&nbsp;&nbsp;&nbsp; 或者<br />
&nbsp;&nbsp;&nbsp; @javax.persistence.SequenceGenerator(<br />
&nbsp;&nbsp;&nbsp; name="SEQ_STORE",<br />
&nbsp;&nbsp;&nbsp; sequenceName="my_sequence")<br />
&nbsp;&nbsp;&nbsp; @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")<br />
&nbsp;&nbsp;&nbsp; 其中：<br />
&nbsp;&nbsp;&nbsp;&nbsp; strategy取值为:<br />
&nbsp;&nbsp;&nbsp;&nbsp;
AUTO - either identity column, sequence or table depending on the underlying DB<br />
&nbsp;&nbsp;&nbsp;&nbsp;
TABLE - table holding the id<br />
&nbsp;&nbsp;&nbsp;&nbsp;
IDENTITY - identity column<br />
&nbsp;&nbsp;&nbsp;&nbsp;
SEQUENCE - sequence<br />
&nbsp;&nbsp; B.复合组键<br />
&nbsp;&nbsp;&nbsp; @Entity<br />
&nbsp;class Customer {<br />
&nbsp; @EmbeddedId CustomerId id;<br />
&nbsp; boolean preferredCustomer;<br />
&nbsp; @MapsId("userId")//user.id与customerId.userId 使用相同的值<br />
&nbsp; @JoinColumns({<br />
&nbsp;&nbsp;&nbsp; @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),<br />
&nbsp;&nbsp;&nbsp; @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")<br />
&nbsp; })<br />
&nbsp; @OneToOne User user;<br />
}<br />
<br />
<br />
@Embeddable<br />
class CustomerId implements Serializable {<br />
&nbsp; UserId userId;<br />
&nbsp; String customerNumber;<br />
}<br />
<br />
<br />
@Entity <br />
class User {<br />
&nbsp; @EmbeddedId UserId id;<br />
&nbsp; Integer age;<br />
}<br />
<br />
@Embeddable<br />
class UserId implements Serializable {<br />
&nbsp; String firstName;<br />
&nbsp; String lastName;<br />
}<br />
&nbsp;&nbsp;&nbsp; &nbsp;<br />
<br />
6.字段设置：<br />
@Column(<br />
&nbsp;&nbsp;&nbsp; name="columnName";<br />
&nbsp;&nbsp;&nbsp; boolean un(2)ique() default false;<br />
&nbsp;&nbsp;&nbsp; boolean nu(3)llable() default true;<br />
&nbsp;&nbsp;&nbsp; boolean in(4)sertable() default true;<br />
&nbsp;&nbsp;&nbsp; boolean up(5)datable() default true;<br />
&nbsp;&nbsp;&nbsp; String col(6)umnDefinition() default "";<br />
&nbsp;&nbsp;&nbsp; String tab(7)le() default "";<br />
&nbsp;&nbsp;&nbsp; int length(8)() default 255;<br />
&nbsp;&nbsp;&nbsp; int precis(9)ion() default 0; // decimal precision<br />
&nbsp;&nbsp;&nbsp; int scale((10)) default 0; // decimal scale<br />
@Transient 非持久化字段<br />
@Basic 持久化字段<br />
@Basic(fetch = FetchType.LAZY) basic 用于定义property的fetch属性<br />
@Enumerated(EnumType.STRING) 标识enum persisted as String in database<br />
@Lob&nbsp; blob clob字段<br />
@Formula("obj_length * obj_height * obj_width")//自定义输出<br />
public long getObjectVolume()<br />
<br />
7.Mapping关系<br />
A.一对多或者一对一：<br />
&nbsp;@OneToOne(cascade = CascadeType.ALL) 一对一关系，级联关系为all<br />
&nbsp;@PrimaryKeyJoinColumn或者<br />
&nbsp;指定关联外键<br />
&nbsp;@JoinColumn(name="passport_fk")<br />
&nbsp;Passport passport，<br />
&nbsp;一对一的另一端只需@OneToOne(mappedBy = "passport")，passport为前一个实体声明的名字<br />
<br />
<br />
@OneToMany(fetch = FetchType.LAZY , mappedBy = "adProduct")<br />
@Cascade(value = {CascadeType.ALL,CascadeType.DELETE_ORPHAN})<br />
<br />
@OrderBy(value = "id")&nbsp; //排序<br />
B.多对一：<br />
&nbsp;&nbsp;&nbsp; @ManyToOne(fetch = FetchType.LAZY)<br />
&nbsp;&nbsp;&nbsp; @JoinColumn(name="adPosition_id",nullable=false)&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; <br />
<br />
8.Fetch and Lazy<br />
<table summary="Lazy and fetch options equivalent" border="1">
    <thead>
        <tr>
            <th>Annotations</th><th>Lazy</th><th>Fetch</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>@[One|Many]ToOne](fetch=FetchType.LAZY)</td>
            <td>@LazyToOne(PROXY)</td>
            <td>@Fetch(SELECT)</td>
        </tr>
        <tr>
            <td>@[One|Many]ToOne](fetch=FetchType.EAGER)</td>
            <td>@LazyToOne(FALSE)</td>
            <td>@Fetch(JOIN)</td>
        </tr>
        <tr>
            <td>@ManyTo[One|Many](fetch=FetchType.LAZY)</td>
            <td>@LazyCollection(TRUE)</td>
            <td>@Fetch(SELECT)</td>
        </tr>
        <tr>
            <td>@ManyTo[One|Many](fetch=FetchType.EAGER)</td>
            <td>@LazyCollection(FALSE)</td>
            <td>@Fetch(JOIN)</td>
        </tr>
    </tbody>
</table>
<br />
9.Cascade<br />
<ul>
    <li>
    <p><a id="entity-hibspec-cascade">PERSIST</a></p>
    </li>
    <li>
    <p><a id="entity-hibspec-cascade">MERGE</a></p>
    </li>
    <li>
    <p><a id="entity-hibspec-cascade">REMOVE</a></p>
    </li>
    <li>
    <p><a id="entity-hibspec-cascade">REFRESH</a></p>
    </li>
    <li>
    <p><a id="entity-hibspec-cascade">DELETE</a></p>
    </li>
    <li>
    <p><a id="entity-hibspec-cascade">SAVE_UPDATE</a></p>
    </li>
</ul>
<br />
10.缓存<br />
<p>缓存的注释写法如下，加在Entity的java类上：<br />
</p>
<p>@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) </p>
<p>缓存的方式有四种，分别为：</p>
<ul>
    <li>CacheConcurrencyStrategy.NONE
    </li>
    <li>CacheConcurrencyStrategy.READ_ONLY，只读模式，在此模式下，如果对数据进行更新操作，会有异常；
    </li>
    <li>CacheConcurrencyStrategy.READ_WRITE，读写模式在更新缓存的时候会把缓存里面的数据换成一个锁，其它事务如果去取相应的缓存数据，发现被锁了直接就去数据库查询；
    </li>
    <li>CacheConcurrencyStrategy.NONSTRICT_READ_WRITE，不严格的读写模式则不会对缓存数据加锁；
    </li>
    <li>CacheConcurrencyStrategy.TRANSACTIONAL，事务模式指缓存支持事务，当事务回滚时，缓存也能回滚，只支持JTA环境。 </li>
</ul>
<br />
<br />
11.No-Annotation 字段：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If the property is of a single type, it is mapped as @Basic<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Otherwise, if the type of the property is annotated as @Embeddable, it is mapped as @Embedded<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Otherwise, if the type of the property is Serializable, it is mapped as @Basic in a column holding the object in its serialized version<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Otherwise, if the type of the property is java.sql.Clob or java.sql.Blob, it is mapped as @Lob with the appropriate LobType<br />
<img src ="http://www.blogjava.net/gumingcn/aggbug/334667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-10-12 16:52 <a href="http://www.blogjava.net/gumingcn/archive/2010/10/12/334667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Rule Engine之Drools</title><link>http://www.blogjava.net/gumingcn/archive/2010/09/25/332860.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Sat, 25 Sep 2010 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/09/25/332860.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/332860.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/09/25/332860.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/332860.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/332860.html</trackback:ping><description><![CDATA[对于做软件的人来说，唯一不变的就是变化。此为行业真理。而对于复杂业务系统的逻辑组件的定义不得不多考虑一下业务的可扩展性，来应对客户的变化。选择Rule Engine是一个不错的方案。<br />
<br />
Drools 是用 Java 语言编写的开放源码规则引擎。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则（这点很重要，本人之前曾用过自己公司的一套业务规则组件，无论是编写还是调试都很麻烦），从而便于学习和理解。并且，还可以将 Java 代码直接嵌入到规则文件中，使Drools 更加吸引人。简单的概括，就是简单使用，易于理解。而且它是免费的。<br />
<br />
<strong>1.rule文件：</strong><br />
rule "rule name"&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; no-loop <br />
&nbsp;&nbsp;&nbsp; when<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; customer : Customer( state == CustomerState.UNCENSORED )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; then<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; customer.setState(CustomerState.AUDITING);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; CustomerTask task=new CustomerTask();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Post law=userService.getPostByPostCode(Constants.PostCode.ROOT_LAW);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setAuditorPost(law);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setEntityState(CustomerState.AUDITING);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setEntityId(customer.getId());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setEntityCode(String.valueOf(customer.getId()));<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setEntityType(Customer.class.getSimpleName());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; task.setTitle(customer.getName()+" test");<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; taskService.assignmentTask(task);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.info("CustomerTask Submit auditorTitle:" + task.getAuditorTitle()); <br />
end<br />
<br />
这里面有个状态的条件判断state == CustomerState.UNCENSORED ，then 关键字后面的便是符合条件的处理逻辑，只要是java程度都可以看懂，比xml类的rule文件好懂了许多。<br />
<br />
接下来<br />
<strong>语法说明：</strong><br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/gumingcn/package.png" height="313" width="303" /><br />
<br />
文件头部分：<br />
<strong>package</strong> drools.java.demo;定义包名,等同于命名空间<br />
<strong>import</strong> drools.java.demo.Machine;导入java类<br />
<strong>global </strong>java.util.List myGlobalList<strong>;</strong><code></code>此关键字让规则引擎知道，myGlobalList对象应该可以从规则中访问<strong>.<br />
function:</strong>类似于公用方法的抽象，如下定义后，各个同一文件下的rule都可以使用<br />
function void setTestsDueTime(Machine machine, int numberOfDays) {<br />
&nbsp;&nbsp;&nbsp; setDueTime(machine, Calendar.DATE, numberOfDays);<br />
} <strong><br />
</strong>
<pre class=""><a id="d0e3160"><strong>rule</strong>：定义了一个规则<br />
<br />
</a><a id="d0e3563">rule "&lt;name&gt;"<br />
&lt;attribute&gt;*<br />
when<br />
&lt;conditional element&gt;*<br />
then<br />
&lt;action&gt;*<br />
end</a><a id="d0e3160"><br />
<br />
<br />
<br />
&lt;name&gt; 即rule的名字标识<br />
<br />
</a><a id="d0e3563">&lt;attribute&gt;:</a><a id="d0e3160"><br />
<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/gumingcn/rule_attributes.png" height="389" width="357" /></a></pre>
常用的属性：<strong><br />
</strong>no-loop ：true 条件结果更改后，修改此条件且定义为no-loop:true的规则不会再重新执行。<br />
<pre class="displaycode">lock-on-active：true 可以看作是no-loop的加强版，当条件结果更改后，不但修改此条件的规则不会重新执行，文件中的任何规则（其 active-lock 属性被设为 <code>true</code>）不会重新执行。</pre>
<code>salience</code>：100 使用它可以让规则执行引擎知道应该启动规则的结果语句的顺序。具有最高显著值的规则的结果语句首先执行；具有第二高显著值的规则的结果语句第二执行，依此类推。当您需要让规则按预定义顺序启动时，这一点非常重要。<br />
<br />
其他属性的解释请见http://downloads.jboss.com/drools/docs/5.1.1.34858.FINAL/drools-expert/html_single/index.html#d0e2607<br />
<br />
<strong>when:</strong>填写条件的地方，比如：<br />
<pre class="programlisting">Cheese( type == "stilton", price &lt; 10, age == "mature" )或<br />
<br />
Cheese( type == "stilton" &amp;&amp; price &lt; 10, age == "mature" )<br />
<br />
</pre>
<strong>then:</strong>业务规则的地方，略。<br />
<br />
<strong>2.用法</strong><br />
<br />
规则文件定义好后，就该是怎么使用它了<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/gumingcn/Forward_Chaining.png" height="316" width="444" /><br />
<br />
如上图，file rule定义好后，就该是如何使用它了。最重要的两个类RuleBase和WorkingMemory<br />
<br />
下面是一个example:<br />
public class RulesEngine {<br />
&nbsp;&nbsp;&nbsp; private RuleBase rules;<br />
&nbsp;&nbsp;&nbsp; private boolean debug = false;<br />
&nbsp;&nbsp;&nbsp; public RulesEngine(String rulesFile) throws RulesEngineException {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; super();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Read in the rules source file<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Reader source = new InputStreamReader(RulesEngine.class<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .getResourceAsStream("../../rules/" + rulesFile));<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Use package builder to build up a rule package<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; PackageBuilder builder = new PackageBuilder();<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // This will parse and compile in one step<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; builder.addPackageFromDrl(source);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Get the compiled package<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Package pkg = builder.getPackage();<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // Add the package to a rulebase (deploy the rule package).<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rules = RuleBaseFactory.newRuleBase();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; rules.addPackage(pkg);<br />
<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } catch (Exception e) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throw new RulesEngineException(<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; "Could not load/compile rules file: " + rulesFile, e);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public RulesEngine(String rulesFile, boolean debug)<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; throws RulesEngineException {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this(rulesFile);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.debug = debug;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; public void executeRules(WorkingEnvironmentCallback callback) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WorkingMemory workingMemory = rules.newStatefulSession();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (debug) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; workingMemory<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; .addEventListener(new DebugWorkingMemoryEventListener());<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; callback.initEnvironment(workingMemory);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; workingMemory.fireAllRules();<br />
&nbsp;&nbsp;&nbsp; }<br />
}<br />
RulesEngine构造方法演示了如何去读入一个rule文件,并构建了一个RuleBase对象(RuleBase 是一个包含了rule文件的所有规则的集合)<br />
executeRules方法定义了如何使用规则文件中定义的那些内容，用RuleBase构建一个WorkingMemory对象，再执行fireAllRules()方法。<br />
WorkingMemory 代表了与rulebase链接的session会话，也可以看作是工作内存空间。如果你要向内存中插入一个对象可以调用insert()方法,同理，更新一个对象使用update()方法。WorkingMemory还有一个setGlobal()方法，用来设置规则内可以引用的对象(相当于规则的全局变量)。<br />
<br />
<strong>3.小技巧</strong><br />
<br />
&nbsp; 可以一次把所有的rule文件都载入内存中存放，这样就不用每次执行都读取文件。<br />
&nbsp; 如果规则文件被修改，也可以用过一个方法来判断是否需要重新载入rule文件<br />
&nbsp; 比如：根据文件的最后修改时间，与内存中对应对象的时间做比较<br />
public boolean hasChange(List&lt;RuleFile&gt; ruleFileList){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for(RuleFile ruleFile:ruleFileList){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!ruleFile.getLastModifyTime().equals(ruleFileMap.get(ruleFile.getFileName()).getLastModifyTime())){<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return true;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
注：具体的helloWorld 请见http://www.ibm.com/developerworks/cn/java/j-drools/#listing12，比我说得好多了。<br />
<img src ="http://www.blogjava.net/gumingcn/aggbug/332860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-09-25 17:48 <a href="http://www.blogjava.net/gumingcn/archive/2010/09/25/332860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring之事件监听</title><link>http://www.blogjava.net/gumingcn/archive/2010/09/01/330513.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Wed, 01 Sep 2010 02:41:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/09/01/330513.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/330513.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/09/01/330513.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/330513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/330513.html</trackback:ping><description><![CDATA[<div class="entry">
<p>写在前面的话：spring的监听事件模型应该是观察者模式。本人项目里的应用在process方法按日期同步某个库的数据，在方法最后publish一个event事件，这个事件用于后续同步过来的数据处理。事件处理采用了spring的监听模型.这样可以做到process方法与event可以异步分离执行。（注：这个事件模型缺省使用<a name="181"><span style="color: red;">SyncTaskExecutor来执行listener的注册event，所有该listener注册的event事件为</span></a>同步执行的）。</p>
<p>当然，spring的这个机制还有很多应用的场景，就不一一列举了。</p>
<p><span style="color: #000000;"><strong>ApplicationEvent </strong></span></p>
<p>事件抽象类，里面只有一个构造函数和一个timestamp。</p>
<p><span style="color: #000000;"><strong>ApplicationListener</strong></span></p>
<p>监听接口，里面只有一个onApplicationEvent方法。需要用户自己编写ApplicationListener的实现。</p>
<p><strong>ApplicationContext</strong></p>
<p>spring上下文,其publishEvent方法用于通知监听器(ApplicationListener的实现)注册event时间.</p>
<h3>publishEvent</h3>
<pre>void <strong>publishEvent</strong>(<a title="class in org.springframework.context" href="http://www.jarvana.com/jarvana/view/org/springframework/spring/1.2.9/spring-1.2.9-javadoc.jar%21/org/springframework/context/ApplicationEvent.html">ApplicationEvent</a>&nbsp;event)</pre>
<dl><dd>
<p>Notify all listeners registered with this application of an application  event.</p>
</dd></dl>
<p>源码解读：<br />
1.作为ApplicationContext的实现AbstractApplicationContext.java的成员变量<a name="181">applicationListeners，是一个ArrayList,保存了所有的</a><a name="181">ApplicationListener</a><br />
2.利用<strong>ApplicationEventMulticaster</strong>接口里的方法来完成注册监听<a class="r">addApplicationListener,移除监听</a><a class="r">removeApplicationListener，</a><a class="r">removeAllListeners，以及通知监听注册事件event：</a><a class="r">multicastEvent</a>(<a class="r">ApplicationEvent</a> <a class="r">event</a>);<br />
上面说到的publishEvent方法即使用了<a class="r">multicastEvent方法<br />
</a><br />
<strong>SimpleApplicationEventMultucaster</strong>作为<a name="181">ApplicationEventMulticaster的一个实现，提供了multicastEvent的实现代码，其实就是迭代所有的监听器，<span style="color: red;">用SyncTaskExecutor同步执行listener的onApplicationEvent</span></a></p>
<p><a name="181">           public void multicastEvent(final ApplicationEvent event) {</a></p>
<p><a name="181">                for (Iterator it = getApplicationListeners().iterator(); it</a></p>
<p><a name="181">                        .hasNext();) {</a></p>
<p><a name="181">                 final ApplicationListener listener = (ApplicationListener) it</a></p>
<p><a name="181">                           .next();</a></p>
<p><a name="181">                    getTaskExecutor().execute(new Runnable() {</a></p>
<p><a name="181">                      public void run() {</a></p>
<p><a name="181">                           listener.onApplicationEvent(event);<br />
}<br />
});<br />
}</a></p>
<p>3.注意事项：自己编写ApplicationListener的实现时，要注意不同的监听器处理不同的事件（复写<a name="181">onApplicationEvent</a>）。原因就是<a name="181">multicastEvent的执行原理。它是迭代执行所有的监听器</a><a name="181">onApplicationEvent</a></p>
<p><a name="181">这里是</a><a name="181">ApplicationEventMulticaster的类分布图</a><a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(&quot;/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif&quot;);" name="181"></a></p>
<p><a name="181"><strong><br />
</strong></a><br />
abstract public class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster(Code)(Java Doc)<br />
public interface ApplicationEventMulticaster (Code)(Java Doc)</p>
<p>   public class SimpleApplicationEventMulticaster extends</p>
<p>这里是ApplicationContext的类分布图<br />
public class DefaultResourceLoader implements ResourceLoader(Code)(Java Doc)<br />
public interface ResourceLoader (Code)(Java Doc)</p>
<p>   abstract public class AbstractApplicationContext extends
DefaultResourceLoader implements
ConfigurableApplicationContext,DisposableBean(Code)(Java Doc)<br />
public interface ConfigurableApplicationContext extends ApplicationContext,Lifecycle(Code)(Java Doc)<br />
public interface DisposableBean (Code)(Java Doc)</p>
<p>   public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry(Code)(Java Doc)<br />
public interface BeanDefinitionRegistry (Code)(Java Doc)</p>
<p>   abstract public class AbstractRefreshableApplicationContext extends<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(&quot;/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif&quot;);" name="181"></a>下面是spring自身的事件应用<br />
1)   ContextRefreshedEvent：当ApplicationContext初始化或者刷新时触发该事件。<br />
2)   ContextClosedEvent：当ApplicationContext被关闭时触发该事件。容器被关闭时，其管理的所有单例Bean都被销毁。<br />
3)   RequestHandleEvent：在Web应用中，当一个http请求（request）结束触发该事件。<br />
4)   ContestStartedEvent：当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。<br />
5)   ContestStopedEvent：当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
</p>
</div>
<img src ="http://www.blogjava.net/gumingcn/aggbug/330513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-09-01 10:41 <a href="http://www.blogjava.net/gumingcn/archive/2010/09/01/330513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ibatis总结(1)</title><link>http://www.blogjava.net/gumingcn/archive/2010/08/30/330342.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Mon, 30 Aug 2010 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/08/30/330342.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/330342.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/08/30/330342.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/330342.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/330342.html</trackback:ping><description><![CDATA[<div class="entry">
<p>1.实体map.xml中配置:<br />
主键获取方式配置,mysql<br />
&lt;selectKey&nbsp; resultClass="java.lang.Integer" keyProperty="id"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; select LAST_INSERT_ID()<br />
&lt;/selectKey&gt;<br />
<br />
动态拼接where条件<br />
&lt;dynamic prepend="where"&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;isNotNull&gt;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; plateId=#value#<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/isNotNull&gt;<br />
&lt;/dynamic&gt;<br />
2.config配置<br />
typeAlias 定义类型别名<br />
&lt;typeAlias alias="Item" type="com.tudou.tudoupromotion.entity.Item"/&gt;<br />
<br />
typeHandler 自定义类型转换<br />
比如，将数据库中的1，2，3格式的数据转换为java 枚举<br />
&nbsp;&lt;typeHandler
javaType="com.tudou.tudoupromotion.entity.Plate"
callback="com.tudou.tudoupromotion.ext.ibatis.PlateHandler"/&gt;</p>
<p>线程缓存等配置</p>
<p>&nbsp;&nbsp;&nbsp; &lt;settings<br />
&nbsp;&nbsp;&nbsp;&nbsp; cacheModelsEnabled="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp; enhancementEnabled="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp; lazyLoadingEnabled="false"<br />
&nbsp;&nbsp;&nbsp;&nbsp; maxRequests="32"<br />
&nbsp;&nbsp;&nbsp;&nbsp; maxSessions="10"<br />
&nbsp;&nbsp;&nbsp;&nbsp; maxTransactions="5"<br />
&nbsp;&nbsp;&nbsp;&nbsp; useStatementNamespaces="true"<br />
&nbsp;&nbsp;&nbsp; /&gt;<br />
&nbsp;&nbsp; cacheModelsEnabled="true"&nbsp; 是否启动缓存机制<br />
&nbsp; enhancementEnabled="true"&nbsp; 是否针对POJO启动字节码增强机制以提升getter/setter的调用效能避免使用javaReflect所带来的性能开销。同时Lazy Loading带来极大的性能提升。<br />
&nbsp; maxRequests最大并发请求数(Statement数)<br />
&nbsp; maxTransactions最大并发事务数<br />
&nbsp;
maxSessions最大Session数，即当前最大允许的并发SqlMapCliect数maxSessions设定必须界于
maxTransactions和maxRequests之间.即&nbsp;&nbsp;
maxTransactions&gt;maxSessions&gt;maxRequests</p>
</div>
<img src ="http://www.blogjava.net/gumingcn/aggbug/330342.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-08-30 22:31 <a href="http://www.blogjava.net/gumingcn/archive/2010/08/30/330342.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用ORMUnit测试数据库schema与Hibernate 实体的Map关系</title><link>http://www.blogjava.net/gumingcn/archive/2010/03/03/314407.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Wed, 03 Mar 2010 06:55:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/03/03/314407.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/314407.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/03/03/314407.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/314407.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/314407.html</trackback:ping><description><![CDATA[ORMUnit下载链接：<br />
http://code.google.com/p/ormunit/<br />
&nbsp;&nbsp;&nbsp; 在做面向关系数据库的应用系统的时候，db表结构在开发过程中，可能会由于前期的设计不足导致不断的修改表结构。如果Java层面采用类似Hibernate ORM,随之对应的是maps &amp; pojos的修改。此时修改后的简单测试就显得尤为重要。<br />
&nbsp;&nbsp;&nbsp; ORMUnit功能比较多，本文只取其少数几个类，完成上面的功能。<br />
&nbsp;&nbsp;&nbsp; 1.首先改写：HibernateORMTestCase类，指定加载的hibernate.cfg.xml位置<br />
&nbsp;&nbsp;&nbsp; public abstract class HibernateORMTestCase extends TestCase {<br />
&nbsp;&nbsp;&nbsp; protected Log logger = LogFactory.getLog(getClass());<br />
&nbsp;&nbsp;&nbsp; protected SessionFactory sessionFactory;<br />
&nbsp;&nbsp;&nbsp; //Location of hibernate.cfg.xml file.<br />
&nbsp;&nbsp;&nbsp; private static String CONFIG_FILE_LOCATION = "com/mmm/china/xxx/dbtest/hibernate.cfg.xml";<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; protected Configuration cfg;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public void setSessionFactory(SessionFactory sessionFactory) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; this.sessionFactory = sessionFactory;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * make configuration<br />
&nbsp;&nbsp;&nbsp;&nbsp; * @return<br />
&nbsp;&nbsp;&nbsp;&nbsp; */<br />
&nbsp;&nbsp;&nbsp; protected Configuration getConfiguration() {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (cfg == null) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cfg=new Configuration().configure(CONFIG_FILE_LOCATION);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return cfg;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp; }&nbsp; <br />
&nbsp;&nbsp;&nbsp; 2.HibernateSchemaChecker类(检查db schema map pojo)：改写输出不符合map关系的表以及变更脚本，并增加计数功能<br />
&nbsp;&nbsp;&nbsp;&nbsp; List getSignificantDifferences(<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] script) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int num=0;<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; List differences = new ArrayList();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; script.length; i++) {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line = script[i];<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (line.indexOf("add constraint") == -1)<br />
&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;differences.add(line);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logger.error("DIFF_LINE&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;="+line);<br />
&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; else{<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; num++;//计算有多少个外键有问题<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logger.info("CONSTRAINT_LINE&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;"+num+"="+line);<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return differences;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注：ORMUnit 检查CONSTRAINT 有问题，在db为sqlserver时，生成的外键约束的名称是自动命名的，与实际数据库的命名不一致，ORMUnit就认为不匹配，所以，要过滤add constraint的error信息<br />
&nbsp;&nbsp; 3.使用HibernateSchemaTests 进行junit测试<br />
&nbsp;&nbsp;&nbsp; public class HibernateSchemaTests extends HibernateORMTestCase&nbsp; {<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private HibernateSchemaChecker schemaChecker;<br />
<br />
&nbsp;&nbsp;&nbsp; protected void setUp() throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; super.setUp();<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; schemaChecker = new HibernateSchemaChecker(getConfiguration(), getConfiguration().buildSessionFactory());<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp;&nbsp; /**<br />
&nbsp;&nbsp;&nbsp; &nbsp;* Verifies&nbsp; all tables and columns referenced by the object/relational<br />
&nbsp;&nbsp;&nbsp; &nbsp;* mapping exist<br />
&nbsp;&nbsp;&nbsp; &nbsp;* <br />
&nbsp;&nbsp;&nbsp; &nbsp;* @throws Exception<br />
&nbsp;&nbsp;&nbsp; &nbsp;*/<br />
&nbsp;&nbsp;&nbsp; public void assertDatabaseSchema() throws Exception {<br />
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; schemaChecker.assertDatabaseSchema();<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
&nbsp;&nbsp; }<br />
&nbsp; 总结：只需要三个类，即可测试数据库schema与hibernate maps &amp; pojo的map关系是否完全匹配，事半功倍。<br />
<img src ="http://www.blogjava.net/gumingcn/aggbug/314407.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-03-03 14:55 <a href="http://www.blogjava.net/gumingcn/archive/2010/03/03/314407.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Apache CouchDB在Ubuntu下的安装</title><link>http://www.blogjava.net/gumingcn/archive/2010/02/27/314071.html</link><dc:creator>阮步兵</dc:creator><author>阮步兵</author><pubDate>Sat, 27 Feb 2010 07:38:00 GMT</pubDate><guid>http://www.blogjava.net/gumingcn/archive/2010/02/27/314071.html</guid><wfw:comment>http://www.blogjava.net/gumingcn/comments/314071.html</wfw:comment><comments>http://www.blogjava.net/gumingcn/archive/2010/02/27/314071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/gumingcn/comments/commentRss/314071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/gumingcn/services/trackbacks/314071.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt;">
&nbsp;<br />
<p>先下载couchdb安装文件：版本为0.9.1</p>
<p>http://couchdb.apache.org/downloads.html</p>
<p>1开始安装依赖包</p>
<p>sudo apt-get build-dep couchdb</p>
<p>sudo apt-get install libmozjs-dev libicu-dev libcurl4-gnutls-dev
libtool </p>
<p>2.解压缩</p>
<p>tar -zxvf apache-couchdb-0.9.1.tar.gz </p>
<p>3.开始安装</p>
<p>cd apache-couchdb-0.9.1</p>
<p>./configure</p>
<p>make</p>
<p>sudo make install</p>
<p>4.启动couchdb</p>
<p>sudo couchdb</p>
<p>5.访问:http://127.0.0.1:5984/_utils/</p>
<p>启动报错：</p>
<pre>$ bin/couchdb<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Apache CouchDB 0.9.0a691361-incubating (LogLevel=info) is starting.<br />
<br />
<br />
<br />
{"init terminating in do_boot",{{badmatch,{error,shutdown}},[{couch_server_sup,start_server,1},<br />
<br />
<br />
<br />
{erl_eval,do_apply,5},{erl_eval,exprs,5},{init,start_it,1},{init,start_em,1}]}}<br />
<br />
<br />
<br />
Crash dump was written to: erl_crash.dump<br />
<br />
<br />
<br />
init terminating in do_boot ()<br />
<br />
<br />
<br />
查了一下官方wiki:<br />
<br />
<br />
<br />
原来是安装文件夹的权限问题<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
解决办法：<br />
<br />
<br />
<br />
sudo adduser couchdb<br />
<br />
<br />
<br />
chown -R couchdb:couchdb /usr/local/etc/couchdb <br />
<br />
<br />
<br />
chown -R couchdb:couchdb /usr/local/var/lib/couchdb <br />
<br />
<br />
<br />
chown -R couchdb:couchdb /usr/local/var/log/couchdb <br />
<br />
<br />
<br />
chown -R couchdb:couchdb /usr/local/var/run <br />
<br />
<br />
<br />
chmod -R 0770 /usr/local/etc/couchdb <br />
<br />
<br />
<br />
chmod -R 0770 /usr/local/var/lib/couchdb <br />
<br />
<br />
<br />
chmod -R 0770 /usr/local/var/log/couchdb <br />
<br />
<br />
<br />
chmod -R 0770 /usr/local/var/run<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
再此启动，看到欢迎界面，所有的testsuite run success,大功告成！</pre>
<br />
<br />
文章来源:<a href="http://guming.blogbus.com/logs/45898514.html">http://guming.blogbus.com/logs/45898514.html</a> </span>
<img src ="http://www.blogjava.net/gumingcn/aggbug/314071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/gumingcn/" target="_blank">阮步兵</a> 2010-02-27 15:38 <a href="http://www.blogjava.net/gumingcn/archive/2010/02/27/314071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>