<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>徐构</title>
    <description></description>
    <link>http://hooney.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>常用 Unix/Linux   shell 命令</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/230093" style="color:red;">http://hooney.javaeye.com/blog/230093</a>&nbsp;
          发表时间: 2008年08月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转自:<a href="http://fanqiang.chinaunix.net/program/code/2006-06-27/4695.shtml" target="_blank">http://fanqiang.chinaunix.net/program/code/2006-06-27/4695.shtml</a><br /><br /><pre name="code" class="ruby">删除 core 文件

# find ~ -name core -exec file {} \; -exec rm -i {} \;

查看使用文件的进程

# fuser -u /usr/my_application/foo

搜索字符串

#grep "hello world" `find ./ -name "*" -print -exec file {} \; |grep text | cut -d ':' -f 1`

目录

#alias dir='ls -Lla|grep ^d'

输出 IP 地址

#ifconfig | grep "inet addr" | grep -v "127.0.0.1" | awk '{print $2;}' | awk -F':' '{print $2;}'

按文件长度排序

#ls -l | grep ^- | sort -nr -k 5 | more

#ls -lR | grep ^- | sort -nr -k 5 | more

二进制文件中的可打印字符

# strings name of binary file

一个月的最后一个星期天执行任务：

18 * * * 0 [`date "+%d"` -gt 24] && /path/to/script

修改扩展名：

# for f in *.abc; do mv $f `basename $f .abc`.def ; done

查看硬盘情况：(Solaris)

# iostat -En

整个目录树拷贝：

# cd

# find . -depth -print | cpio -pudm

按长度排序目录下所有文件

# du -a | sort -n -r | more

检查文件内每行是否有相同列数

#awk '{print NF}' test.txt |sort -nu|more

去除空行

#sed -e '/^[ ]*$/d' InputFile >OutputFile

查看进程占用的对应文件 inode 号(Solaris)

#/usr/proc/bin/pfiles

删除指定用户的所有进程

# kill -9 `ps -fu username |awk '{ print $2 }'|grep -v PID`

Bash 操作快捷键：

ctrl-l -- clear screen

ctrl-r -- does a search in the previously given commands so that you don't

have to repeat long command.

ctrl-u -- clears the typing before the hotkey.

ctrl-a -- takes you to the begining of the command you are currently typing.

ctrl-e -- takes you to the end of the command you are currently typing in.

esc-b -- takes you back by one word while typing a command.

ctrl-c -- kills the current command or process.

ctrl-d -- kills the shell.

ctrl-h -- deletes one letter at a time from the command you are typing in.

ctrl-z -- puts the currently running process in background, the process

can be brought back to run state by using fg command.

esc-p -- like ctrl-r lets you search through the previously given commands.

esc-. -- gives the last command you typed.

文件名里的空格替换为下划线

# for i in $1 ; do mv "$i" `echo $i | sed 's/ /_/g'` ; done

查看远程主机时间

# telnet remotehostname 13|grep :

只显示 top 命令的states 行

#while true; do top -d 2 | col -b | grep states; sleep 10; done

加速显示　tar 文件内容

# tar tvfn

让 目录名也能　Spell Check

#shopt -s cdspell

当输错命令时，系统会自动进入类似的目录

查看　Sun 服务器型号

# /usr/platform/`uname -m`/sbin/prtdiag -v | grep `uname -m`

在vi 中一行文字前后添加字符

:/^\(.*\)/s//我要 \1 添加/

查找某包含字符串(Verita)软件包的详细信息 (Solaris)

pkginfo -l `pkginfo | grep -i VERITAS | awk '{print $2}'`

Sun 的一大堆脚本

<a href="http://www.sun.com/bigadmin/scripts/index.html" target="_blank">http://www.sun.com/bigadmin/scripts/index.html</a> </pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/230093#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 19 Aug 2008 11:54:13 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/230093</link>
        <guid>http://hooney.javaeye.com/blog/230093</guid>
      </item>
      <item>
        <title>rails魔术字段的实现 ,alias_method_chain用法</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/210244" style="color:red;">http://hooney.javaeye.com/blog/210244</a>&nbsp;
          发表时间: 2008年07月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Encapsulates the common pattern of:<br /><br />  alias_method :foo_without_feature, :foo<br />  alias_method :foo, :foo_with_feature<br /><br />With this, you simply do:<br /><br />  alias_method_chain :foo, :feature<br />替我们定义了两个方法：foo_with_feature 和 foo_without_feature &lt;保存原来的foo方法><br />def foo_with_feature <br />  在此添加想向foo方法里面写的代码<br />  foo_without_feature 调用一下原来的方法<br />end<br /><br /><br />And both aliases are set up for you.<br /><br />Query and bang methods (foo?, foo!) keep the same punctuation:<br /><br />  alias_method_chain :foo?, :feature<br /><br />is equivalent to<br /><br />  alias_method :foo_without_feature?, :foo?<br />  alias_method :foo?, :foo_with_feature?<br /><br />so you can safely chain foo, foo?, and foo! with the same feature. <br /><pre name="code" class="ruby">
module ActiveRecord
  # Active Record automatically timestamps create and update operations if the table has fields
  # named created_at/created_on or updated_at/updated_on.
  #
  # Timestamping can be turned off by setting
  #   &lt;tt>ActiveRecord::Base.record_timestamps = false&lt;/tt>
  #
  # Timestamps are in the local timezone by default but can use UTC by setting
  #   &lt;tt>ActiveRecord::Base.default_timezone = :utc&lt;/tt>
  module Timestamp
    def self.included(base) #:nodoc:
      base.alias_method_chain :create, :timestamps
      base.alias_method_chain :update, :timestamps
值得注意的是 :create , :update 这两个方法均为实例方法，它和类方法 :create ,:update 重名，但最终类方法也要去掉实例的:create 和 :update方法。

   这里并不是把实例方法用别名定义为类方法。   再说也不可能把实例方法定义为类方法
。
base.class_inheritable_accessor :record_timestamps, :instance_writer => false
      base.record_timestamps = true
    end

    private
      def create_with_timestamps #:nodoc:
        if record_timestamps
          t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
          write_attribute('created_at', t) if respond_to?(:created_at) && created_at.nil?
          write_attribute('created_on', t) if respond_to?(:created_on) && created_on.nil?

          write_attribute('updated_at', t) if respond_to?(:updated_at)
          write_attribute('updated_on', t) if respond_to?(:updated_on)
        end
        create_without_timestamps
      end

      def update_with_timestamps #:nodoc:
        if record_timestamps
          t = self.class.default_timezone == :utc ? Time.now.utc : Time.now
          write_attribute('updated_at', t) if respond_to?(:updated_at)
          write_attribute('updated_on', t) if respond_to?(:updated_on)
        end
        update_without_timestamps
      end
  end
end

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/210244#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Jul 2008 18:03:24 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/210244</link>
        <guid>http://hooney.javaeye.com/blog/210244</guid>
      </item>
      <item>
        <title>javascript Math reference</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/209519" style="color:red;">http://hooney.javaeye.com/blog/209519</a>&nbsp;
          发表时间: 2008年06月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.w3schools.com/jsref/jsref_obj_math.as" target="_blank">javascript Math参考</a><br /><br /><pre name="code" class="html">

Math Object Methods

FF: Firefox, N: Netscape, IE: Internet Explorer
Method 	Description 	FF 	N 	IE
abs(x) 	Returns the absolute value of a number 	1 	2 	3
acos(x) 	Returns the arccosine of a number 	1 	2 	3
asin(x) 	Returns the arcsine of a number 	1 	2 	3
atan(x) 	Returns the arctangent of x as a numeric value between -PI/2 and PI/2 radians 	1 	2 	3
atan2(y,x) 	Returns the angle theta of an (x,y) point as a numeric value between -PI and PI radians 	1 	2 	3
ceil(x) 	Returns the value of a number rounded upwards to the nearest integer 	1 	2 	3
cos(x) 	Returns the cosine of a number 	1 	2 	3
exp(x) 	Returns the value of Ex 	1 	2 	3
floor(x) 	Returns the value of a number rounded downwards to the nearest integer 	1 	2 	3
log(x) 	Returns the natural logarithm (base E) of a number 	1 	2 	3
max(x,y) 	Returns the number with the highest value of x and y 	1 	2 	3
min(x,y) 	Returns the number with the lowest value of x and y 	1 	2 	3
pow(x,y) 	Returns the value of x to the power of y 	1 	2 	3
random() 	Returns a random number between 0 and 1 	1 	2 	3
round(x) 	Rounds a number to the nearest integer 	1 	2 	3
sin(x) 	Returns the sine of a number 	1 	2 	3
sqrt(x) 	Returns the square root of a number 	1 	2 	3
tan(x) 	Returns the tangent of an angle 	1 	2 	3
toSource() 	Represents the source code of an object 	1 	4 	-
valueOf() 	Returns the primitive value of a Math object 	1 	2 	4

