low level programmer

星期日 一月 24, 2010

打包不同環境設定檔的 build.xml

description

上次做了可以部署不同環境的 build.xml 之後,
隨著產品的完整與使用的其他專案愈來愈多, 設定檔對應的環境也愈來愈多了.
不可能每次加個環境的設定檔就加個 target.
所以就改寫 build.xml 使能夠給定參數決定要複製哪一份設定檔.
另外原本的版本每次打包前都要跑測試, 不過這有點慢,
而且只有負責開發的人才需要測試, 給 user 自己部署的話是不用跑測試的,
所以就加了 target 使能夠直接打包不用跑 test.

usage

不知道會不會有人想用這份現成的 build.xml, 我自己是覺得蠻方便的. 還可用在 Hudson
要用這份 build.xml 的前提是專案資料夾結構並須符合以下格式
/ant/lib/jsp-api.jar
/ant/lib/junit-4.4.jar
/ant/lib/servlet-api.jar
/src
/test
/web
/config/yourconfigfolders1
/config/yourconfigfolders2
/config/yourconfigfolders3
...
/config/yourconfigfoldersN
只要確定專案資料夾結構符合規定就可以使用這份 build.xml
裡面的 target 不多, 主要會用到的大概如下.
clean : 清空 build 與 dist 資料夾
clean-dist-jarwar : clean 與 dist 後打包檔案到 dist 資料夾
clean-dist-test : clean 與 dist 後執行測試
clean-dist-test-jarwar : clean 與 dist 與 test 後打包檔案到 dist 資料夾
注意這是在使用 target 的時候要帶參數, 目的就是要指定想使用哪一個設定檔.
例如想打包 /config/yourconfigfolders1, 就輸入
ant clean-dist-jarwar -Dconfig=yourconfigfolders1
想打包 /config/yourconfigfolders2, 就輸入
ant clean-dist-jarwar -Dconfig=yourconfigfolders2
依此類推.

codes

