2009-06-18

Blogger模組套件-最新文章、最新回應及Blog聯播

由於本身自己javascript不強,沒辦法自己寫出(改天有空再研究研究),所以這篇就轉貼囉!!轉貼來自:Abin's Tech Note沒附上Blog聯播的code(因為本身沒用到),有興趣可以去原作者的Blog看看。
##CONTINUE##
紅色的部分字可以自行更改的,例如:我的Blog只有我一個作者,所以在最新文章裡面,我就將'+authorname+': 這串字給拿掉,因為不必要顯示!!
最新文章:
<div id="newPosts">
  Loading...
  <noscript>failed!<br/>Javascript not supported here!</noscript>
</div>
<script>
function handlePosts(json) {
  function compareentry(a,b) {
    order= Date.parse(a.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/, '$1/$2/$3 $4 GMT')) - Date.parse(b.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/, '$1/$2/$3 $4 GMT'));
    return 0-order;
  }
  var temp = '<ul>';
  var PostShow = 10;
  var sortentry = json.feed.entry.sort(compareentry);
  for (var i=0, Post; Post = sortentry[i]; i++) {
    if (i >= PostShow)
      break;
    var title=Post.title.$t;
    var j=0;
    while (j < Post.link.length && Post.link[j].rel != "alternate")
      j++;
    var link=Post.link[j].href;
    var authorname=Post.author[0].name.$t;
    var timestamp=Post.published.$t.substr(0,10);
    temp += '<li><span class="item-title">'+authorname+': <a href="'+link+'">'+ title +'</a> - '+timestamp+'</span></li>';
  }
  temp+="</ul>";
  document.getElementById("newPosts").innerHTML = temp;
}
</script>
<script src="/feeds/posts/default?alt=json-in-script&callback=handlePosts" type="text/javascript">


最新回應
<div id="newComments">
  Loading...
  <noscript>failed!<br/>Javascript not supported here!</noscript>
</div>
<script>
function handleComments(json) {
  function compareentry(a,b) {
  order= Date.parse(a.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/, '$1/$2/$3 $4 GMT')) - Date.parse(b.published.$t.replace(/^(\d{4})-(\d{2})-(\d{2})T([0-9:]*)([.0-9]*)(.)(.*)$/, '$1/$2/$3 $4 GMT'));
  return 0-order;
  }
  var temp = '<ul>';
  var CommentShow = 10;
  var sortentry = json.feed.entry.sort(compareentry);
  for (var i=0, Comment; Comment = sortentry[i]; i++) {
    if (i >= CommentShow)
      break;
    var title=Comment.content.$t.substr(0,30);
    title=title.replace(new RegExp("BR","gm"), "");
    title=title.replace(new RegExp("</>","gm"), " ");
    var link=Comment.link[0].href.replace("#", "#comment-");
    var authorname=Comment.author[0].name.$t;
    var timestamp=Comment.published.$t.substr(0,10);
    temp += '<li><span class="item-title">'+authorname+': <a href="'+link+'">'+ title +'</a> - '+timestamp+'</span></li>';
  }
  temp+="</ul>";
  document.getElementById("newComments").innerHTML = temp;
}
</script>
<script src="/feeds/comments/default?alt=json-in-script&callback=handleComments" type="text/javascript"/></script>

2009-06-17

Google提供免費的部落格-Blogger

個人是認為google的blogger是適合常常會在google大神找資料且又不喜歡複雜的操作介面的人使用,為什麼是要常常會在google上找資料的呢?因為google的blogger提供了精簡的功能及簡易的操作還有就是可以擴充模組元件,所以其他你想要的功能,你可能就要到網路上搜尋一下,都有很詳盡的解說安裝,如果沒辦法耐著性子到網路上找尋的話,不要輕易嘗試,個人是很喜歡google的blogger後台操作介面,很視覺化的從上至下的階層,只能用一目了然形容,寫文章時還會自動儲存。像是其他一些知名的blogger提供了很多強大的功能,但是有時要找那個功能,還真的是要花一點時間找,這是自己本身的經驗,因為平常coding已經眼花瞭亂了,想要輕鬆寫的Blogger還要給它整一下,可能就去睡覺了吧!!所以來試試google的blogger吧

使用google的blooger 相當簡單
1.註冊google的帳號一個(建議是先申請gmail再去使用google其他功能,因為直接申請google帳號需要一個email,而且登入時是要輸入email和密碼,如果是直接申請gamil的話,就是輸入帳號和密碼,個人是比較喜歡這樣,都要使用google還要輸入其他的email,還真是有點不舒服!!)
Google
  1. 進到google首頁點最上方的gmail
  2. 點選右下方的建立帳戶
  3. 填寫相關資料
  4. 完成後,即可使用google提供大量的功能

2.登錄google帳戶
3.最選網頁最上面的"更多"的連結
4.點選Blogger
接著就開始申請blogger囉~~

2009-06-13

log4j基本觀念

