2010年8月28日 星期六

使用Hibernate Tool 由資料表自動建立Java Class

 

  1. 新建專案
    image
  2. 設定專案的Build Path,加入JDBC Driver及Hibernate的library設定 
     image
  3. 切換到Hibernate Tool perspective
    image
  4. 對新建的Project按右鍵,新建Hibernate Configuration File
    image
  5. 指定Configuration file存放的位置
    image
  6. 依下圖填上資訊,勾選Create a console configuration
     image
  7. 按下一步後,就會帶入Console Configuration 設定,選定Database Connection後,按下Finish完成Console的設定
    image
  8. 切換到Hibernate Configurations view
    image
  9. 依序展開Hibernate Console Configuration
    image
  10. 選取Hibernate Code Generation Configuration
    image
  11. 設定Main tab的內容(最好給定package名稱),記得勾選Reverse engineer from JDBC configuration
     image
  12. 勾選要自動產生的東西後,按Run
     image
  13. 程式碼產生完成
    image 

Java Persistence Framework比較

資料來源:http://www.javaworld.com/javaworld/jw-07-2008/jw-07-orm-comparison.html

目前Java關於persistence的Framework主要有iBATIS、JPA和Hibernate三種,這篇文章簡單地介紹了如何選擇這三種framework來做persistence的處理。

他們之間的主要差異在於,iBAITS並沒有提供完整的O/R mapping,它所做的是Object與 SQL return result之間的mapping。而且iBAITS運作時,是直接使用內嵌的SQL來查詢資料庫,所以Programmer必需直接撰寫SQL,且必需綁定在資料庫伺服器的提供商。不過這種設計,programmer可以直接掌控SQL,所以能不斷tune出效能最好的SQL

Hibernate及JPA都有完整的O/R mapping的功能,它們都不直接採用SQL,而是有自己的查詢語言(雖然長得很像SQL),在執行時期再動態產生SQL進行資料庫查詢。也因為如此,使用其所開發的程式,不會有綁定在某家資料庫系統的問題。相較於Hibernate,JPA提供的是一組標準,任何provider都可以去實作JPA標準(如Apache的 OpenJPA),因此實際執行的效能及一些特性就必需看各家JPA provider實作的程度如何;而Hibernate本身就是一個實作,算是目前滿活躍的一個framework,有許多人在使用及維護。

最後iBAITS支援.NET、及Ruby on Rails;Hibernate支援Java及.NET;而JPA(Java Persistence API)當然只支援Java

Features iBATIS Hibernate JPA
Simplicity Best Good Good
Complete ORM solution Average Best Best
Adaptability to data model changes Good Average Average
Complexity Best Average Average
Dependence on SQL Good Average Average
Performance Best Best N/A *
Portability across different relational databases Average Best N/A *
Portability to non-Java platforms Best Good Not Supported
Community support and documentation Average Good Good

2010年1月11日 星期一

Unicode encoding 基本概念

參考來源:

http://docs.python.org/howto/unicode.html

http://www.joelonsoftware.com/articles/Unicode.html

最近在學Python,到了Python網站上逛逛時,發現Unicode How to 這篇文章後,才算是對所謂的 unicode、encoding的觀念有比較正確的了解。

一般大家對Unicode的了解是,它是用來解決原本ASCII編碼無法支援英語系以外字元的問題所開發出來的編碼方式。依照它的歷史演進,有 UTF-16、UTF-8…等等的不同implementation。一般人不了解的是,Unicode定義的只是一個個的 code point,並將這個code point指向某個字元,這裡的字元是一個抽象的概念。如 A 和 A 都對應到同一個code point;而A與 a則對應到不同的code point。為了與ASCII相容,原本 0~127的ASCII碼到了Unicode中,還是代表同樣的字元,如0x61在Unicode或ASCII中,都是對應到 a這個字元。

Encoding的概念

接下介紹encoding這個觀念。前面說Unicode是定義一個個的抽象的 code point對應,那如何把一連串的Unicode 字串儲存到電腦的記憶體或檔案中呢? 比方說,若用Unicode表示Hello這個字串,就會變成這樣

  H        e             l            l          o
U+0048 U+0065 U+006C U+006C U+006F

當要將這個字串儲存到電腦的記憶中時,需要把每個字元的Unicode碼,轉換成一個個實際的 byte 資料,這個過程就叫做Encoding。相反地,如果你拿到一連串的byte(可能是瀏覽器抓到的、可能是由檔案讀出來的)時,則需要將這些byte資訊,重新解釋回它所代表的字元,這個過程叫decoding。如下圖(此為示意圖,實際上並不一定這樣作,請接下去看)

image

一般人(也許只有我)都會以為,Unicode的做法只是單純地用2個byte來表示字元(如上圖的例子),這樣就有 2^16 個字元可用,但實際上,並不是這麼簡單。事實上,Unicode有許多不同版本,如UTF-16或UTF-8。UTF-16的作法就是用16個bit來代表一個字元;而UTF-8則是使用8個bit來encode字元。其中UTF-16是較早期的版本,它在推出時,並不受到喜愛,原因就在上面的例子

           它會造成空間的浪費!!!

因為當時,internet還沒有像現在這麼恐怖,所以電腦還是在阿兜阿 的世界比較風行,對於阿阿兜阿來說,他們根本用不到 ASCII以外的字元,如果為了要apply UTF-16,原本只要1個byte(0x48h) 就可以代表H這個字元,用了UTF-16後,要用2個byte(0x0048h)來代表,而第二個byte中所有的bit的值都為零! 等於是浪費了一個byte。這對於那些阿兜阿根本不make sense,所以使用的人很少。直到後來UTF-8的出現,Unicode才被大家所接受。那麼UTF-8是如何使用8個bit來做encoding的工作呢?UTF-8使用的編碼規則如下:

  1. 如果code point < 128,則用單一個byte來表示該字元(也就是,原本ASCII的字元完全不受影響)
  2. 如果 128<=code point <=0x7ff,則用2個值介於 128 ~255的 byte來表示
  3. 如果code point> 0x7ff,則用3個或4個 值介於 128~255的byte來表示