build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="myproject" default="default" basedir=".">
    <description>Builds the project.</description>
    <property name="project.name" value="myproject" />
    <property name="dist" value="dist" />
    <property name="build" value="build" />
    <property name="build.version" value="1.0" />
    <property name="lib" value="web/WEB-INF/lib" />
    <property name="ant.lib" value="ant/lib" />
    <property name="build.reports.tests" value="build/reports/tests" />
    <property name="build.tests" value="build/tests" />
    <property name="build.tests.classes" value="build/tests/classes" />
    <property name="build.web" value="build/web" />
    <property name="build.web.classes" value="${build.web}/WEB-INF/classes" />
    <property name="build.web.lib" value="${build.web}/WEB-INF/lib" />
    <property name="src.java" value="src" />
    <property name="src.test" value="test" />
    <property name="src.config" value="config/${config}" />
    <property name="src.webapp" value="web" />
    <property name="dist.manifest" value="dist/MANIFEST.MF" />
    <property name="dist.mainclass" value="" />
    <path id="build.classpath">
        <fileset dir="${ant.lib}" includes="*.jar" />
        <fileset dir="${lib}" includes="*.jar" />
    </path>
    <target name="clean">
        <delete dir="${build}" />
        <delete dir="${dist}" />
    </target>
    <target depends="clean" name="clean-dist">
        <mkdir dir="${build.web.classes}" />
        <mkdir dir="${build.tests.classes}"/>
        <mkdir dir="${dist}" />
        <javac destdir="${build.web.classes}"
                srcdir="${src.java}"
                classpathref="build.classpath"
                source="1.5"
                target="1.5"
                encoding="UTF-8">
        </javac>
        <copy todir="${build.web.classes}">
            <fileset dir="${src.java}">
                <exclude name="**/*.java" />
                <include name="**/*"/>
            </fileset>
        </copy>
        <javac destdir="${build.tests.classes}"
                srcdir="${src.test}"
                classpathref="build.classpath"
                source="1.5"
                target="1.5"
                encoding="UTF-8">
            <classpath location="${build.web.classes}" />
        </javac>
        <copy todir="${build.tests.classes}">
            <fileset dir="${src.test}">
                <exclude name="**/*.java" />
                <include name="**/*"/>
            </fileset>
        </copy>
        <copy todir="${build.web.lib}">
            <fileset dir="${lib}" />
        </copy>
        <copy todir="${build.web}">
            <fileset dir="${src.webapp}" />
        </copy>
    </target>

    <target name="clean-dist-test" depends="clean-dist">
        <mkdir dir="${build.reports.tests}" />
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config}" />
        </copy>
        <junit  haltonfailure="false" showoutput="true">
            <jvmarg value="-version:1.5.0" />
            <classpath>
                <pathelement path="${build.tests.classes}" />
                <pathelement path="${build.web.classes}"/>
                <path refid="build.classpath" />
            </classpath>
            <batchtest fork="yes" todir="${build.reports.tests}">
                <fileset dir="${src.test}">
                    <include name="**/*"/>
                </fileset>
                <formatter type="xml" />
            </batchtest>
        </junit>
    </target>


    <target name="init-dist-manifest">
        <copy todir="dist/lib">
            <fileset dir="${lib}" includes="*.jar" />
        </copy>
        <path id="jar.classpath">
            <fileset dir="dist/lib">
                <include name="*.jar" />
            </fileset>
        </path>
        <manifestclasspath property="jar.manifest.classpath" jarfile="dist/${project.name}.jar">
            <classpath refid="jar.classpath" />
        </manifestclasspath>
        <manifest file="${dist.manifest}">
            <attribute name="Class-Path" value="${jar.manifest.classpath}" />
            <attribute name="Main-Class" value="${dist.mainclass}"/>
            <attribute name="Implementation-Title" value="${project.name}"/>
            <attribute name="Implementation-Version" value="${build.version}"/>
            <attribute name="Implementation-Vendor" value="YourCompany Technology Corporation"/>
            <attribute name="Implementation-Build" value="myproject-${build.version}-M201001240200"/>
        </manifest>
    </target>

    <target depends="clean-dist-test,init-dist-manifest" name="clean-dist-test-jarwar">
        <jar destfile="dist/${project.name}.jar" manifest="${dist.manifest}" >
            <fileset  dir="${build.web.classes}"/>
        </jar>
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config}" />
        </copy>
        <war destfile="${dist}/${project.name}.war">
            <fileset dir="${build.web}" />
        </war>
    </target>

    <target depends="clean-dist,init-dist-manifest" name="clean-dist-jarwar">
        <jar destfile="dist/${project.name}.jar" manifest="${dist.manifest}" >
            <fileset  dir="${build.web.classes}"/>
        </jar>
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config}" />
        </copy>
        <war destfile="${dist}/${project.name}.war">
            <fileset dir="${build.web}" />
        </war>
    </target>

</project>

星期三 十一月 18, 2009

codeline 的控制

專案通常會有三種環境: DEV / UAT / PROD.
為了讓每次的佈署與修改的 bug 都有好的版本管理方式, 我列一下一個需求進來該有怎樣的操作流程.
希望看官們能給點意見, 謝謝! :D
(這只是草稿, 希望以後可以適當的完整, 也不要太複雜好讓人容易記住).

    - create branch for development
        - create branch from trunk to /branches/DEV/
        - develop in branch
        - test in branch
        - fix bugs in branch
        - finish branch development
    
    - merge to trunk
        - create tag from trunk to /tags/DEV/
        - merge branch to trunk
        - test in trunk
        - fix bugs in trunk
        - finish trunk mergence
        
    - deploy to UAT
        - create tag from trunk to /tags/UAT/ before deploy to UAT
        - deploy to UAT
        - test in UAT
        - fix bugs in UAT
            - create branch from /tags/UAT/ to /branches/UAT
            - fix bugs in /branches/UAT/
            - test in /branches/UAT/
            - finish fix bugs in /branches/UAT/
            - create tag from trunk to /tags/UAT/
            - merge from branch to trunk
            - go to "deploy to UAT"
        - finish UAT deployment
        
    - deploy to PROD
        - create tag from trunk to /tags/PROD/ before deploy to PROD
        - deploy to PROD
        - test in PROD
        - fix bugs in PROD
            - create branch from /tags/PROD/ to /branches/PROD/
            - fix bugs in /branches/PROD/
            - test in /branches/PROD/
            - finish fix bugs in /branches/PROD
            - create tag from trunk to /tags/PROD/
            - merge from branch to trunk
            - go to "deploy to PROD"
        - finish PROD deployment

星期五 十一月 06, 2009

[分享] 節錄版本控制與平行開發文章重點的投影片

今天在公司分享介紹一篇文章

Streamed Lines: Branching Patterns for Parallel Software Development