根據官方網站和網路上資料整理的一些心得,雖然一些簡介是來自網路上的,但是其中也加了很多我的使用心得,要引用記得附註連結。

log4j 學過java的人應該都知道這個好用的API,java學了那麼久竟然還不會用,真是太冏了,決定來學一下,順便整理一下,有需要的話網友看看吧!!
##CONTINUE##

log4j簡介

Log4j 是一套開放源碼的工具,方便編程人員在程式中加入 log 機制,並輸出到各種目標上。Log4j 能夠透過外部的設定檔(properites 或 XML)進行設定。Log4j 能夠將 log message 寫到 console、 檔案、串流、TCP 協定的伺服器或Unix Syslog daemon 等等,相當的多得應用。Log4j 具有 5 種 log 等級(DEBUG、INFO、 WARN、ERROR、FATAL),可用於不同的系統狀態下所產生的訊息。

Log4j的三大元件

  • Logger - 由編程人員在程式中使用,進行 logging 的元件
  • Appender - 負責將 log message 輸出到各種裝置上
  • Layout - 決定 log message 的格式


Log4j的階層架構


一個程式可擁有多個logger,每個logger以名稱做區分,並且每個logger有階層的概念。
Example:假如你定義了 "com.util"此logger的一些設定(輸出格式、log等級或是輸出裝置),如果你沒有定義"com.util.cnn"此logger的設定,則他將會延續"com.util"logger的設定。
預設最高的logger是root logger且他一定存在,他可隨時從在程式中以 Logger.getRootLogger(),其它 logger 則以 Logger.getLogger(String loggerName) 取得。

Logger


Logger可以被指派等級。能夠指派給 Logger 的等級有 : DEBUG、INFO、WARN、ERROR、FATAL 5 種,定義在 org.apache.log4j.Level 類別中。這 5 種等級的高低順序為 FATAL > ERROR > WARN > INFO > DEBUG。
Logger等級決定可印出的message數量,Logger只印自身等級或是高於自身等級的message。
Exmaple: 定義一個Logger的等級為WARN,則他只會印出FATAL、ERROR及WARN的message。
Logger之間以名稱區分,所以在程式中任何地方,呼叫 Logger.getLogger(),並傳入同一個 Logger名稱,則會得到同一個Logger的reference。

Appender


一個Looger將會透過Appender將message輸出到定的裝置上,一個Logger可擁有多個Appender,因此可輸出到多個裝置上。

Layout


Logger可透過Layout來配置輸出到裝置上message的格式。
PatternLayout 的 格式字元列表如下:

  • %c 輸出日誌訊息所屬的類別的全名
  • %d 輸出日誌時間點的日期或時間,指定格式的方式:%d{yyy-MM-dd HH:mm:ss }。
  • %l 輸出日誌事件的發生位置,即輸出日誌訊息的語句處於它所在的類別的第幾行。
  • %m 輸出代碼中指定的訊息,如log(message)中的message。
  • %n 輸出一個列尾符號。
  • %p 輸出優先階層,即DEBUG,INFO,WARN,ERROR,FATAL。如果是調用debug()輸出的,則為DEBUG,依此類推。-5p 代表將此字串填滿至 5 個字元,以空白補不足處。
  • %r 輸出自應用啟動到輸出該日誌訊息所耗費的毫秒數。
  • %t 輸出產生該日誌事件的線程名。
  • %f 輸出日誌訊息所屬的類別的類別名。


設定log4j


有2種方式可以設定log4j,一個是在撰寫java code時設定,另一個是外部設定(*.properties),外部設定比較有彈性且易於修改,不像前者還要重新編譯code。
1.在撰寫java code時設定:

package codinghunter.log4j;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
public class Log4jTest {
private static Logger logger = Logger.getLogger(Log4jTest.class);
public static void main(String[] args) {
BasicConfigurator.configure();
logger.info("This is an info message.");
logger.debug("This is a debug message.");
}
}

BasicConfigurator.configure(); 就是以預設值去設定log4j
2.外部設定(*.properties)
首先在classpath下建立一個log4j.properties的檔案,設定如下:

//定義 Root Logger 的等級為 INFO,且為其指定一個 appender 名為 rootAppender.
log4j.rootLogger=info, rootAppender

//指定 rootAppender 的類型為ConsoleAppender(輸出再主控台下)
log4j.appender.rootAppender=org.apache.log4j.ConsoleAppender

//指定 rootAppender 的 Layout.
log4j.appender.rootAppender.layout=org.apache.log4j.PatternLayout

//指定 rootAppender Layout 的輸出格式.
log4j.appender.rootAppender.layout.ConversionPattern=%d- %-p -%c - %m%n