Math Object Properties
Property 	Description 	FF 	N 	IE 
constructor 	A reference to the function that created the object 	1 	2 	4
E 	Returns Euler's constant (approx. 2.718) 	1 	2 	3
LN2 	Returns the natural logarithm of 2 (approx. 0.693) 	1 	2 	3
LN10 	Returns the natural logarithm of 10 (approx. 2.302) 	1 	2 	3
LOG2E 	Returns the base-2 logarithm of E (approx. 1.414) 	1 	2 	3
LOG10E 	Returns the base-10 logarithm of E (approx. 0.434) 	1 	2 	3
PI 	Returns PI (approx. 3.14159) 	1 	2 	3
prototype 	Allows you to add properties and methods to the object 	1 	2 	4
SQRT1_2 	Returns the square root of 1/2 (approx. 0.707) 	1 	2 	3
SQRT2 	Returns the square root of 2 (approx. 1.414) 	1 	2 	3
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/209519#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 29 Jun 2008 20:43:09 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/209519</link>
        <guid>http://hooney.javaeye.com/blog/209519</guid>
      </item>
      <item>
        <title>redcloth 安装至ruby on rails 项目中</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/208838" style="color:red;">http://hooney.javaeye.com/blog/208838</a>&nbsp;
          发表时间: 2008年06月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.  拷贝redcloth.rb到ror的lib目录内。<br /><br />2.  拷贝jstoolbar相关的javascript 、stylesheet、images到对应的public目录里面。另外把压缩包里的help目录完整地拷贝到public目录下，其是redcloth语法的使用帮助.<br /><br />3.  在application的helper方法中添加如下两个方法：<br /><pre name="code" class="ruby">require 'redcloth'       #在application_helper 文件头引入redcloth

       用于页中生成相应textarea框的jstoolbar方法。
  def wikitoolbar_for(field_id)
    help_link = "文本格式化" + ': ' +
      link_to("帮助", compute_public_path('wiki_syntax', 'help', 'html'),
                              :onclick => "window.open(\"#{ compute_public_path('wiki_syntax', 'help', 'html') }\", \"\", \"resizable=yes, location=no, 
width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;")

    javascript_include_tag('jstoolbar/jstoolbar') +
      javascript_include_tag("jstoolbar/lang/jstoolbar-zh") +
      javascript_tag("var toolbar = new jsToolBar($('#{field_id}')); toolbar.setHelpLink('#{help_link}'); toolbar.draw();")
  end
  
     在view中格式化要显示的文本.
  def textilizable(text)
    RedCloth.new(h(text)).to_html
  end</pre><br /><br /><br />4. 最后，在你的全局stylesheet里面引入jstoolbar.css文件，完成安装。
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/208838#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 27 Jun 2008 22:45:48 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/208838</link>
        <guid>http://hooney.javaeye.com/blog/208838</guid>
      </item>
      <item>
        <title>rails route</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/208180" style="color:red;">http://hooney.javaeye.com/blog/208180</a>&nbsp;
          发表时间: 2008年06月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">
      # ==== Relying on named routes
      #
      # If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter,
      # you'll trigger the named route for that record. The lookup will happen on the name of the class. So passing
      # a Workshop object will attempt to use the workshop_path route. If you have a nested route, such as 
      # admin_workshop_path you'll have to call that explicitly (it's impossible for url_for to guess that route). 
      #

有这样一个路由：
map.show_forums_topic '/forums/:forum_id/topics/:topic_id/', :controller=>'topic', :action=>'show'
我们就可以用来映射到些地址：
redirect_to show_forums_topic(@forums,@topic)
或者编辑：redirect_to edit_forums_topic(@forums,@topic)
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/208180#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 26 Jun 2008 11:55:03 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/208180</link>
        <guid>http://hooney.javaeye.com/blog/208180</guid>
      </item>
      <item>
        <title>ruby 日期</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/207815" style="color:red;">http://hooney.javaeye.com/blog/207815</a>&nbsp;
          发表时间: 2008年06月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">
difference = Time.now - time
    seconds    =  difference % 60
    difference = (difference - seconds) / 60
    minutes    =  difference % 60
    difference = (difference - minutes) / 60
    hours      =  difference % 24
    difference = (difference - hours)   / 24
    days       =  difference % 7
    difference = (difference - days)    /  7
    weeks      =  difference % 4
    difference = (difference - weeks)   / 4
    months     =  difference % 12
    years      = (difference - months)  / 12

puts "(#{years} years , #{months} months ,#{weeks} weeks, #{days} days, #{hours}:#{minutes}:#{seconds})"
</pre><br /><br /><br />rail 实现<br /><br /><pre name="code" class="ruby">
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
        from_time = from_time.to_time if from_time.respond_to?(:to_time)
        to_time = to_time.to_time if to_time.respond_to?(:to_time)
        distance_in_minutes = (((to_time - from_time).abs)/60).round
        distance_in_seconds = ((to_time - from_time).abs).round

        case distance_in_minutes
          when 0..1
            return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
            case distance_in_seconds
              when 0..4   then 'less than 5 seconds'
              when 5..9   then 'less than 10 seconds'
              when 10..19 then 'less than 20 seconds'
              when 20..39 then 'half a minute'
              when 40..59 then 'less than a minute'
              else             '1 minute'
            end

          when 2..44           then "#{distance_in_minutes} minutes"
          when 45..89          then 'about 1 hour'
          when 90..1439        then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
          when 1440..2879      then '1 day'
          when 2880..43199     then "#{(distance_in_minutes / 1440).round} days"
          when 43200..86399    then 'about 1 month'
          when 86400..525599   then "#{(distance_in_minutes / 43200).round} months"
          when 525600..1051199 then 'about 1 year'
          else                      "over #{(distance_in_minutes / 525600).round} years"
        end
      end
</pre><br /><br />中文实现:<br /><pre name="code" class="ruby">
  #相对现在来格式化时间
  def time_ago_in_words_zh(from_time, include_seconds = false)
    distance_of_time_in_words(from_time,Time.now,include_seconds)
  end
  
  def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
    from_time = from_time.to_time if from_time.respond_to?(:to_time)
    to_time = to_time.to_time if to_time.respond_to?(:to_time)
    distance_in_minutes = (((to_time - from_time).abs)/60).round
    distance_in_seconds = ((to_time - from_time).abs).round

    case distance_in_minutes
      when 0..1
        return ' 1 分钟' unless include_seconds
        case distance_in_seconds
          when 0..4   then ' 5 秒'
          when 5..9   then ' 10 秒'
          when 10..19 then ' 20 秒'
          when 20..39 then ' 半分钟'
          else             ' 1 分钟'
        end

      when 2..44           then " #{distance_in_minutes} 分钟"
      when 45..1439        then " #{(distance_in_minutes.to_f / 60.0).round} 小时"
      when 1440..2879      then ' 昨天'
      when 2880..4319      then ' 前天'
      when 4320..43199     then " #{(distance_in_minutes / 1440).round} 天"
      when 43200..525599   then " #{(distance_in_minutes / 43200).round} 个月"
      else                      " #{(distance_in_minutes / 525600).round} 年"
    end
  end
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/207815#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 25 Jun 2008 12:38:51 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/207815</link>
        <guid>http://hooney.javaeye.com/blog/207815</guid>
      </item>
      <item>
        <title>使用include中嵌Hash取出一个多层次的对象关联数据</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/195706" style="color:red;">http://hooney.javaeye.com/blog/195706</a>&nbsp;
          发表时间: 2008年05月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用include中嵌Hash取出一个多层次的对象关联数据.<br /><br />首先有如下关系:<br /><pre name="code" class="ruby">
project issue  : 一对多
issue comment : 一对多
comment history : 一对多
Project ［1］ &lt;---- [n] issue (1) &lt;---- (n) comment [1] &lt;---- [n] history
</pre><br /><br /><pre name="code" class="ruby">
class Project
  has_many :issues
end
</pre><br /><br /><pre name="code" class="ruby">
class Issue
  belongs_to :project
  has_many :cccc      # cccc  为了区别后面的名称不致混淆

#在issue中创建一条与之对应的comment,这里用实例变量为了方便在issue保存的时候也一同保存comment的信息。
  def init_comment(content = "")
    @current_comment ||= Comment.new(:resource => self, :creater => current_user, :content => content)
    @issue_before_change = self.clone
    @current_comment
  end
  
#issue保存的时候一同保存comment，以及histories的信息。
##这里需要注意的是，要保证histories表中的comment_id(histories表中与comment关联的外键) `comment_id` int(11) default '0', 必需设置一个默认值，否则将不能保存comment 和 history的信息。
  def before_save
    if @current_comment
      # attributes changes
      (Issue.column_names - %w(id content resource_id resource_type)).each {|c|
        @current_comment.histories &lt;&lt; History.new(:property=>c,
                                                  :comment => @current_comment,
                                                  :old_value => @issue_before_change.send(c),
                                                  :value => send(c)) unless send(c)==@issue_before_change.send(c)
      }
      @current_comment.save
    end
    # Save the issue even if the comment is not saved (because empty)
    true
  end

end
</pre><br /><br /><pre name="code" class="ruby">
class Comment
  belongs_to :issue
  has_many :histories
end
</pre><br /><br /><pre name="code" class="ruby">
class History
  belongs_to :comment
end
</pre><br /><br />一条语句实现取出这其中的所有记录：<br /><pre name="code" class="ruby">
Project.find(:first,:include =>[{ :issue => { :cccc => { :histories => :comment }}}]
注意，include中的关联的名称要对应好。
</pre><br /><br /><pre name="code" class="ruby">
API 中的相关使用介绍
To include a deep hierarchy of associations, use a hash:

  for post in Post.find(:all, :include => [ :author, { :comments => { :author => :gravatar } } ])

That‘ll grab not only all the comments but all their authors and gravatar pictures. You can mix and match symbols, arrays and hashes in any combination to describe the associations you want to load.

All of this power shouldn‘t fool you into thinking that you can pull out huge amounts of data with no performance penalty just because you‘ve reduced the number of queries. The database still needs to send all the data to Active Record and it still needs to be processed. So it‘s no catch-all for performance problems, but it‘s a great way to cut down on the number of queries in a situation as the one described above.

Since the eager loading pulls from multiple tables, you‘ll have to disambiguate any column references in both conditions and orders. So :order => "posts.id DESC" will work while :order => "id DESC" will not. Because eager loading generates the SELECT statement too, the :select option is ignored.

You can use eager loading on multiple associations from the same table, but you cannot use those associations in orders and conditions as there is currently not any way to disambiguate them. Eager loading will not pull additional attributes on join tables, so "rich associations" with has_and_belongs_to_many are not a good fit for eager loading.

When eager loaded, conditions are interpolated in the context of the model class, not the model instance. Conditions are lazily interpolated before the actual model exists. 

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/195706#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 May 2008 16:09:45 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/195706</link>
        <guid>http://hooney.javaeye.com/blog/195706</guid>
      </item>
      <item>
        <title>getAttribute的返回值类型(Firefox与IE兼容性)</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/186470" style="color:red;">http://hooney.javaeye.com/blog/186470</a>&nbsp;
          发表时间: 2008年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在改AJAXRequest的过程中，碰到了个问题，应该算是Firefox和IE之间的兼容性问题。<br /><br />提交表单时，往往需要先对表单进行验证，而这个验证的过程一般是放在form标签的onsubmit属性中。<br /><br />onsubmit一般是由浏览器在form的submit动作发生时自动触发，但是如果表单由我们自己来提交，比如在AJAX应用中，就是由我们自己写程序将表单转换成请求字符串，再通过XMLHttpRequest发送到服务器，那么如果在此同时不丢掉表单验证的话，就需要我们自己来获取 onsubmit属性，并去处理它。<br /><br />在获取属性时，为了保证兼容性，我用getAttribute来获取标签的属性值，但是发获取了onsubmit属性之后，发现在Firefox和IE中使用getAttribute("onsubmit")所返回的返回值类型是不同的。<br /><br />测试代码如下：<br /><br />===================================================<br /><br />// code by xujiwei from www.xujiwei.cn&lt;br /><br />// Firefox中提示框内容为string，IE中为function&lt;br /><br />&lt;form id="test" onsubmit="return validform();"><br />    Name: &lt;input type="text" id="name" />&lt;br /><br />    &lt;input type="button" onclick="validate();" value="Validate" /><br />&lt;/form><br />&lt;script type="text/javascript"><br />&lt;!--<br />    function validform() {<br />        return (document.getElementById("name").value!="");<br />    }<br />    alert(typeof(document.getElementById("test").getAttribute("onsubmit")));<br />//--><br />&lt;/script><br /><br />===================================================<br /><br />在Firefox中使用getAttribute("onsubmit")返回值的是一个字符串，而在IE中的返回值类型则是function，也就是一个函数，因此如果在IE中处理onsubmit，我们可以直接调用这个函数：<br /><br />===================================================<br /><br />// code by xujiwei from www.xujiwei.cn&lt;br /><br />// 注意，下面这段代码只能在IE中正常运行&lt;br /><br />&lt;form id="test" onsubmit="return validform();"><br />    Name: &lt;input type="text" id="name" />&lt;br /><br />    &lt;input type="button" onclick="validate();" value="Validate" /><br />&lt;/form><br />&lt;script type="text/javascript"><br />&lt;!--<br />    function validform() {<br />        return (document.getElementById("name").value!="");<br />    }<br />    function validate() {<br />        var vaf=document.getElementById("test").getAttribute("onsubmit");<br />        if(vaf())<br />            alert("OK");<br />        else<br />            alert("Error");<br />    }<br />//--><br />&lt;/script><br /><br />===================================================<br /><br />但是，在Firefox中，使用getAttribute("onsubmit")返回的是一个字符串，因此就不能直接这样使用了，而应该将字符串转换成函数再去调用：<br /><br />===================================================<br /><br />// code by xujiwei from www.xujiwei.cn&lt;br /><br />// 注意，下面这段代码只能在Firefox中正常运行&lt;br /><br />&lt;form id="test" onsubmit="return validform();"><br />    Name: &lt;input type="text" id="name" />&lt;br /><br />    &lt;input type="button" onclick="validate();" value="Validate" /><br />&lt;/form><br />&lt;script type="text/javascript"><br />&lt;!--<br />    function validform() {<br />        return (document.getElementById("name").value!="");<br />    }<br />    function validate() {<br />        // 使用new Function将字符串转换成函数<br />        var vaf=new Function(document.getElementById("test").getAttribute("onsubmit"));<br />        if(vaf())<br />            alert("OK");<br />        else<br />            alert("Error");<br />    }<br />//--><br />&lt;/script><br /><br />===================================================<br /><br />如果把上面这段代码在IE中运行，那么会发现无论是否在输入框中输入值，都会显示“Error”。<br /><br />因此，如果要解决这个问题，可以在使用getAttribute获取onsubmit属性值之后，判断返回值类型是否为字符串，如果是字符串就使用new Function将它转换成函数：<br /><br />===================================================<br /><br />// code by xujiwei from www.xujiwei.cn&lt;br /><br />// 注意，下面这段代码在Firefox和IE中均能正常运行&lt;br /><br />&lt;form id="test" onsubmit="return validform();"><br />    Name: &lt;input type="text" id="name" />&lt;br /><br />    &lt;input type="button" onclick="validate();" value="Validate" /><br />&lt;/form><br />&lt;script type="text/javascript"><br />&lt;!--<br />    function validform() {<br />        return (document.getElementById("name").value!="");<br />    }<br />    function validate() {<br />        var vaf=document.getElementById("test").getAttribute("onsubmit");<br />        vaf=typeof(vaf)=="string"?new Function(vaf):vaf;<br />        if(vaf())<br />            alert("OK");<br />        else<br />            alert("Error");<br />    }<br />//--><br />&lt;/script><br /><br />===================================================<br /><br />这样，就解决了使用getAttribute("onsubmit")返回值类型不一样的问题，对于其他回调函数如onclick也可以这样处理。当然，如果大家有什么更好的解决方案也可以提出来分享一下:)
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/186470#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 24 Apr 2008 17:29:25 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/186470</link>
        <guid>http://hooney.javaeye.com/blog/186470</guid>
      </item>
      <item>
        <title>多对多关联数据存储ROR</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/185272" style="color:red;">http://hooney.javaeye.com/blog/185272</a>&nbsp;
          发表时间: 2008年04月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: medium">Sku MODEL :</span><br /><pre name="code" class="ruby">
class Sku &lt; ActiveRecord::Base

  has_and_belongs_to_many :records,
      :delete_sql=>'DELETE FROM skus_records WHERE sku_id= \'#{id}\' AND record_id = #{record.id}',
      :before_remove=>:record_removed_info,
      :insert_sql =>'insert into skus_records (sku_id,record_id,createdOn) values (\'#{id}\',#{record.id},now())'

end</pre><br /><br /><br /><span style="font-size: medium">Record MODEL :</span><br /><pre name="code" class="ruby">
class Record &lt; ActiveRecord::Base
  has_and_belongs_to_many :skus,
      :delete_sql=>'DELETE FROM skus_records WHERE sku_id= \'#{record.id}\' AND record_id = #{id}',
      :before_remove=>:record_removed_info,
      :insert_sql =>'insert into skus_records (sku_id,record_id,createdOn) values (\'#{record.id}\',#{id},now())' 

end</pre><br /><br /><br />以下是在Record 模型中，指定一条记录，并把此记录与多个sku信息关联。<br /><br /><pre name="code" class="ruby">
sku_models = []
[1,2,3,4,5,6,7].each do |id|
sku = Sku.find_by_skuid(id)
sku_models &lt;&lt; sku unless sku.nil?
end
record_m = Record.find(224)
record_m.skus.concat(sku_models) unless record_m.nil?   # 向 record 224 的记录添加多个sku的信息。

record_m.skus.delete(sku_models)  # 从 record 224中删除指定的sku的对应关系。
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/185272#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 22 Apr 2008 10:16:33 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/185272</link>
        <guid>http://hooney.javaeye.com/blog/185272</guid>
      </item>
      <item>
        <title>HowToRunBackgroundJobsInRails--ap4r</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/180906" style="color:red;">http://hooney.javaeye.com/blog/180906</a>&nbsp;
          发表时间: 2008年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://ap4r.rubyforge.org/wiki/wiki.pl?GettingStarted" target="_blank">http://ap4r.rubyforge.org/wiki/wiki.pl?GettingStarted</a><br /><br />   <ol><li>1.  Business logics can be implemented as simple Web applications, or ruby code, whether it's called asynchronously or synchronously.</li><li>   2. Asynchronous messaging is reliable by RDBMS persistence (now MySQL only) or file persistence, under the favor of reliable-msg.</li><li>   3. Load balancing over multiple AP4R processes on single/multiple server(s) is supported.</li><li>   4. Asynchronous logics are called via various protocols, such as XML-RPC, SOAP, HTTP POST, and more. </li></ol><br /><br />未完待续`````````````````````<br /><br />http://www.infoq.com/cn/news/2007/06/messaging-with-ap4r
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/180906#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Apr 2008 16:59:47 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/180906</link>
        <guid>http://hooney.javaeye.com/blog/180906</guid>
      </item>
      <item>
        <title>一个表单提交多条记录的处理（Ruby on Rails)</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/180283" style="color:red;">http://hooney.javaeye.com/blog/180283</a>&nbsp;
          发表时间: 2008年04月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用的是一个一对多关联，代码如下：view: partial<br />名称：&lt;input type="text" name="invoice[][name]" /><br />描述：&lt;input type="text" name="invoice[][description]" />&lt;br/><br />rhtml:<br /><pre name="code" class="ruby">&lt;% form_tag "/purchase/save_order" do -%>
&lt;p>&lt;label for="order_name">订单:&lt;/label>&lt;%= text_field :order, :name %>&lt;/p>
&lt;p>物 品:    &lt;%= link_to_remote "增加物品",
                     :update => 'mat',
                     :url => {:action => :add_field },
                     :position => 'bottom' %>&lt;/p>
&lt;div id="mat">
    &lt;%= render :partial => 'mat_input' %>
&lt;/div>
&lt;p>&lt;%= submit_tag "提 交", :class => "submit" %>&lt;/p>
controller:
def save_order
    begin
      @order = Order.new(params[:order])
      total = params[:invoice].length
      params[:invoice].each do |invoice|
        @invoice = Invoice.new(invoice)
        @order.invoices &lt;&lt; @invoice
      end
      if request.post? and @order.save
        flash[:notice] = "#{total}条物品记录已保存"
      end
    rescue
      raise
    end
    redirect_to(:action => "index")
end

def add_field
    render :partial => 'mat_input'
end
</pre><br />关键在于partial中文本框name属性的设置
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/180283#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 07 Apr 2008 21:34:17 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/180283</link>
        <guid>http://hooney.javaeye.com/blog/180283</guid>
      </item>
      <item>
        <title>render 页面javascript调用</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/179329" style="color:red;">http://hooney.javaeye.com/blog/179329</a>&nbsp;
          发表时间: 2008年04月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          情景：<br /><pre name="code" class="java">
在使用 rail 中的 自动完成功能 auto_complete_field时，假若返回的页面中有 javascript脚本，那它将不会被返回。 必需把它用 javascript_function 方法进行改写。
a.rhtml 中 render _b.rhtml 页面。 在_b.rhtml中如果包含了 javascript脚本，则不能被render到a.rhtml中。
</pre><br /><br /><pre name="code" class="c">
我在_b.rhtml中用了auto_complete_field来对用户输入进去提示。因为auto_complete_result 返回的已经是javascript脚本了，就不能把javascript发送给客户端。
</pre><br /><br />解决方法：<br /><pre name="code" class="ruby">
在application_helper.rb中覆盖此方法：不返回javascript脚本，把结果放到_b.rhtml中 用javascript_function方法把脚本输出到客户端。

  def auto_complete_field_no_javascript_tag(field_id, options = {})
    function =  "var #{field_id}_auto_completer = new Ajax.Autocompleter("
    function &lt;&lt; "'#{field_id}', "
    function &lt;&lt; "'" + (options[:update] || "#{field_id}_auto_complete") + "', "
    function &lt;&lt; "'#{url_for(options[:url])}'"

    js_options = {}
    js_options[:tokens] = array_or_string_for_javascript(options[:tokens]) if options[:tokens]
    js_options[:callback]   = "function(element, value) { return #{options[:with]} }" if options[:with]
    js_options[:indicator]  = "'#{options[:indicator]}'" if options[:indicator]
    js_options[:select]     = "'#{options[:select]}'" if options[:select]
    js_options[:paramName]  = "'#{options[:param_name]}'" if options[:param_name]
    js_options[:frequency]  = "#{options[:frequency]}" if options[:frequency]

    { :after_update_element => :afterUpdateElement, 
      :on_show => :onShow, :on_hide => :onHide, :min_chars => :minChars }.each do |k,v|
      js_options[v] = options[k] if options[k]
  end

    function &lt;&lt; (', ' + options_for_javascript(js_options) + ')')

    function
  end

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/179329#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Apr 2008 17:18:57 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/179329</link>
        <guid>http://hooney.javaeye.com/blog/179329</guid>
      </item>
      <item>
        <title>mysql进行优化</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/178936" style="color:red;">http://hooney.javaeye.com/blog/178936</a>&nbsp;
          发表时间: 2008年04月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          mysql进行优化的地方，简单总结几点：<br />在设计数据表的时候，尽可能使用最有效(最小的)数据类型，尽可能使用更小的整数类型,可能定义字段类型为 NOT NULL。这会运行的更快，而且每个字段都会节省1个bit。如果在应用程序中确实需要用到 NULL，那么就明确的指定它。不过要避免所有的字段默认值是 NULL),尽可能使用最有效(最小的)数据类型。MySQL有好几种特定的类型能节省磁盘和内存。 尽可能使用更小的整数类型。在 MyISAM 表中，如果没有用到任何变长字段(VARCHAR, TEXT, 或 BLOB字段)的话，那么就采用固定大小的记录格式。这样速度更快，不过可能会浪费点空间。表的主索引应尽可能短。这样的话会每条记录都有名字标识且更高效。只创建确实需要的索引。索引有利于检索记录，但是不利于快速保存记录。如果总是要在表的组合字段上做搜索，那么就在这些字段上创建索引。索引的第一部分必须是最常使用的字段.如果总是需要用到很多字段，首先就应该多复制这些字段，使索引更好的压缩。一个字段很有可能在最开始的一些数量字符是各不相同的，因此在这些字符上做索引更合适。MySQL支持在一个字段的最左部分字符做索引。索引越短，速度越快，不仅是因为它占用更少的磁盘空间，也因为这提高了索引缓存的命中率，由此减少了磁盘搜索。在某些情况下，把一个频繁扫描的表分割成两个更有利。在对动态格式表扫描以取得相关记录时，它可能使用更小的静态格式表的情况下更是如此。<br /><br />进行数据库操作的时候，能有多简单就有多简单，能不用圆括号就不用圆括号，去掉那些多余的选项，能用SQL解决的就不要用程序语言来处理(mysql处理的速度比解析语言快很多)；<br /><br />删除表中所有数据的时候，用效率更高的TRUNCATE TABLE tbl_name 而不是DELETE FROM tbl_name；<br /><br />在锁表的情况下，更新多个记录比多次更新记录要快很多，因此：推迟更新并且把很多次更新放在后面一起做。<br /><br />数据库在连接时的开销很大，一个页面行不要有多次对库进行连接和关闭的操作！<br /><br />经常需要读写操作的表用 MEMORY(HEAP)表！
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/178936#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Apr 2008 17:57:54 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/178936</link>
        <guid>http://hooney.javaeye.com/blog/178936</guid>
      </item>
      <item>
        <title>Extreme Programming Applied PlAYING TO WIN</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/178597" style="color:red;">http://hooney.javaeye.com/blog/178597</a>&nbsp;
          发表时间: 2008年04月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          第四章 说服有抵触情绪的人<br />  <span style="font-size: x-small">无论是什么原因使您做出决定，都永远会有人说您错了。也总会有困难让您相信批评您的人是正确的。<br />  制订一条行动路线，沿着它坚持走下去，是需要具有与士兵一样的勇气的。</span><br />---------Ralph Waldo Emerson<br /><br />4.1. <span style="font-size: medium"><strong>抵制主要来自两方面：经理和开发人员。</strong></span><br />    经理和开发人员经常会因为骄傲而成为其牺牲品。这两种人都惧怕变化，不愿承认他们需要学习新的知识。这是来自这一群人的诸多抵触情绪中最关键的部分。您会遇到的抵制远不像这些这么简单，而且也并不是一开始就全部暴露的。您要有思想准备，随时都应准备处理这类问题。<br />4.2. <strong>有说服力的结果</strong><br />   如果XP很快就能产生较好的结果，又比旧的方法少忍受些痛苦，经理和开发人员就不会再说团队应该按照旧的方法工作了，不会仅仅是因为大家熟悉这些方法。如果他们仍坚持这样做，我看您应该考虑离开这家公司了。<br />4.3.  <strong>不该做的事情</strong><br />    如果一个方法能增加获得结果的机会，就去使用这个方法吧。反之，就不要去理会它，或者改变它使其能在现有环境下成功。<br />    记住获得结果才是目标，而不是XP本身或者您是不是正确。
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/178597#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Apr 2008 22:58:13 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/178597</link>
        <guid>http://hooney.javaeye.com/blog/178597</guid>
      </item>
      <item>
        <title>MySql的字符串函数</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/176996" style="color:red;">http://hooney.javaeye.com/blog/176996</a>&nbsp;
          发表时间: 2008年03月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">