有做投影片節錄重點.
http://docs.google.com/present/view?id=dcsswcvv_5f65vrwfp

不過這篇文章好像蠻久的了, 而且也只是大概看一下, 如果有誤解或是該抓的重點沒抓到請提出來討論喔.

星期二 十月 06, 2009

簡單的推文到 twitter, plurk, facebook

因為客戶想要, 所以看一下客戶口中的"推文到 twitter, plurk, facebook"是怎麼回事.
根據客戶的描述文字, 目前猜測可能是以下的簡單功能.
facebook 的部份跟 twitter/plurk 不太一樣的地方是不知道怎麼顯示字串訊息
而且給的是網頁的位址, facebook 會自動去找那個網頁有什麼可以顯示的..

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
        <script type="text/javascript">
            function sendToPlurk() {
                var msg = document.getElementById('msg').value;
                window.open('http://www.plurk.com/?qualifier=shares&status=' + msg );
            }
            function sendToTwitter() {
                var msg = document.getElementById('msg').value;
                window.open('http://twitter.com/home/?status=' + msg );
            }
            function sendToFacebook() {
                var url = document.getElementById('url').value;
                window.open('http://www.facebook.com/sharer.php?u=' + encodeURIComponent(url) );
            }
       </script>
    </head>
    <body>
        <input type="text" size="100" id="msg" value="測試" /><br />
        <a href="javascript:sendToPlurk()">
            發訊息上 plurk
        </a><br />
        <a href="javascript:sendToTwitter()">
            發訊息上 twitter
        </a><br /><br /><br />
        URL : <input type="text" size="100" id="url" value="http://www.youtube.com/watch?v=x6QA3m58DQw" /><br />
        <a href="javascript:sendToFacebook()">
            發訊息上 facebook
        </a>
    </body>
</html>

星期五 七月 03, 2009

簡單, 複雜與靈活設計的記分

程式設計中, 簡單才是王道. 可是如果都只求 work 的簡單也不太好.
今天心血來潮, 突然覺得這好像可以自己評分.

整個過程目的就是要計算積分後取絕對值, 分數愈低表示設計愈恰當.
"簡單"積分是1
"複雜"積分是10
"靈活"積分是-10

所以一個個的小程式區塊設計就可以評分:
如果你有一個簡單, 沒有靈活, 那你的程式是 Math.abs( 1 + 0*10 + 0*-10 ) = 1 分
如果有一個簡單, 但是有一個靈活, 那就是 Math.abs( 1 + 0*10 + 1*-10 ) = 9 分
如果有一個簡單, 而且還有一個複雜, 但是都沒有靈活, 那就是 Math.abs( 1 + 1*10 + 0*-10 ) = 11 分
當然你也可以把10個簡單換成一個複雜.

如何, 是這樣的感覺嗎?
簡單是最重要的,
可是當簡單變複雜就是一點點重構與一點點設計模式出馬建立一個靈活的時候了.

星期一 六月 15, 2009

Tomcat 用 ImageIO 讀圖要有 temp 資料夾

今天遇到一個狀況就是無法在 Tomcat 上用 ImageIO 讀圖片, 出現

javax.imageio.IIOException: Can't create cache file!
	javax.imageio.ImageIO.createImageInputStream(ImageIO.java:333)
	javax.imageio.ImageIO.read(ImageIO.java:1321)
	org.apache.jsp.test_jsp._jspService(test_jsp.java:65)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
讓人大吃一驚, 因為原本程式都跑好好的.
試了半天去 google 總算找到原因.
原來是要確保 $CATALINA_BASE/temp 這個資料夾存在
(如果有另外設定不要放 temp 放其他地方, 就是該設定的資料夾要存在)
IIOException can’t create cache file


就像他說的: Who would guess that doing PNG conversion with JDK APIs requires you to have a temp folder off of $CATALINA_BASE?

星期二 六月 09, 2009

依不同環境包檔案的 build.xml

description