//自訂自己的logger,可定義到單一一個class也可以是一個package
log4j.logger.codinghunter.log4j.Log4jTest=INFO, log4jAppender
log4j.appender.log4jAppender=org.apache.log4j.RollingFileAppender
log4j.appender.log4jAppender.File=c:/tmp/codinghunter/Log4jTest/log4j.log
//log4j.appender.log4jAppender.File 為輸出的路徑,如果設定的路徑中有資料夾不存在,它會自動幫你建立
log4j.appender.log4jAppender.MaxFileSize=100KB
log4j.appender.log4jAppender.MaxBackupIndex=10
log4j.appender.log4jAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.log4jAppender.layout.ConversionPattern=%c - %m%n



番外篇:


以下是自動碰到的一個問題,那就是想要一個Logger擁有2個不同等級的Appender,看似好像很一般,但是仔細看一下,指定一個logger的Appender時可以一次指定多個,但設定的等級皆為同一個
Ex:log4j.logger.codinghunter.log4j.Log4jTest=INFO, log4jAppender,log4jAppender2
2個Appender設定的等級皆為INFO,但是我想要一個INFO另一個DEBUG怎麼做呢??
最後加上這個即可:
log4j.appender.log4jAppender.Threshold=DEBUG

其他資料


Log4j提供的appender有以下幾種:
org.apache.log4j.ConsoleAppender(輸出在控制台)
org.apache.log4j.FileAppender(輸出到文件檔案)
org.apache.log4j.DailyRollingFileAppender(每天產生一個文件檔案)
org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的时候產生一個新的文件)
org.apache.log4j.WriterAppender(將log信息以串流格式發送到任意指定的地方)

Log4j提供的layout有以下幾種:
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以任意地指定布局模式)
org.apache.log4j.SimpleLayout(包含log信息的級別和信息字符串)
org.apache.log4j.TTCCLayout(包含log產生的时間、線程、類别等等信息)

上面有提到對單一個logger的Appender等級的設定,其實還有可以指定package或是class的等級
log4j.logger.codinghunter.log4j.Log4jTest = DEBUG
log4j.logger.codinghunter.log4j = INFO

2009-06-01

自動增加字段

動增加這個語法真的是好用,新增一筆資料進去,自動幫你產生一個id

Ex:
create table TableName (
SurveyId int unsigned not null auto_increment,
primary key(SurveyId))
};

auto_increment 的那個參數一定要為primary key ,如果還有其他的primary key則會發生錯誤

若已存在table:
alter table TableName add SurveyId int unsigned auto_increment , add primary key(SurveyId);


可用此語法移除
alter table OtherPrimarykeyName drop primary key;

ps. 型態不一定要用 int unsigned ,int 也行

取得MySQL中的自動字串

EX:
Table 型態 : survey ( SurveyId int unsigned not null auto_increment ,
SurveyName varchar(20) not null ,
SurveyTemplateId varchar(5) not null)

Statement stmt;
stmt.executeUpdate ( " insert into survey ( SurveyName , SurveyTemplateId ) values( ' Name ' , ' Id ' );

int autoIncKeyFromFunc = -1;
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next())
autoIncKeyFromFunc = rs.getInt(1);
rs.close();

autoIncKeyFromFunc就是自動字串

取的方法好像好幾種,這只是其中一種

POI之Hssf的formula bug

問題是:
使用 countif 這個function 之後所產生該欄位的值是 #value!
使用辜狗大神找了很久都沒找到,有的是有人發問題但是沒有解...
後看發現問題點是在於該欄位沒有計算所導致,因為我點選fx之後值就算出來了
官網FormulaEvaluation的說明
所以猜測應該是沒計算所導致 依照官網的範例
就在程式碼中加上這行 "evaluator.evaluateFormulaCell(c);"
但是根本沒有這個"evaluateFormulaCell()" 傻眼...難道版本不同??
找到只有evaluate()能用,所以就將就用一下,試出來的結果還是一樣...囧...

後來一直反覆看都不知道為什麼??
在最上頭看到一個Note
In versions of POI before 3.0.3, this code lived in the scratchpad area of the POI SVN repository. If using an such an older version of POI, ensure that you have the scratchpad jar or the scratchpad build area in your classpath before experimenting with this code. Users of all versions of POI may wish to make use of a recent SVN checkout, as new functions are currently being added fairly frequently.
版本問題??
接著去湯姆貓看一下lib的版本,發現我真是個笨蛋ㄚ,因為我湯姆貓中poi的版本竟然有3個....
把舊的移除,留最新的版本一試
眼淚都要留下來了....
卡了好久終於有值了,而且我也把evaluator.evaluate()拿掉也可以,就照一般寫formula的方法
最後確定3.1沒有這個問題而舊的2個版本都不行(3.0.2和3.0)

POI之Hssf的跨欄置中

跨欄置中這個功能是常常被用到的
剛好專研有用到,查了一下用法大概如下:
HSSFSheet s;
s.addMergedRegion(new Region(0,(short)0,1,(short)0));
new Region() 裡面有4個參數
1.row起點位置
2.cell起點位置
3.row結束位置
4.cell結束位置
蠻直觀的,應該很好理解