如此一來,UTF-8既不會影響原本使用ASCII編碼的使用者,又可以將其它語言的字元都涵蓋進來,因此成為現在Unicode編碼的主流

瀏覽器如何知道要用何種編碼?

在瀏覽網頁時,有的時候會出現無法正常顯示頁面的狀況,這是因為瀏覽器用了錯誤的編碼機制來解讀資料。那瀏覽器是如何決定要如何解讀收到的資料呢?答案就是 Content-Type:text/plain;charset=”UTF-8”這個資訊。

COntent-Type這個資訊可以放在HTTP的header,也可以放在 HTML的 <head>…</head>中,如

<html>
  <head>
  <meta http-equiv="Content-Type"   content="text/html; charset=utf-8">

要知道瀏覽器收到的資料只是一連串的byte資訊,需要另外告訴瀏覽器這個byte資訊是用那一種編碼方式 encode而成的,這樣它才能以正確的編碼機制來解讀Byte的資訊。如果HTTP header或 HTML的<head>…</head>中沒有給定Content-Type資訊時,瀏覽器會試著去猜可能的編碼方式,然後用該編碼方式來做解讀。既然是用猜的,就可能會有猜錯的狀況,結果就是顯示出亂碼了!

2010年1月6日 星期三

在python安裝新的package

一般Python的 package會有提供 setup的 script,不過要使用這個script前,需先安裝 setuptools這個套件,此套件可以在 http://pypi.python.org/packages/2.6/s/setuptools/ 這個網址找到。

安裝setuptools套件後,就可以參照所要安裝的套件中的README檔案的指示,用新套件提供的setup.py來安裝了,如下

C:\Package_Source_DIR>C:\Python26\python.exe   setup.py   install

2009年12月25日 星期五

Python Dictionary資料型態的方法

Dictionary資料型態的建立

Dictionary相對於Perl的Hash資料型態,不像list或tuple型態必需用 integer當作index,dictionary是使用名稱來做index。

在Python中宣告dictionary資料型態的方法很簡單。由下面的但子可以看到,dictionary資料型態用 { }包覆,其中,每一個index和value pair用逗號區隔開來;而index和value之間則用 冒號 區隔

>>> x = {'one':1,'two':2}

>>> x
   {'one': 1, 'two': 2}

除此之外,也可以使用dict()這個function來定義,用法如下。dict()這個function的參數可以是其它的dictionary或sequence(如list或tuple)

>>> x = dict([('one',1),('two',2)])

>>> x
   {'one': 1, 'two': 2}

下面為另一種寫法,注意此寫法與上一個例子的差異! 在這個寫法中,one和two等keyword不需用引號括起來;而上面的寫法中,one和two這兩個keyword就必需用引號括起來

>>> x=dict(one=1,two=2)

>>> x
   {'one': 1, 'two': 2}

Dictonary資料型態的方法

與sequence資料型態一樣,dictionary也有下列幾種基本的方法

  • len(dic):回傳dic這個dictionary有多少的key-value pair
  • dic(k):回傳k這個key所指向的value
  • del dic(k):刪除以k做為key的這組
  • k in dic:檢視dic中,有沒有k這個key

除了上述方法之外,dictionary還有下列專屬的方法

clear:

clear可以把dictionary中的東西清空。如

>>> dic
   {'two': 4, 'one': 2}

>>> dic.clear()

>>> dic
   {}

copy:

Copy可以複製dictionary的內容。如

>>> dic
  {'two': 2, 'one': 1}

>>> dic2 = dic.copy()

>>> dic2
  {'two': 2, 'one': 1}

get:

get這個方法可以用key來找尋相對的value,與 dic['key']這個取值方式的差別在於,當key值不存在於dic這個dictionary時,dic['key']這種取值方式會回傳exception。

>>> dic['key']

Traceback (most recent call last):
   File "<pyshell#104>", line 1, in <module>
    dic['key']
   KeyError: 'key'

若用get這個方法取值,當key值不存在時,不會出現exception

>>> dic.get('key')


   >>>

若要定義key值不存在時,要回傳何預設值,可用

>>> dic.get('key','N/A')
  'N/A'

items:

這個方法可以將dictionary中的所有元素以 list的方式回傳,回傳的元素並不會遵照固定的順序

>>> dic.items()
   [('two', 2), ('one', 1)]

iteritems:

和items一樣,也是回傳dictionary中的元素。不同的地方在於,它是以一個 iterator 物件的方式回傳。接著可以在迴圈中,用此物件將元素一一列出

>>> it = dic.iteritems()

>>> it
   <dictionary-itemiterator object at 0x00DC0500>
   >>> list(it)
   [('two', 2), ('one', 1)]

keys及 iterkeys:

keys會回傳dictionary的所有key值;iterkeys則是回傳一個iterator物件,可由該物件取得key值

popitem:

將dictionary中的元素移出,類似於list的pop功能。不過因為dictionary沒有順序觀念,所以移出的順序不固定

>>> dic
  {'three': 3, 'two': 2, 'one': 1}
   >>> dic.popitem()
  ('three', 3)
  >>> dic
  {'two': 2, 'one': 1}

values及itervalues:

與keys及iterkeys功能相似,不過它回傳的是dictionary的value