為了部署方便, 參考 maven 的資料夾結構.
src/main/java
src/main/resources
src/main/config-dev
src/main/config-uat
src/main/config-prod
src/main/webapp
src/test/java
src/test/resources
寫了這個 build.xml 來依照部署的環境包檔案.

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="fubon-sportslotto-activity-200907" default="default" basedir=".">
    <description>Builds the project myp.</description>
    <property name="project.name" value="myp" />
    <property name="dist" value="dist" />
    <property name="build" value="build" />
    <property name="lib" value="lib" />
    <property name="build.test" value="build/test" />
    <property name="build.web" value="build/web" />
    <property name="build.web.classes" value="${build.web}/WEB-INF/classes" />
    <property name="build.web.lib" value="${build.web}/WEB-INF/lib" />
    <property name="main.resources" value="src/main/resources" />
    <property name="src.java" value="src/main/java" />
    <property name="src.config.dev" value="src/main/config-dev" />
    <property name="src.config.uat" value="src/main/config-uat" />
    <property name="src.config.prod" value="src/main/config-prod" />
    <property name="src.webapp" value="src/main/webapp" />
    <path id="build.classpath">
        <fileset dir="${lib}" includes="*.jar" />
    </path>
    <target name="clean">
        <delete dir="${build}" />
        <delete dir="${dist}" />
    </target>
    <target depends="clean" name="clean-dist">
        <mkdir dir="${build.web.classes}" />
        <mkdir dir="${dist}" />
        <javac destdir="${build.web.classes}" 
                srcdir="${src.java}"
                classpathref="build.classpath"
                source="1.5"
                target="1.5"
                encoding="UTF-8">
        </javac>
        <copy todir="${build.web.classes}">
            <fileset dir="${src.java}">
                <include name="**/*.xml"/>
            </fileset>
        </copy>        
        <copy todir="${build.web.lib}">
            <fileset dir="${lib}" />
        </copy>
        <copy todir="${build.web}">
            <fileset dir="${src.webapp}" />
        </copy>
    </target>

    <target depends="clean-dist" name="clean-dist-uat">
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config.uat}" />
        </copy>        
        <war destfile="${dist}/${project.name}.war">
            <fileset dir="${build.web}" />
        </war>
    </target>

    <target depends="clean-dist" name="clean-dist-dev">
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config.dev}" />
        </copy>        
        <war destfile="${dist}/${project.name}.war">
            <fileset dir="${build.web}" />
        </war>
    </target>
    
    <target depends="clean-dist" name="clean-dist-prod">
        <copy todir="${build.web.classes}">
            <fileset dir="${src.config.prod}" />
        </copy>        
        <war destfile="${dist}/${project.name}.war">
            <fileset dir="${build.web}" />
        </war>
    </target>
    
</project>

星期二 六月 02, 2009

幾個 td 一個 tr 的邏輯

description

常遇到這種幾個 td 要一個 tr, 排版要整齊的邏輯.
雖然蠻簡單的, 可是都要想一下.
乾脆整理記錄起來

codes


package test;

import java.util.ArrayList;
import java.util.List;


public class TestTrTdWrap {
    
    public static void main(String[] args) {
        TestTrTdWrap test = new TestTrTdWrap();
        test.test();
    }

    private void test() {
        System.out.println("test 1 items 2 td wrap");
        showTrTd( takeItems(1), 2 );
        System.out.println("test 7 items 3 td wrap");
        showTrTd( takeItems(7), 3 );
        System.out.println("test 7 items 2 td wrap");
        showTrTd( takeItems(7), 2 );
        System.out.println("test 17 items 9 td wrap");
        showTrTd( takeItems(17), 9 );
        System.out.println("test 17 items 2 td wrap");
        showTrTd( takeItems(17), 2 );
    }

    private List<Item> takeItems(int cnt) {
        List<Item> items = new ArrayList<Item>();
        for ( int i = 0; i < cnt; i++ ) {
            items.add( new Item() );
        }
        return items;
    }

    private void showTrTd(List<Item> items, int tdWrap) {
        int itemSize = items.size();
        int roundCnt = itemSize + ( tdWrap - (itemSize % tdWrap) );
        for ( int i = 0; i < roundCnt; i++ ) {
            if ( i % tdWrap == 0 ) {
                System.out.println("<tr>");
            }
            if ( itemSize > i ) {
                System.out.printf("    <td>%s</td>%n", items.get(i).getContent());
            } else {
                System.out.println("    <td> </td>");
            }
            if ( i % tdWrap == tdWrap - 1 ) {
                System.out.println("</tr>");
            }
        }
    }

}
class Item {
    private String content = "testContent";
    public String getContent() {
        return content;
    }
}

星期五 三月 13, 2009

jsp上取得http開頭網址

reference

apache string taglib

note