MySql的字符串函数

ASCII(str)
    返回字符串str的最左面字符的ASCII代码值。如果str是空字符串，返回0。如果str是NULL，返回NULL。

    mysql> select ASCII('2');
              -> 50
    mysql> select ASCII(2);
              -> 50
    mysql> select ASCII('dx');
              -> 100

    也可参见ORD()函数。
ORD(str)
    如果字符串str最左面字符是一个多字节字符，通过以格式((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]返回字符的ASCII代码值来返回多字节字符代码。如果最左面的字符不是一个多字节字符。返回与ASCII()函数返回的相同值。

    mysql> select ORD('2');
              -> 50
     

CONV(N,from_base,to_base)
    在不同的数字基之间变换数字。返回数字N的字符串数字，从from_base基变换为to_base基，如果任何参数是NULL，返回NULL。参数N解释为一个整数，但是可以指定为一个整数或一个字符串。最小基是2且最大的基是36。如果to_base是一个负数，N被认为是一个有符号数，否则，N被当作无符号数。 CONV以64位点精度工作。

    mysql> select CONV("a",16,2);
              -> '1010'
    mysql> select CONV("6E",18,8);
              -> '172'
    mysql> select CONV(-17,10,-18);
              -> '-H'
    mysql> select CONV(10+"10"+'10'+0xa,10,10);
              -> '40'
     

BIN(N)
    返回二进制值N的一个字符串表示，在此N是一个长整数(BIGINT)数字，这等价于CONV(N,10,2)。如果N是NULL，返回NULL。

    mysql> select BIN(12);
              -> '1100'

OCT(N)
    返回八进制值N的一个字符串的表示，在此N是一个长整型数字，这等价于CONV(N,10,8)。如果N是NULL，返回NULL。

    mysql> select OCT(12);
              -> '14'
     

HEX(N)
    返回十六进制值N一个字符串的表示，在此N是一个长整型(BIGINT)数字，这等价于CONV(N,10,16)。如果N是NULL，返回NULL。

    mysql> select HEX(255);
              -> 'FF'
     

CHAR(N,...)
    CHAR()将参数解释为整数并且返回由这些整数的ASCII代码字符组成的一个字符串。NULL值被跳过。

    mysql> select CHAR(77,121,83,81,'76');
              -> 'MySQL'
    mysql> select CHAR(77,77.3,'77.3');
              -> 'MMM'
     

CONCAT(str1,str2,...)
    返回来自于参数连结的字符串。如果任何参数是NULL，返回NULL。可以有超过2个的参数。一个数字参数被变换为等价的字符串形式。

    mysql> select CONCAT('My', 'S', 'QL');
              -> 'MySQL'
    mysql> select CONCAT('My', NULL, 'QL');
              -> NULL
    mysql> select CONCAT(14.3);
              -> '14.3'

LENGTH(str)
    　 
OCTET_LENGTH(str)
    　 
CHAR_LENGTH(str)
    　 
CHARACTER_LENGTH(str)
    返回字符串str的长度。

    mysql> select LENGTH('text');
              -> 4
    mysql> select OCTET_LENGTH('text');
              -> 4

    注意，对于多字节字符，其CHAR_LENGTH()仅计算一次。
LOCATE(substr,str)
    　 
POSITION(substr IN str)
    返回子串substr在字符串str第一个出现的位置，如果substr不是在str里面，返回0.

    mysql> select LOCATE('bar', 'foobarbar');
              -> 4
    mysql> select LOCATE('xbar', 'foobar');
              -> 0

    该函数是多字节可靠的。  

LOCATE(substr,str,pos)
    返回子串substr在字符串str第一个出现的位置，从位置pos开始。如果substr不是在str里面，返回0。

    mysql> select LOCATE('bar', 'foobarbar',5);
              -> 7

    这函数是多字节可靠的。
INSTR(str,substr)
    返回子串substr在字符串str中的第一个出现的位置。这与有2个参数形式的LOCATE()相同，除了参数被颠倒。

    mysql> select INSTR('foobarbar', 'bar');
              -> 4
    mysql> select INSTR('xbar', 'foobar');
              -> 0

    这函数是多字节可靠的。
LPAD(str,len,padstr)
    返回字符串str，左面用字符串padstr填补直到str是len个字符长。

    mysql> select LPAD('hi',4,'??');
              -> '??hi'
     

RPAD(str,len,padstr)
    返回字符串str，右面用字符串padstr填补直到str是len个字符长。    

    mysql> select RPAD('hi',5,'?');
              -> 'hi???'

LEFT(str,len)
    返回字符串str的最左面len个字符。

    mysql> select LEFT('foobarbar', 5);
              -> 'fooba'

    该函数是多字节可靠的。
RIGHT(str,len)
    返回字符串str的最右面len个字符。

    mysql> select RIGHT('foobarbar', 4);
              -> 'rbar'

    该函数是多字节可靠的。
SUBSTRING(str,pos,len)
    　 
SUBSTRING(str FROM pos FOR len)
    　 
MID(str,pos,len)
    从字符串str返回一个len个字符的子串，从位置pos开始。使用FROM的变种形式是ANSI SQL92语法。

    mysql> select SUBSTRING('Quadratically',5,6);
              -> 'ratica'

    该函数是多字节可靠的。
SUBSTRING(str,pos)
    　 
SUBSTRING(str FROM pos)
    从字符串str的起始位置pos返回一个子串。

    mysql> select SUBSTRING('Quadratically',5);
              -> 'ratically'
    mysql> select SUBSTRING('foobarbar' FROM 4);
              -> 'barbar'






</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/176996#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Mar 2008 17:52:39 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/176996</link>
        <guid>http://hooney.javaeye.com/blog/176996</guid>
      </item>
      <item>
        <title>统计一个字段中出现 ( 多个指定词) 的出现的次数</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/175914" style="color:red;">http://hooney.javaeye.com/blog/175914</a>&nbsp;
          发表时间: 2008年03月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="ruby">mysql>select sum(if(locate(',watch,',concat(",",seokeyword,","))>0,1,0)) as watch,sum(if(locate(',fashion watch,',concat(',',seokeyword,',')>0,1,0)) as `fashion watch` 
from uxcell_channels;

+-------+---------------+
| watch | fashion watch |
+-------+---------------+
|   928 |           501 | 
+-------+---------------+
</pre><br /><pre name="code" class="ruby">
ux.first.attributes
ux.first.attributes.keys</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/175914#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 25 Mar 2008 17:06:15 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/175914</link>
        <guid>http://hooney.javaeye.com/blog/175914</guid>
      </item>
      <item>
        <title>SQL语句优化技术分析</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/174402" style="color:red;">http://hooney.javaeye.com/blog/174402</a>&nbsp;
          发表时间: 2008年03月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          抄自: http://www.phpchina.com/1628/viewspace_9576.html<br />操作符优化<br /><br />IN 操作符<br /><br />用IN写出来的SQL的优点是比较容易写及清晰易懂，这比较适合现代软件开发的风格。<br /><br />但是用IN的SQL性能总是比较低的：<br />    数据库试图将其转换成多个表的连接，如果转换不成功则先执行IN里面的子查询，再查询外层的表记录，如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功，但对于含有分组统计等方面的SQL就不能转换了。<br /><br />    推荐方案：在业务密集的SQL当中尽量不采用IN操作符。<br /><br />NOT IN操作符<br /><br />    此操作是强列推荐不使用的，因为它不能应用表的索引。<br /><br />    推荐方案：用NOT EXISTS 或（外连接+判断为空）方案代替<br /><br />&lt;> 操作符（不等于）<br /><br />    不等于操作符是永远不会用到索引的，因此对它的处理只会产生全表扫描。<br /><br />推荐方案：用其它相同功能的操作运算代替，如<br /><br />    a&lt;>0 改为 a>0 or a&lt;0<br /><br />    a&lt;>’’ 改为 a>’’<br /><br />IS NULL 或IS NOT NULL操作（判断字段是否为空）<br /><br />    判断字段是否为空一般是不会应用索引的，因为B树索引是不索引空值的。<br /><br />    推荐方案：<br /><br />用其它相同功能的操作运算代替，如<br /><br />    a is not null 改为 a>0 或a>’’等。<br /><br />    不允许字段为空，而用一个缺省值代替空值，如业扩申请中状态字段不允许为空，缺省为申请。<br /><br />    建立位图索引（有分区的表不能建，位图索引比较难控制，如字段值太多索引会使性能下降，多人更新操作会增加数据块锁的现象）<br /><br /><br /><br />> 及 &lt; 操作符（大于或小于操作符）<br /><br />    大于或小于操作符一般情况下是不用调整的，因为它有索引就会采用索引查找，但有的情况下可以对它进行优化，如一个表有100万记录，一个数值型字段A， 30万记录的A=0，30万记录的A=1，39万记录的A=2，1万记录的A=3。那么执行A>2与A>=3的效果就有很大的区别了，因为 A>2时数据库会先找出为2的记录索引再进行比较，而A>=3时数据库则直接找到=3的记录索引。<br /><br /><br /><br />LIKE操作符<br /><br />LIKE 操作符可以应用通配符查询，里面的通配符组合可能达到几乎是任意的查询，但是如果用得不好则会产生性能上的问题，如LIKE ‘%5400%’ 这种查询不会引用索引，而LIKE ‘X5400%’则会引用范围索引。一个实际例子：用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描，如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询，性能肯定大大提高。<br /><br /><br /><br />UNION操作符<br /><br />UNION在进行表链接后会筛选掉重复的记录，所以在表链接后会对所产生的结果集进行排序运算，删除重复的记录再返回结果。实际大部分应用中是不会产生重复的记录，最常见的是过程表与历史表UNION。如：<br /><br />select * from gc_dfys<br /><br />union<br /><br />select * from ls_jg_dfys<br /><br />这个SQL在运行时先取出两个表的结果，再用排序空间进行排序删除重复的记录，最后返回结果集，如果表数据量大的话可能会导致用磁盘进行排序。<br /><br />推荐方案：采用UNION ALL操作符替代UNION，因为UNION ALL操作只是简单的将两个结果合并后就返回。<br /><br />select * from gc_dfys<br /><br />union all<br /><br />select * from ls_jg_dfys<br /><br /><br /><br />SQL书写的影响<br /><br />同一功能同一性能不同写法SQL的影响<br /><br />如一个SQL在A程序员写的为<br /><br />    Select * from zl_yhjbqk<br /><br />B程序员写的为<br /><br />    Select * from dlyx.zl_yhjbqk（带表所有者的前缀）<br /><br />C程序员写的为<br /><br />    Select * from DLYX.ZLYHJBQK（大写表名）<br /><br />D程序员写的为<br /><br />    Select * from DLYX.ZLYHJBQK（中间多了空格）<br /><br /><br /><br /><br />WHERE后面的条件顺序影响<br /><br /><br /><br />WHERE子句后面的条件顺序对大数据量表的查询会产生直接的影响，如<br /><br />Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1<br /><br />Select * from zl_yhjbqk where xh_bz=1 and dy_dj = '1KV以下'<br /><br />以上两个SQL中dy_dj（电压等级）及xh_bz（销户标志）两个字段都没进行索引，所以执行的时候都是全表扫描，第一条SQL的dy_dj = '1KV以下'条件在记录集内比率为99%，而xh_bz=1的比率只为0.5%，在进行第一条SQL的时候99%条记录都进行dy_dj及xh_bz的比较，而在进行第二条SQL的时候0.5%条记录都进行dy_dj及xh_bz的比较，以此可以得出第二条SQL的CPU占用率明显比第一条低。<br /><br /><br /><br />SQL语句索引的利用<br /><br />对操作符的优化（见上节）<br /><br />对条件字段的一些优化<br /><br />采用函数处理的字段不能利用索引，如：<br /><br />substr(hbs_bh,1,4)=’5400’，优化处理：hbs_bh like ‘5400%’<br /><br />trunc(sk_rq)=trunc(sysdate)， 优化处理：<br /><br />sk_rq>=trunc(sysdate) and sk_rq&lt;trunc(sysdate+1)<br /><br />进行了显式或隐式的运算的字段不能进行索引，如：<br /><br />ss_df+20>50，优化处理：ss_df>30<br /><br />‘X’||hbs_bh>’X5400021452’，优化处理：hbs_bh>’5400021542’<br /><br />sk_rq+5=sysdate，优化处理：sk_rq=sysdate-5<br /><br />hbs_bh=5401002554，优化处理：hbs_bh=’ 5401002554’，注：此条件对hbs_bh 进行隐式的to_number转换，因为hbs_bh字段是字符型。<br /><br />条件内包括了多个本表的字段运算时不能进行索引，如：<br /><br />ys_df>cx_df，无法进行优化<br /><br />qc_bh||kh_bh=’5400250000’，优化处理：qc_bh=’5400’ and kh_bh=’250000’<br /><br /><br /><br /><br /><pre name="code" class="java">


用   WHERE   和   HAVING   筛选行  
  SELECT   语句中的   WHERE   和   HAVING   子句控制用源表中的那些行来构造结果集。WHERE   和   HAVING   是筛选。这两个子句指定指定一系列搜索条件，只有那些满足搜索条件的行才用来构造结果集。我们称满足搜索条件的行符合参与行集的限定条件。例如，下列   SELECT   语句中的   WHERE   子句将限定只选择地区为华盛顿州   (WA)   的行：  
   
  SELECT   CustomerID,   CompanyName  
  FROM   Northwind.dbo.Customers  
  WHERE   Region   =   'WA'  
   
  HAVING   子句通常与   GROUP   BY   子句结合使用，尽管指定该子句时也可以不带   GROUP   BY。HAVING   子句指定在应用   WHERE   子句的筛选后要进一步应用的筛选。例如，下列   WHERE   子句仅限定以高于   $100   的单价销售产品的订单，而   HAVING   子句进一步将结果限制为只包括   100   件以上的订单：  
   
  SELECT   OrdD1.OrderID   AS   OrderID,  
                SUM(OrdD1.Quantity)   AS   "Units   Sold",  
                SUM(OrdD1.UnitPrice   *   OrdD1.Quantity)   AS   Revenue  
  FROM   [Order   Details]   AS   OrdD1  
  WHERE   OrdD1.OrderID   in   (SELECT   DISTINCT   OrdD2.OrderID  
                                                  FROM   [Order   Details]   AS   OrdD2  
                                                  WHERE   OrdD2.UnitPrice   >   $100)  
  GROUP   BY   OrdD1.OrderID  
  HAVING   SUM(OrdD1.Quantity)   >   100  
   
  WHERE   和   HAVING   子句中的搜索条件或限定条件可包括：    
   
  比较运算符（如   =、&lt;   >、&lt;   和   >）。例如，下列查询从   Products   表中检索产品分类为   2   的行：    
  SELECT   ProductID,   ProductName  
  FROM   Northwind.dbo.Products  
  WHERE   CategoryID   =   2  
  ORDER   BY   ProductID  
   
  范围（BETWEEN   和   NOT   BETWEEN）。例如，下列查询从   Products   表中检索产品分类从   2   到   4   的行：    
  SELECT   CategoryID,   ProductID,   ProductName  
  FROM   Northwind.dbo.Products  
  WHERE   CategoryID   BETWEEN   2   and   4  
  ORDER   BY   CategoryID,   ProductID  
   
  列表（IN、NOT   IN）。例如，下列查询从   Products   表中检索产品分类   ID   与列表中某一   ID   匹配的行：    
  SELECT   CategoryID,   ProductID,   ProductName  
  FROM   Northwind.dbo.Products  
  WHERE   CategoryID   IN   (1,4,5,7)  
  ORDER   BY   CategoryID,   ProductID  
   
  模式匹配（LIKE   和   NOT   LIKE）。例如，下列查询从   Products   表中检索产品名称以   Ch   开头的行：    
  SELECT   CategoryID,   ProductID,   ProductName  
  FROM   Northwind.dbo.Products  
  WHERE   ProductName   LIKE   'Ch%'  
  ORDER   BY   CategoryID,   ProductID  
   
   
   
  说明     可用于   text   列的   WHERE   条件只有返回其它数据类型的函数（如   PATINDEX()）或运算符（如   IS   NULL、IS   NOT   NULL、LIKE   和   NOT   LIKE）。  
   
  空值（IS   NULL   和   IS   NOT   NULL）。例如，下列查询从   Customers   表中检索客户地区不为   NULL   的行：    
  SELECT   CompanyName,   City,   Region,   Country  
  FROM   Northwind.dbo.Customers  
  WHERE   Region   IS   NOT   NULL  
  ORDER   BY   CompanyName  
   
   
   
  说明     比较空值时请谨慎从事。例如，指定   =   NULL   与指定   IS   NULL   是不同的。有关更多信息，请参见空值。  
   
  所有记录（=ALL、>ALL、&lt;=   ALL、ANY）。例如，下列查询从   Order   Details   表中检索装运产品数量大于分类   1   中任意产品的装运数量的订单和产品   ID：    
  USE   Northwind  
  GO  
  SELECT   OrdD1.OrderID,   OrdD1.ProductID  
  FROM   "Order   Details"   OrdD1  
  WHERE   OrdD1.Quantity   >   ALL  
              (SELECT   OrdD2.Quantity  
                FROM   "Order   Details"   OrdD2   JOIN   Products   Prd  
                            ON   OrdD2.ProductID   =   Prd.ProductID  
                WHERE   Prd.CategoryID   =   1)  
  GO  
   
  上述条件的组合（AND、OR、NOT）。例如，下列查询检索库存水平低于再订购点，或来自供应商   15   并属于分类   4   的所有产品：    
  SELECT   ProductID,   ProductName  
  FROM   Northwind.dbo.Products  
  WHERE   UnitsInStock   &lt;   ReorderLevel  
        OR   (SupplierID   =   15   AND   CategoryID   =   4)  
   
   
   
  说明     当在   WHERE   子句中搜索   Unicode   字符串时，请在搜索字符串之前加字符   N，例如：  
   
  SELECT   CompanyName,   ContactName,   Phone,   Fax  
  FROM   Northwind.dbo.Customers  
  WHERE   CompanyName   =   N'Berglunds   snabbk&ouml;p'   


</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/174402#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 21 Mar 2008 10:23:55 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/174402</link>
        <guid>http://hooney.javaeye.com/blog/174402</guid>
      </item>
      <item>
        <title>WEB 设计页面东东</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/174214" style="color:red;">http://hooney.javaeye.com/blog/174214</a>&nbsp;
          发表时间: 2008年03月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          Quick Start<br /><br />Some useful hints if you are new to Plone:<br /><br />    * Access key + 4 focuses the LiveSearch field - you can start writing your search terms straight away, and have all your information at your fingertips without leaving the keyboard. For information about how to use access keys in your particular browser, see the Accessibility page.<br />    * Plone will automatically be displayed in the language your browser asks for. If you need more control over languages in Plone, install Plone Language Tool from the Site Setup. If you need to maintain your content in multiple languages, download LinguaPlone.<br />    * Workflow states are color coded if you are logged in, so it is easy to keep track of content security and visibility. Try the Site Map with color coding for a visual security inspection of your site!<br />    * If you prefer working with pure HTML, Structured Text or ReStructured Text markup instead of using a visual editor, you can disable it in your preferences.<br /><br /><br />可用的访问键<br /><br />这个网站访问键设置，接近大多数国际的推荐。他们是：<br /><br />    * 1 首页<br />    * 2 跳到内容<br />    * 3 网站地图<br />    * 4 搜索<br />    * 5 高级搜索<br />    * 6 网站导航树<br />    * 9 联系信息<br />    * 0 访问键详细信息<br /><br />在不同的网站浏览器中使用访问键<br /><br />Internet Explorer 5+ (Windows)<br />    按住Alt键，敲击访问键的数字或字母，放开这两个键，敲击ENTER .<br />Firefox, Mozilla 和 Netscape 7+ (Windows)<br />    按住Alt键，敲击访问键的数字或字母。<br />Firefox, Mozilla 和 Netscape 7+ (Mac OS X)<br />    按住Ctrl键，敲击访问键的数字或字母。<br />Safari 和 Omniweb (Mac OS X)<br />    按住Ctrl键，敲击访问键的数字或字母。<br />Konqueror (Linux)<br />    按住并释放 Ctrl键，接下来敲击访问键的数字或者字母。<br />Internet Explorer 4 (Windows)<br />    按住Alt键，敲击访问键的数字或字母。<br />Internet Explorer 5+ (Mac)<br />    按住Ctrl键，敲击访问键的数字或字母。<br />Internet Explorer 4.5 (Mac)<br />    不支持访问键，请选择另外一个浏览器。<br />Netscape 6和更早版本(所有平台)<br />    不支持访问键，请使用另外一个浏览器。<br /><br />可访问性声名<br /><br />我们已经力尽所能，利用我们的知识和理解，使用为不同人提供访问因特网的各种方法，开发每个人都能使用的清晰和简单的网站。
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/174214#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 20 Mar 2008 17:08:54 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/174214</link>
        <guid>http://hooney.javaeye.com/blog/174214</guid>
      </item>
      <item>
        <title>Single table inheritance：单表继承</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/169103" style="color:red;">http://hooney.javaeye.com/blog/169103</a>&nbsp;
          发表时间: 2008年03月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div style="text-align: center"><span style="font-size: x-large">Single table inheritance：单表继承</span></div><br /><br /><br /><br />转于:<a href="http://my4java.itpub.net/post/9983/78535" target="_blank">http://my4java.itpub.net/post/9983/78535</a><br />一、介绍：<br /><br />关系数据库不支持继承，所以在将对象映射到数据库时，我们必须考虑如何在关系表中表现我们完美的继承结构。当映射到一个关系数据库时，我们试图最小化在多个表内处理一个继承体系时快速增长的结合。单表继承则将一个继承体系的所有类映射到单个表的字段中。<br /><br />在一个关系数据库内至少可以有三种形式来表现继承体系。Martin Fowler 在<a href="http://www.martinfowler.com/eaaCatalog/" target="_blank">http://www.martinfowler.com/eaaCatalog/</a>中做了简短的描述。<br /><br />1、Class Table Inheritance：继承体系中的每个类都由单个表来表现。<br /><br />2、Single Table Inheritance：继承体系中的所有类都由一个单独表中的列来表现。<br /><br />3、Concrete Table Inheritance：继承体系中的每个具体类由单个表来表现。<br /><br />可参考下面的链接：<br /><br />1、 <a href="http://www.martinfowler.com/eaaCatalog/classTableInheritance.html" target="_blank">http://www.martinfowler.com/eaaCatalog/classTableInheritance.html</a><br /><br />2、 <a href="http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html" target="_blank">http://www.martinfowler.com/eaaCatalog/singleTableInheritance.html</a><br /><br />3、 <a href="http://www.martinfowler.com/eaaCatalog/concreteTableInheritance.html" target="_blank">http://www.martinfowler.com/eaaCatalog/concreteTableInheritance.html</a><br /><br />二、“活动记录”的支持：<br /><br />“活动记录”使用第二种途径来支持继承，这意味着你必须添加一个string列，通过在列中存储类的名字，而此列缺省地称为，“type”(可以通过覆写Base.inheritance_column来修改缺省名称)。这意味着一个继承看起来是这样的：<br /><br /><pre name="code" class="ruby">class Company &lt; ActiveRecord::Base; end

class Firm &lt; Company; end

class Client &lt; Company; end

class PriorityClient &lt; Client; end</pre><br /><br />当你完成Firm.create(:name => "37signals")，这个记录将被保存在companies表中且type="firm"。然后你可以使用Company.find(:first, "name = ‘37signals’")来获取此行，并且它会返回一个Firm对象。<br /><br />如果你没有在你的表内定义type列，则不会触发单表继承。这种情况下，它只是像普通子类一样工作没什么魔术可用。<br /><br />注意，所有的属性必须位于同一表内。<br /><br /><span style="color: indigo"><strong>注意：Rails在使用STI类之前必须能看到包含它们的文件，否则你会得到“uninitialized constant”错误。如果类的名字与包含它的文件的名称不是同样的话，你可能要有麻烦。如果你在'employees.rb'文件内有个“模型”为Manager。在这种情况下，Rails将不能从类名字中分析出文件名。<br /><br />解决这个问题最简单的方式是添加“model :employees”到你的application.rb“控制器”中，那里'employees'是不带扩展名的，包含STI类的文件名(所以解决上面问题，“模型”应该包含文件名'employees.rb‘才可以。)这会强迫Rails加载此文件并看到你在其内定义的所有“模型”，然后在你使用时，Rails已经知道了你的STI类。</strong></span><br /><br />使用Employee[:type]来访问子表信息，不要使用Employee.type。type是一个Ruby废弃的方法，所以直接访问它来设置或修改行的type会导致陌生的Ruby消息。<br /><br />在使用“单个表继承时“有个明显的约束。两个子类不能有同样名字但不同type的属性，那样两个属性将被映射为同一个列。<br /><br />三、例子：<br /><pre name="code" class="ruby">
# simplified

def new

case @params[:person_type]

when "Manager"

@person = Manager.new

when "Slave"

@person = Slave.new

end

end

在你的“视图”中，完成：

&lt;%= hidden_field_tag "person_type", @person[:type] %>

然后是create方法：

#again, simplified

def create

case @params[:person_type]

when "Manager"

@person = Manager.new(@params[:person])

when "Slave"

@person = Slave.new(@params[:person])

end

if @person.save

redirect_to :action => :list

else

render_action :new

end

end

甚至你可以在你的Person类中创建一个factory类方法。

class Person &lt; ActiveRecord::Base

def self.factory(type, params = nil)

case type

when "Manager"

return Manager.new(params)

when "Slave"

return Slave.new(params)

else

return nil

end

end

end

然后，你可以在new和create方法内完成

def new

@person = Person.factory(@params[:person_type])

end

def create

@person = Person.factory(@params[:person_type], @params[:person])

if @person.save

...

end

end

你也可以使用下面方式来创建一个子类(thanks to Sean Hussey/Ezra)

person_type = "Manager"

@person = eval(person_type + ".new")

或者使用 constantize:

person_type = "Manager"

@person = person_type.constantize.new

如果你的“type”列的文本没有精确地匹配你的类名字，你可能得这样做：

class ETH &lt; ListData; end

Ethnicity = ETH</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/169103#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 07 Mar 2008 16:34:50 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/169103</link>
        <guid>http://hooney.javaeye.com/blog/169103</guid>
      </item>
      <item>
        <title>用巧命令行DIY你的xterm 颜色 for linux</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/167062" style="color:red;">http://hooney.javaeye.com/blog/167062</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在上面的示例中，我们使用了专用的用反斜杠转义的字符序列，藉此通知 bash 将用户名和主机名插入提示行中，当这些转义字符序列出现在 PS1 变量中时，bash 就会用特定的值替换它们。我们使用了序列 "\u"（表示用户名）和 "\ H"（表示主机名的第一部分）。下面是 bash 可识别的全部专用序列的完整列表（您可以在 bash man page 的  "PROMPTING" 部分找到这个列表）： <br /><br /><br /><pre name="code" class="ruby">
序列 说明 
\a ASCII 响铃字符（也可以键入 \007） 
\d "Wed Sep 06" 格式的日期 
\e ASCII 转义字符（也可以键入 \033） 
\h 主机名的第一部分（如 "mybox"） 
\H 主机的全称（如 "mybox.mydomain.com"） 
\j 在此 shell 中通过按 ^Z 挂起的进程数 
\l 此 shell 的终端设备名（如 "ttyp4"） 
\n 换行符 
\r 回车符 
\s shell 的名称（如 "bash"） 
\t 24 小时制时间（如 "23:01:01"） 
\T 12 小时制时间（如 "11:01:01"） 
\@ 带有 am/pm 的 12 小时制时间 
\u 用户名 
\v bash 的版本（如 2.04） 
\V Bash 版本（包括补丁级别） ?/td>; 
\w 当前工作目录（如 "/home/drobbins"） 
\W 当前工作目录的“基名 (basename)”（如 "drobbins"） 
\! 当前命令在历史缓冲区中的位置 
\# 命令编号（只要您键入内容，它就会在每次提示时累加） 
\$ 如果您不是超级用户 (root)，则插入一个 "$"；如果您是超级用户，则显示一个 "#" 
\xxx 插入一个用三位数 xxx（用零代替未使用的数字，如 "\007"）表示的 ASCII 字符 
\\ 反斜杠 
\[ 这个序列应该出现在不移动光标的字符序列（如颜色转义序列）之前。它使 bash 能够正确计算自动换行。 
\] 这个序列应该出现在非打印字符序列之后。 

</pre><br /><br />这样，您已经知道了 bash 中用反斜杠转义的全部专用序列。请稍微演练一下这些序列，以对它们的工作方式获得一些感性认识。在您做了一些测试之后，下面开始添加颜色。 <br /><br />彩色化 <br />添加颜色相当容易；第一步是设计不带颜色的提示行。然后，我们所要做的只是添加终端（而不是 bash）可识别的专用转义序列，以使它以彩色显示文本的某些部分。标准 Linux 终端和 X 终端允许您设置前景（文字）颜色和背景颜色，如果需要，还可以启用 "bold" 字符。有八种颜色可供我们选择。 <br /><br />颜色是通过在 PS1 中添加专用序列来选择的 -- 基本上是夹在 "\e["（转义开方括号）和 "m" 之间数字值。如果指定一个以上的数字代码，则用分号将它们分开。下面是一个颜色代码示例： <br /><br /><br />"\e[0m" <br /><br /><br /><br />如果将数字代码指定为零，则它就会通知终端将前景、背景和加粗设置重置为它们的默认值。您可能会在在提示行结束时使用这个代码，以使您键入的文字成为非彩色的。现在，让我们看一下这些颜色代码。请注意下面的抓屏结果： <br /><br />颜色表 <br /><br /><br />要使用这个表，首先请查找您要使用的颜色，然后查找对应的前景编号 (30-37) 和背景编号 (40-47)。例如，如果您喜欢黑底绿字，则可将编号分别设为 32 和 40。然后打开您的提示行定义并在其中添加适当的颜色代码。下面的定义： <br /><br /><br />export PS1="\w>; " <br /><br /><br /><br />变为： <br /><br /><br />export PS1="\e[32;40m\w>; " <br /><br /><br /><br />到现在为止，提示行尽管已经很不错了，但仍不太完美。在 bash 显示出工作目录以后，我们需要使用 "\e[0m" 序列将颜色重新设置为正常值。 <br /><br /><br />export PS1="\e[32;40m\w>; \e[0m" <br /><br /><br /><br />这个定义将显示一个漂亮的绿色提示行，但我们仍需要做一些扫尾工作。我们不需要包括 "40" 这个背景颜色设置，因为它将背景设置为黑色，而黑色是默认颜色。此外，绿色还很暗；我们通过添加一个 "1" 颜色代码来修正这个问题，这将启用更亮的加粗文字。除了这个修改之外，我们还需要将全部非打印字符用专用的 bash 转义序列 "\[" 和 "\]" 括起来。这两个序列通知 bash，被括起来的字符不占用行上的任何空间，这样就使自动换行能够继续正常工作。没有这两个转义序列，尽管您有了一个非常漂亮的提示行，但是如果您键入的命令恰好到达终端的最右端，就会造成显示混乱。下面是我们最终的提示行： <br /><br /><br />export PS1="\[\e[32;1m\]\w>; \[\e[0m\]" <br /><br /><br /><br />别担心在同一个提示行中使用几种颜色，就像下面这样： <br /><br /><br />export PS1="\[\e[36;1m\]\u@\[\e[32;1m\]\H>; \[\e[0m\]" <br /><br /><br /><br />Xterm 中的乐趣 <br />我已说明了如何在提示行中添加信息和颜色，但您还可以更进一步。您可以通过在提示行中添加专用代码来使 X 终端（如 rxvt 或 aterm）的标题栏得到动态更新。您所要做的只是将下面的序列添加到您的 PS1 提示行中： <br /><br /><br />"\e]2;titlebar\a" <br /><br /><br /><br />只须用您希望其出现在 xterm 标题栏中的文字替换子串 "titlebar" 即可，现在已经一切就绪了！不必使用静态文字；您可以将  bash 转义序列插入标题栏中。请查看下面这个示例，它将用户名、主机名和当前工作目录显示在标题栏中，并定义了一个简短、明亮的绿色提示行： <br /><br /><br />export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>;\[\e[0m\] " <br /><br /><br /><br />这就是我在上面的抓屏结果中所用的那个提示行。我喜欢这个提示行，因为它将全部信息显示在标题栏上，而不是显示在终端上，终端对一行可以显示多少字符有限制。顺便提一句，确保用 "\[" 和 "\]" 将您的标题栏序列括起来（因为就终端而言，这个序列是非打印序列）。将大量信息放在标题栏中的问题是，如果您使用非图形终端（如系统控制台），则看不到这些信息。为了解决这个问题，可以在您的 .bashrc 中添加以下几行： <br /><br /><pre name="code" class="ruby">
if [ "$TERM" = "linux" ] 
then 
#we're on the system console or maybe telnetting in 
export PS1="\[\e[32;1m\]\u@\H >; \[\e[0m\]" 
else 
#we're not on the console, assume an xterm 
export PS1="\[\e]2;\u@\H \w\a\e[32;1m\]>;\[\e[0m\] " 
fi 

</pre><br /><br />这个 bash 条件语句将根据当前的终端设置动态设置提示行。为了获得一致性，您一定希望配置您的 ~/.bash_profile，以便它在启动时搜索 (source) 您的 ~/.bashrc。确保您的 ~/.bash_profile 文件中有以下这样一行：
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/167062#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 20:20:56 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/167062</link>
        <guid>http://hooney.javaeye.com/blog/167062</guid>
      </item>
      <item>
        <title>linux 终端下输出显示颜色color for xterm in ruby lang.</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/167061" style="color:red;">http://hooney.javaeye.com/blog/167061</a>&nbsp;
          发表时间: 2008年03月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          linux 下,在ROR的app中,看到的有颜色的sql语句,实现方法,当然是调用 linux 的系统颜色来作设置的,当用tail -f file 查看文件的时候就可以看到不同颜色标识的文字啦.<br /><br /><pre name="code" class="ruby">
location at :
/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract_adapter.rb
        def format_log_entry(message, dump = nil)
          if ActiveRecord::Base.colorize_logging
            if @@row_even
              @@row_even = false
              message_color, dump_color = "4;36;1", "0;1"
            else
              @@row_even = true
              message_color, dump_color = "4;35;1", "0"
            end

            log_entry = "  \e[#{message_color}m#{message}\e[0m   "
            log_entry &lt;&lt; "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
            log_entry
          else
            "%s  %s" % [message, dump]
          end
        end

</pre><br /><br />linux 端颜色设置 :<br />1.  用echo "&lt;ctrl-v>;&lt;escape>;[31m测试&lt;ctrl-v>;&lt;escape>;[37m"<br />   echo "^[[Xm YourChar"<br />   (X=30,31...36?)<br />   请注意这个转义系列的敲法是，&lt;ctrl-v>;&lt;escape>;[30m<br />   echo "&lt;ctrl-v>;&lt;escape>;[&lt;代码>;;&lt;代码>;;&lt;代码>;m"<br />   注意，语句必须要在""之间，属性分隔符为";"，如闪烁红色<br />   echo "&lt;ctrl-v>;&lt;escape>;[31;5m测试"<br /><br />2.  前景             背景              颜色<br />   ---------------------------------------<br />   30                40               黑色<br />   31                41               紅色<br />   32                42               綠色<br />   33                43               黃色<br />   34                44               藍色<br />   35                45               紫紅色<br />   36                46               青藍色<br />   37                47               白色<br /><br />   代码              意义<br />   -------------------------<br />   0                 OFF<br />   1                 高亮显示<br />   4                 underline<br />   5                 闪烁<br />   7                 反白显示<br />   8                 不可见<br /><br />3.  产生颜色(黑色背景加绿色前景色)：<br />   sco:            setcolor red; echo "abcd"; setcolor white<br />   Linux/BSD:      /usr/bin/echo -e "\033[40;32m"<br />   System V:       /usr/bin/echo "\033[40;32m"<br />   Generic Method: /usr/bin/echo "&lt;ctrl-v>;&lt;escape>;[40;32m"
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/167061#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 03 Mar 2008 20:18:04 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/167061</link>
        <guid>http://hooney.javaeye.com/blog/167061</guid>
      </item>
      <item>
        <title>常用资料</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/165561" style="color:red;">http://hooney.javaeye.com/blog/165561</a>&nbsp;
          发表时间: 2008年02月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: xx-large">mysql </span><br /><pre name="code" class="ruby">
<span style="font-size: medium">查找异常线程:</span>
shell >mysqladmin proc stat -i2 (-i2每隔两秒显示一次)

<span style="font-size: medium">杀死线程:</span> shell >mysqladmin kill id

<span style="font-size: medium">授权</span>
mysql>grant all on productcenter.* to 'user'@'localhost' identified by 'password';(指定的user用户拥有productcenter数据库中的所有表的所有权限(select ,insert,update,delete.....)
mysql>grant select on productcenter.* to 'user'@'localhost' identified by 'password';(只拥有select 权限)

</pre><br /><br /><span style="font-size: xx-large">shell</span><br /><pre name="code" class="ruby">
#>find ./ -name *~ -type f -exec rm -rf {} \; 
(删除当前目录及子目录下所有以 ~ 结尾的文件.)

#>find ./ -name .svn -type d -exec rm -rf {} \;
(删除当前目录以及子目录下所有名为 .svn 的目录)


</pre>
          <br/>
          <span style="color:red;">
            <a href="http://hooney.javaeye.com/blog/165561#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Feb 2008 20:02:25 +0800</pubDate>
        <link>http://hooney.javaeye.com/blog/165561</link>
        <guid>http://hooney.javaeye.com/blog/165561</guid>
      </item>
      <item>
        <title>RJS Reference</title>
        <author>xu_wccq</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://hooney.javaeye.com">xu_wccq</a>&nbsp;
          链接：<a href="http://hooney.javaeye.com/blog/160032" style="color:red;">http://hooney.javaeye.com/blog/160032</a>&nbsp;
          发表时间: 2008年01月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: xx-large"><span style="color: indigo">JavaScriptGenerator</span></span><br /><br />摘自：《OReilly.RJS.Templates.for.Rails.Jun.2006.chm》chapter 7<br /><br /><pre name="code" class="ruby">
The following is a list of all of the methods public methods offered by the JavaScriptGenerator. These methods are called on the page object in your RJS templates.

Since RJS is all about generating JavaScript, it is nice to know what is going on behind the scenes. Knowing about the JavaScript that is generated makes it much easier to debug problems and create more complex applications. At some point, your RJS code may become too complex or there may be a task that you can't perform elegantly with RJS. If you understand how RJS generates JavaScript, you can easily port your code into a JavaScript library and use RJS to access your new JavaScript objects and methods.

Therefore, for all of the following definitions, I have placed the JavaScript that the method generates after the Ruby code. The Ruby code is marked with the comment # Ruby code, and the JavaScript is marked with // Generated JavaScript.



&lt;&lt;(javascript)

Writes raw JavaScript to the page.
        
        
[](id)

Returns a JavaScriptElementProxy for the DOM element with the specified id. Methods can be called on the returned element. Multiple method calls can also be chained together.
        
        # Ruby code
        page['header'].show
        
        // Generated JavaScript
        $("header").show();
        
        # Ruby code
        page['header'].first.second
        
        // Generated JavaScript
        $("header").first().second();
        
        


assign(variable, value)

Assigns a value to the JavaScript variable specified. Ruby objects are automatically converted to JavaScript objects by calling the object's to_json method if it has one, or inspect if it doesn't.
        
        # Ruby code
        page.assign 'name', { :first => "Cody", :last => "Fauser" } 
        
        // Generated JavaScript
        name = { "first": "Cody", "last": "Fauser" };
        
        


alert(message)

Displays a JavaScript alert dialog box with the provided message.
        
        # Ruby code
        page.alert 'An error occurred while processing your request'
        
        // Generated JavaScript
        alert("An error occurred while processing your request");
        
        


call(function, arg, ...)

Calls a JavaScript function and passes in zero or more arguments.
        
        # Ruby code
        page.call 'displayError', 'An error occurred', 'Critical' 
        
        // Generated JavaScript
        displayError("An error occurred", "Critical");
        
        
        
        You can call methods on custom objects that you've added to your page by specifying the variable name and the method call.
        
        # Ruby code
        page.call 'inventory.showTotal' 
        
        // Generated JavaScript
        inventory.showTotal();
        
        


delay(seconds = 1)

Executes the code within the block after delaying for the specified number of seconds.
        
        # Ruby code
        page.delay(5) do
          page.visual_effect :highlight, 'navigation'
        end
        
        // Generated JavaScript
        setTimeout(function() {
        ;
        new Effect.Highlight("navigation", {});
        }, 5000);
        
        


draggable(id, options = {})

Makes the DOM element specified by the id draggable.
        
        # Ruby code
        page.draggable('photo', :revert => true)
        
        // Generated JavaScript
        new Draggable('photo', {revert: true});
        
        


drop_receiving( id, options = {})

Makes the DOM element specified by the id receive dropped draggable elements. Draggable elements are created using the RJS draggable method or by using draggable_element() Scriptaculous helper.
        
        # Ruby code
        page.drop_receiving('photo', :url => { :action => 'add' })
        
        // Generated JavaScript
        Droppables.add("photo", {onDrop:function(element){new
        Ajax.Request('/hello_world/add', {asynchronous:true, evalScripts:true,
        parameters:'id=' + encodeURIComponent(element.id)})}});
        
        


hide(id, ...)

Hides one or more DOM elements. Specify the elements to hide by their DOM ids.
        
        # Ruby code
        page.hide('first', 'second')
        
        // Generated JavaScript
        Element.hide("first", "second");
        
        


insert_html(position, id, *options_for_render)

Inserts the HTML into the specified position in relation to the element.
        
        The available positions are:
        
        
        


:before

The content is inserted into the page before the element.
        
        
:after

The content is inserted into the page after the element.
        
        
:top

The content is inserted into the element before the element's existing content.
        
        
:bottom

The content is inserted into the element after the element's existing content.
        
        # Ruby code
page.insert_html(:bottom, 'products', '&lt;li>Refrigerator&lt;/li>')

// Generated JavaScript
new Insertion.Bottom("products", "&lt;li>Refrigerator&lt;/li>");





redirect_to(location)

Redirect the browser to the location specified. redirect_to() passes the location to url_for(), so any of the arguments you normally use with url_for() can also be used with redirect_to().
        
        # Ruby code
        page.redirect_to('http://www.google.com')
        
        // Generated JavaScript
        window.location.href = "http://www.google.com";
        
        # Ruby code
        page.redirect_to(:controller => 'inventory', :action => 'list')
        
        // Generated JavaScript 
        window.location.href = "http://localhost:3000/inventory/list";
        
        


remove(id, ...)

Removes one or more DOM elements from the page.
        
        # Ruby code
        page.remove('first', 'second')
        
        // Generated JavaScript
        ["first", "second"].each(Element.remove);
        
        


replace(id, *options_for_render)

Replaces the entire element specified or outerHTML. replace is useful with partial templates so that the entire partial, which includes a container element, can be rendered and used to replace content during an RJS call. An example is an unordered list. A partial containing a  &lt;li>  tag can be rendered instead of having to replace the innerHTML of the  &lt;li> . Replacing just the innerHTML would require the  &lt;li>  tag to be moved out of the partial.
        
        # Ruby code
        product.replace 'banner', '&lt;id="banner">Welcome back Cody&lt;/div>'
        
        // Generated JavaScript
        Element.replace("banner", "&lt;id=\"banner\">Welcome back Cody&lt;/div>");
        
        


replace_html(id, *options_for_render)

Replaces the content or innerHTML of the DOM element with the id with either a String or the output of a rendered partial template.
        
        # Ruby code
        page.replace_html 'timestamp', Time.now
        
        // Generated JavaScript
        Element.update("timestamp", "Sat Apr 29 15:14:24 EDT 2006");
        
        


select(pattern)

Selects DOM elements using CSS-based selectors. Returns a JavaScriptElementCollectionProxy that can then receive proxied enumerable methods. See the JavaScriptCollectionProxy methods in the next section.
        
        # Ruby code
        page.select "#content p"
        
        // Generated JavaScript
        # => $$("#content p");
        
        


sortable(id, options = {})

Makes the element with the DOM ID id sortable using drag and drop. The options are the same as the options for ScriptaculousHelper#sortable_element().
        
        # Ruby code
        # Assuming the current controller is ProjectsController
        page.sortable 'project-65', :url => { :action => 'sort' }
        
        // Generated JavaScript
        Sortable.create("project-65", {onUpdate:function(){
          new Ajax.Request('/projects/sort', {
            asynchronous:true, evalScripts:true, parameters:Sortable.serialize("project-65")
            }
          )}
        });
        
        


show(id, ...)

Makes one or more hidden DOM elements visible. As with hide(), the elements are specified by their DOM ids.
        
        # Ruby code
        page.show 'element-20', 'element-30'
        
        // Generated JavaScript
        Element.show("element-20", "element-30");
        
        


toggle(id, ...)

Toggles the visibility of one or more DOM objects.
        
        # Ruby code
        page.toggle 'product-1', 'product-2', 'product-3'
        
        // Generated JavaScript
        Element.toggle("product-1", "product-2", "product-3");
        
        


visual_effect(name, id = nil, options = {})

Creates a new Scriptaculous visual effect to the element with the DOM id. See the following section on visual effects for a list of the visual effects shipping with Rails 1.1.
        
        # Ruby code
        page.visual_effect :highlight, 'list-item-69', :duration => 5
        
        // Generated JavaScript
        new Effect.Highlight("list-item-69",{duration:5});
</pre><br /><br /><span style="font-size: x-large"><span style="color: darkred">JavaScriptElementProxy</span></span><br /><pre name="code" class="ruby">

The JavaScriptElementProxy is a proxy to a real DOM object. You can proxy method calls to the any of the DOM object's JavaScript methods. A few additional methods have been added to the proxy objects to make them more useful. This reference covers those enhanced non-JavaScript methods.



replace_html(*options_for_render)

Replaces the innerHTML of the DOM object. See the JavaScriptGenerator#replace_html() method for more information.
        
        
replace(*options_for_render)

Replaces the outerHTML for the DOM object. See JavaScriptGenerator#replace() method for more information.
        
        
reload

Reloads the content for the element by re-rendering a partial with the same name as the DOM element's id.
        
        page['header'].reload
            
        # Equivalent to:
            
        page['header'].replace :partial => 'header'

</pre><br /><br /><span style="font-size: xx-large"><span style="color: darkblue">JavaScriptCollectionProxy</span></span><br /><br /><pre name="code" class="ruby">
The JavaScriptCollectionProxy is the most difficult part of RJS to understand and work with. This section will first cover some of the trickier aspects of the enumerable support and the actual reference will begin. This will help you avoid trouble and maintain your productivity.


Block Variables and the Enumerable methods
JavaScriptGenerator#select() returns an instance of the JavaScriptElementCollectionProxy class. JavaScriptElementCollectionProxy inherits from JavaScriptCollectionProxy, which provides all of the functionality. The trickiest part about the collection proxy enumerable methods is the code that goes within the block. The code within the block is translated into a JavaScript iterator function. Another tricky aspect of the enumerable block is that you can use any variable names you like for the block parameters, but in the generated JavaScript iterator function the variable names used are always value and index. This rule applies to any expression you use within the block that isn't a simple method called on the proxy object.

The first block parameter is always the element and the second is always the index, except with inject() and pluck(). If you don't access the value or index within the block, then you don't have to pass them into the block. In the following example, the block parameter is named element.

# Ruby code
page.select('#elements span').all('allVisible') do |element, index|
  element.visible
end

// Generated JavaScript
var allVisible = $$("#elements span").all(function(value, index) {
return value.visible();
});



As you can see from the generated JavaScript, the variable value was used and not element, as it was named in the Ruby code. This works well, as long as the code within the block is a simple proxied method call, as it was in the preceding code. More complex expressions need to be written as a string and passed to the &lt;&lt; method of the page object.

When using a direct element proxy rather than a string passed to &lt;&lt;, the generator assumes that the proxied call is a method call and automatically adds (). This means that you can't directly proxy an element's property, such as element.innerHTML.

page.select('#elements span').any('allVisible') do |value, index|
  page &lt;&lt; '!value.visible()'
end



The last expression in the block is the statement appended to the return statement in the generated JavaScript code, so it is possible to safely add more method calls to the block.


Inspecting the Results of the Enumerations
The one problem with the enumerable functions is that it is difficult to inspect the return JavaScript variables assigned by the function. The FireBug console is unable to display the assigned variable when the variable is assigned during the execution of eval() after an Ajax call. I used a small Logger class that uses the printfire() method discussed in the FireBug chapter to log to the JavaScript console. I then created a simple class to inspect the JavaScript variables assigned by the enumerable functions. You can define the class in public/javascripts/application.js.

var Inspector = {}

Inpsector = {
  inspect: function(val) {
    if (val.innerHTML) {
      Logger.log(val.innerHTML);
    } else {
      Logger.log(val);
    }
  },

  inspectArray: function(array) {
    array.each(this.inspect);
  }
}



Following is an example of the usage of the Logger class for inspecting the variable assigned by the return value of sort_by(). In this case sort_by() sorts all the paragraphs in the page by the length of their content and stores the sorted objects in an Array named sortedParagraphs.

page.select('p').sort_by('sortedParagraphs') do |value, index|
  page &lt;&lt; 'value.innerHTML.length;'
end

page &lt;&lt; 'Logger.inspectArray(sortedParagraphs);'



This code simply iterates through the sorted paragraphs and displays the HTML content of each object to the FireBug console. Feel free to expand and improve on the code to meet your own needs.


Method Reference
All of the following enumerable methods are simply proxies to the Prototype enumerable method of the same name. For each method (except for pluck), there is a corresponding Ruby enumerable method with the same name. The Ruby enumerable method may have an added ? (e.g., all?). The Prototype methods were meant to mimic Ruby's enumerable methods. Therefore, you can get a pretty good idea of the overall intent of each method by examining the Ruby version.



all(variable) {|value,index| block }

Each element is passed to the block. The block is converted to a JavaScript iterator function. The JavaScript variable is set to TRue if the iterator function never returns false or null.
        
        # Ruby code
        page.select('#line-items li').all('allVisible') do |value, index|
          value.visible
        end
        
        // Generated JavaScript
        var allVisible = $$("#line-items li").all(function(value, index) {
        return value.visible();
        });
        
        


any(variable){|value, index| block }

Each element is passed to the block. The block is converted to a JavaScript iterator function. The JavaScript variable is set to TRue if the iterator function never returns false or null.
        
        # Ruby code
        page.select('#line-items li').any('anyVisible') do |value, index|
          value.visible
        end
        
        // Generated JavaScript    
        var anyVisible = $$("#line-items li").any(function(value, index) {
        return value.visible();
        });
        
        


collect(variable){|value, index| block }

The block is converted to a JavaScript iterator. This method assigns a new JavaScript Array to the JavaScript variable containing the results of executing the iterator function once for each element.
        
        # Ruby code
        page.select('#orders tr').collect('heights') do |value, index|
          value.get_height
        end
            
        // Generated JavaScript
        var heights = $$("#orders tr").collect(function(value, index) {
        return value.getHeight();
        });
        
        


detect(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to the first element for which the iterator function does not return false.
        
        # Ruby code
        page.select('#content p').detect('first_visible') do |value, index|
          value.visible
        end
        
        // Generated JavaScript    
        var first_visible = $$("#content p").detect(function(value, index) {
        return value.visible();
        });
        
        


each{|value, index| block }

Passes each element to the block, which is converted to a JavaScript iterator function. The iterator function is called once for each element.
        
        # Ruby code
        page.select('#content p').each do |value, index|
          page &lt;&lt; 'alert(value.innerHTML);'
        end
            
        // Generated JavaScript
        $$("p").each(function(value, index) {
        alert(value.innerHTML);
        });
        
        


find(variable){|value, index| block }

A synonym for JavaScriptCollectionProxy#detect().
        
        
find_all(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to an Array of all elements for which the iterator function does not return false.
        
        # Ruby code
        page.select('#content p').find_all('empty_paragraphs') do |value, index|
          value.empty
        end
        
        // Generated JavaScript    
        var empty_paragraphs = $$("#content p").collect(function(value, index) {
        return value.empty();
        });
        
        


grep(variable, pattern){|value, index| block }

Each DOM element with a toString() matching the Regexp pattern is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to an Array containing the results of executing the iterator function once for each element.
        
        This method isn't entirely useful in the context of RJS. Its only real use is matching DOM elements using the pattern based on their type, which is output by the toString() method. The toString() method outputs [object HTMLDivElement] for a  &lt;div>  element. Use the FireBug console to view the toString() output for other elements.
        
        # Ruby code
        page.select('#content p').grep('hidden', /Div|Paragraph/) do |value, index|
          value.hidden
        end
        
        // Generated JavaScript    
        var hidden = $$("#content p").grep(/Div|Paragraph/, function(value, index) {
        return value.hidden();
        });
        
        


inject(variable, memo){|memo, value, index| block }

Each element and the accumulator value memo is passed to the given block. The block is converted to a JavaScript iterator function. The iterator function is called once for each element and the result is stored in memo. The result returned to the JavaScript variable is the final value of memo. The initial value of memo is set in one of two ways. The value of the parameter memo is used as the initial value if a non nil value is passed in to the method. Otherwise, the first element of the collection is used as the initial value.
        
        # Ruby code
        page.select('#content .columns').inject('totalWidth', 0) do |memo, value, index|
           page &lt;&lt; '(memo + value.offsetWidth)'
        end
        
        // Generated JavaScript
        var totalWidth = $$(".columns").inject(0, function(memo, value, index) {
        return(memo + value.offsetWidth);
        });
        
        


map(variable){|value, index| block }

Synonym for JavaScriptCollectionProxy#collect().
        
        
max(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to the largest value returned by the iterator function.
        
        # Ruby code
        page.select('p').max('longestParagraphLength') do |value, index|
          page &lt;&lt; 'value.innerHTML.length'
        end
            
        // Generated JavaScript
        var longestParagraphLength = $$("p").max(function(value, index) {
        return value.innerHTML.length;
        });
        
        


min(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to the smallest value returned by the iterator function.
        
        # Ruby code
        page.select('p').min('shortestParagraphLength') do |value, index|
          page &lt;&lt; 'value.innerHTML.length'
        end
            
        // Generated JavaScript
        var shortestParagraphLength = $$("p").min(function(value, index) {
        return value.innerHTML.length;
        });
        
        


partition(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function and is executed once for each element. The JavaScript variable is set to an Array containing to Arrays. The first Array contains all of the elements for which the iterator function evaluated to true. The second Array contains all of the remaining elements.
        
        # Ruby code
        page.select('.products').partition('productsByVisibility') do |value, index|
          value.visible
        end
        
        // Generated JavaScript
        var productsByVisibility = $$(".products").partition(function(value, index) {
        return value.visible();
        });
        
        


pluck(variable, property)

Iterates through the collection creating a new Array from the value of the given property of each object without a function call. The resulting Array is assigned to the JavaScript variable.
        
        # Ruby code
        page.select('.amounts').pluck('amounts', 'innerHTML')
            
        // Generated JavaScript
        var amounts = $$(".amounts").pluck("innerHTML");
        
        


reject(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. The JavaScript variable is assigned to an Array of all elements for which the iterator function returns false.
        
        # Ruby code
        page.select('p').reject('paragraphsWithContent') do |value, index|
          value.empty
        end
        
        // Generated JavaScript
        var paragraphsWithContent = $$("p").reject(function(value, index) {
        return value.empty();
        });
        
        


select(variable){|value, index| block }

A synonym for JavaScriptCollectionProxy#find_all().
        
        
sort_by(variable){|value, index| block }

Each element is passed to the given block. The block is converted to a JavaScript iterator function. Assigns the JavaScript variable to an Array of the elements sorted using the result of the iterator function as keys for the comparisons when sorting.
        
        # Ruby code
        page.select('p').sort_by('sortedParagraphs') do |value, index|
          page &lt;&lt; 'value.innerHTML.length;'
        end
            
        // Generated JavaScript
        var sortedParagraphs = $$("p").sortBy(function(value, index) {
        return value.innerHTML.length;
        });
        
        


zip(variable, arg1, ...){|value, index| block }

Merges elements with the arrays passed as parameters. Elements in the corresponding index of each array form a new array. The resulting array of arrays is assigned to the JavaScript variable. If a block is provided it is converted to an iterator function and is applied to each resulting Array. The name of the parameter to the iterator function is array.
        
        For this example, assume that the page has the following paragraph elements:
        
        &lt;p id="first">First Paragraph&lt;/p>
        &lt;p id="second">Second Paragraph&lt;/p>
        
        
        
        First, applying zip without a block:
        
        # Ruby code
        page.select('p').zip('zipped', [1, 2], [3,4])
            
        // Generated JavaScript
        var zipped = $$('p').zip([1,2], [3,4]);
        
        
        
        The resulting array of arrays, where the paragraphs (represented by their ids) are DOM objects:
        
        [[&lt; id="first">, 1, 3], [&lt;p id="second" >, 2, 4]]
        
        
        
        Applying zip with a block:
        
        # Ruby code
        page.select('p').zip('zipped', [1, 2], [3,4]) do |array|
          page.call 'array.reverse'
        end
            
        // Generated JavaScript
        var zipped = $$("p").zip([1,2], [3,4], function(array) {
        return array.reverse();
        });
        
        
        
        The resulting Array of arrays, where the paragraphs (represented by their ids) are DOM objects:
        
        [[3, 1, &lt;p id="first">], [4, 2, &lt;p id="second" >]]

</pre><br /><br /><span style="font-size: x-large"><span style="color: greens">Visual Effects</span></span><br /><br /><pre name="code" class="ruby">
For the purposes of RJS templates, all visual effects are accessed using the name of the effect as a symbol, e.g.,