一般我們會用 ${pageContext.request.contextPath} 來表示目前的路徑, 可是這在 EL 上會以 "/" 開頭. 這樣的網頁只能在 server 上跑. 當需求是網頁要在 server 外跑就不行了. 所以必須取得 http://www.aaa.com/qqq 的字串 我找到的作法是使用 apache 的 string taglib 搭配使用. 結果就是
<c:set var="jspFolder" value="/WEB-INF" />
<str:substring var="serverURL" start="0" end="${fn:indexOf(pageContext.request.requestURL, jspFolder)}" >${pageContext.request.requestURL}</str:substring>
感覺以後會常用到所以紀錄一下

星期五 十月 31, 2008

CSS - Some notes

TODO supply a title

reference

Head First HTML with CSS & XHTML

focal points

  1. 在 html 使用 CSS : 在 head tag 內宣告 style tag 指定 type 為 text/css
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>TEST</title>
        <style type="text/css">
            pre {
                background-color : yellow;
            }
        </style>
    </head>                    
                    
  2. 引用 CSS 的檔案
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>TEST</title>
        <link type="text/css" rel="stylesheet" href="TestXHtml.css" />
    </head>                    
                    
  3. 大部分的 CSS 效果有繼承關係, 也可以 override. 所以 body tag 裡面的 tag 效果大部份會繼承 body tag 的 CSS 效果, 不過如果 body tag 內的 tag 也有定自己的 CSS 就會以 body tag 內 tag 自己的 CSS 為主
  4. 如果屬性比方說 font-size 寫 2em 或 200% 表示相較於繼承來的屬性而言是多少比例, 使用這種相對關係的比例好處是只要控制 root 的效果, 整體的效果就能一起變動
  5. 指定 tag 的 style.
    body {
        font-size : 10px;
    }
    
    /* 一次指定兩個 tag 的效果 */
    h1, h2 {
        color : gray;
    }
                    
  6. 指定 class
    /* p tag 如果指定 class 為 classA 就會使用此效果 */
    p.classA {
        font-size : 10px;
        border-width : thin;
        border-style : solid;
        border-color : #007e7e;
    }
    
    /* 任何的 tag 只要 class 為 classB 就使用此效果 */
    .classB {
        font-size : 20px;
        padding-top : 120px;
        padding-right : 20px;
        padding-bottom : 20px;
        padding-left : 20px;
    }
                    
    如果一個 p tag 宣告
    <p class="classB classA">
      TEST TESTTEST TESTTEST TESTTEST TEST
    </p>                    
                    
    這樣 p tag 同時會有 classA 與 classB 的效果. 不過 font-size 會符合 classB 的效果, 這是因為 classB 比較晚宣告.
  7. 指定 id 如果一個 p tag 宣告
    <p id="testid">
      TEST TESTTEST TESTTEST TESTTEST TEST
    </p>                    
                    
    則透過使用 #
    /* 不論什麼 tag 只要 id 是 testid 都套用此效果 */                    
    #testid {
        font-size : 10px;
    }
    /* tag p 的 id 是 testid 就套用此效果 */ 
    p#testid {
        font-size : 20px;
    }
                    
    都可以拿來指定 testid 這個 p tag.
  8. 指定某個 parent 後的 child
    /* div tag 下的 p tag 下的所有 blockquote tag 子孫都套用此效果 */                    
    div p blockquote {
        font-size : 100px;
    }
    
    /* div tag 下的所有 p tag child 都套用此效果 */
    div p {
        font-size : 100px;
    }
    
    /* testid 這個 id 下的所有 p tag 子孫都套用此效果 */                    
    #testid p {
        font-size : 100px;
    }
    
    /* 只有 testid 這個 id 下的 p tag child (不包括所有子孫, 只有直系 child)套用此效果 */                    
    #testid>p {
        font-size : 100px;
    }
                    
  9. 屬性速記
    /* 原本的屬性 */
    .classA {
        border-width : thin;
        border-style : solid;
        border-color : #007e7e;
    }
    /* 可以寫成這樣, 不用管順序 */
    .classB {
        border : thin solid #007e7e;
    }
    /* 如果有 top bottom 之類的, 就已上右下左為順序 */
    /* 上 0px, 右 10px, 下 20px, 左 30px */
    .classC {
        padding : 0px, 10px, 20px, 30px;
    }
    /* 下右下左都一樣, 就寫一個即可 */
    /* 四面都 100px */
    .classD {
        padding : 100px;
    }
    /* 上下一樣, 左右一樣. */
    /* 上下為 10px, 左右 20px */
    .classE {
        padding : 10px, 20px;
    }
    /* 字型速記的順序 : font : font-style font-variant font-weight font-size/line-height font-family */
    /* 字型速記 optional 的項目有 font-style font-variant font-weight */
                    
  10. Pseudo class : 雖然不能自己定義, 但是如果使用到瀏覽器支援的虛擬類別就可以呈現效果.
    /* 連結原本的顏色為藍色 */                    
    a:link {
        color : blue;
    }
    /* 拜訪過的連結是灰色 */
    a:visited {
        color : gray;
    }
    /* 滑鼠在上方時呈現綠色 */
    a:hover {
        color : green;
    }                  
    /* id 為 testid 的 tag 滑鼠滑過連結時呈現黃色 */
    #testid a:hover {
        color : yellow;
    }
                    
  11. Cascade
    1. 瀏覽器會先把 CSS 中相關的設定依照 作者, 使用者, 瀏覽器預設 排列出來, 再依照元素的優先分數決定要使用哪個效果.
    2. 一種計算分數的方式 : 百位數代表 id, 有 id 加 1 分; 十位數代表 class 或 pseudo class, 有指定加 1 分; 個位數代表 tag name, 有指定加 1 分
      /* grade : 1 */                            
      h1 {
          color : red;
      }
      /* grade : 11 */
      h2.myClass {
          color : red;
      }
      /* grade : 100 */
      #testid {
          color : red;
      }
                              
  12. 浮動 float
    /* id 為 testid 的 div 元素會浮動到畫面右邊, 其下方的元素會自動往上補又不會蓋掉這個 div */                    
    div#testid {
        width : 300px;
        background-color : lightblue;
        float : right;
    }                    
                    
  13. 使用 clear 避免因為 float 元素而擠壓到自己的內容
    /* 這樣 testid2 的右邊不會因為 testid 浮動到畫面右邊導致 testid2 的內容被擠壓到.
     * testid2 會被擠到 testid 下方 */                    
    div#testid2 {
        clear : right;
    }
    
    div#testid {
        width : 35%;
        background-color : lightblue;
        float : right;
    }                    
                    
  14. 現制整個畫面的寬度. 比方說要限制在寬度 800, 可以用一個 div 把所有的網頁內容放在這個 div 內, 然後取名 allContent, 再套用下面的 css.
    /* margin-left 和 margin-right 設定為 auto 可使這個 div 保持在畫面中間 */                    
    div#allContent {
        width : 800px;
        margin-left : auto;
        margin-right : auto;
    }                    
                    
  15. 絕對定位 : 透過 position 設定為 absolute(預設為 static), 可以明確指定這個 div 的寬高以及出現的位置在哪. 使用這種方式指定的話, position 為 static 的元素都不會理會這個元素的位置而直接被 position 為 absolute 的元素覆蓋掉
    /* 這樣會底色黃色出現在離頂端 200px 離左方 200px 的位置 */                    
    div#anywhere {
        background-color : yellow;
        position : absolute;
        width : 400px;
        top : 200px;
        left : 200px;
    }                    
                    
  16. z-index : 使用絕對定位之後就會有兩個元素重疊的現象, 這時候就要決定誰在上面誰在下面, 決定誰上誰下的地方在 z-index 這個屬性, 誰大誰就放上面.
    /* 這兩個 div 可看出 : 重疊的時候 anywhere1 會被 anywhere2 蓋過去 */                    
    div#anywhere1 {
        position : absolute;
        background-color : yellow;
        width : 400px;
        top : 10%;
        right : 20%;
        z-index : 10;
    }
    
    div#anywhere2 {
        position : absolute;
        background-color : blue;
        width : 200px;
        top : 20%;
        right : 20%;
        z-index : 20;
    }                    
                    
  17. 使用 absolute 的時候, top 與 right 等的設定, 是與 "最接近的已定位祖先" 相比較. 以下的 HTML 與 CSS 的效果就是 outer 會把 inner 的 div 整個包起來
    /* HTML */
    <div id="outer">
        <p>
            ...some content
        </p>
        <div id="inner">
            <p>
                anywhere anywhere anywhere anywhere anywhere anywhere 
                anywhere anywhere anywhere anywhere anywhere anywhere 
            </p>
            <p>
                anywhere anywhere anywhere anywhere anywhere anywhere 
                anywhere anywhere anywhere anywhere anywhere anywhere 
            </p>
        </div>
        <p>
            ...some content
        </p>
    </div>
    /* CSS */
    div#outer {
        background-color : yellow;
        position : absolute;
        top : 100px;
        left : 100px;
        width : 400px;
    }
    
    div#inner {
        background-color : green;
        position : absolute;
        top : 100px;
        left : 100px;
        width : 100px;   
        z-index : 2;
    }
                    
  18. fixed : 固定在瀏覽器上的某個位置
    /* outer 會固定在離瀏覽器頂端 100px 與瀏覽器左邊離 -60px, 所以會被瀏覽器左邊擋掉一點 */
    div#outer {
        background-color : yellow;
        position : fixed;
        top : 100px;
        left : -60px;
        width : 400px;
    }                    
                    
  19. relative : 與其他元素的相對位置加上偏移. 這個屬性和 absolute 與 fixed 都不同, 使用 relative 讓元素像是一般的元素一樣會被畫面上各種元素擠來擠去, 最後再加上指定的偏移量.
    /* outer 會跑到被擠壓過後的位置往下移 50px 往右移 20px */
    div#outer {
        background-color : yellow;
        position : relative;
        top : 50px;
        left : 20px;
        width : 400px;
    }                    
                    
  20. 改變 li 項目清單的外觀.
    li#a {
        list-style-type : disc;
    }
    li#b {
        list-style-type : circle;
    }
    li#c {
        list-style-type : square;
    }
    li#d {
        list-style-type : none;
    }
    li#e {
        list-style-image : url( rock.jpg );
    }
    
    /* A.XXX 
     * B.XXX
     * C.XXX
     */
    li#f {
        list-style-image : upper-alpha;
    }
                    
  21. 改變 li 控制 li 內的文字出現在標識下或文字下
    /* A.XXX
     *   XXX
     * B.XXX
     */
     li {
        list-style-type : upper-alpha;
        list-style-position : outside;
    }
    /* A.XXX
     * XXX
     * B.XXX
     */
     li {
        list-style-type : upper-alpha;
        list-style-position : inside;
    }
                    
  22. 把 table 的水平邊框和垂直邊框設定成不同大小
    table#testid {
        border : thin solid black;
        border-spacing : 10px 30px;
    }                    
                    
  23. 使邊框重疊
    /* 方法 1. 指定 border-spacing */
    table#testid {
        border : thin solid black;
        border-spacing : 0px;
    }
    /* 方法 2. 指定 border-collapse */
    table#testid {
        border : thin solid black;
        border-collapse : collapse;
    }
                    
  24. 使 table 裡面的 table 的 th 背景為白色
    table table th {
        background-color : white;
    }
                    
  25. 列印的時候套用另一組 CSS.
    <!-- 手攜裝置的  CSS -->
    <link rel="stylesheet" type="text/css" media="handheld" href="forhandheld.css" /> 
    
    <!-- 列印的  CSS -->
    <link rel="stylesheet" type="text/css" media="print" href="forprint.css" /> 
                    
    1. 列印最好用點數如 12pt 來指定文字大小
    2. display 屬性可用來控制列印時候的特殊情形, 比方說不印就設 display : none

星期六 十月 18, 2008

SQL - 查詢每天最後一筆

description

很少用 SQL, 結果遇到一個需求就想很久..
關於查詢每天的最後一筆這種好像蠻常見的需求, 上網卻沒看到什麼解法.
不過還好最後有做出來, 雖然醜醜的.
在這分享一下.
不過這一定是個破解法, 希望有人可以提供更好的解法, 謝謝..
ps. 這個是 derby 的語法

SQL

我有一個 table, 有三個欄位, ID 是用 UUID
create table TEST_DATE (
    ID varchar(40), 
    EMP_ID varchar(40), 
    MY_DATE timestamp
)
然後我的需求是, 找出某個 EMP_ID 每天的最後一筆資料, 結果就是
select * from TEST_DATE d2 where d2.MY_DATE in (
    select MAX_DATE from ( (
        select DATE(d.MY_DATE) DAY, max(d.MY_DATE) MAX_DATE 
        from TEST_DATE d 
        where d.EMP_ID = '123456'
        group by DATE(d.MY_DATE) 
    ) T
) )