Hibernate SQLQuery 範例

String hql ="SELECT {customerTank.*},{customer.*} FROM Customer_Tank customerTank , Customer customer  WHERE customerTank.customerId = customer.customerId " ;
SQLQuery sqlQuery= session.createSQLQuery(hql);
sqlQuery.addEntity("customerTank",CustomerTank.class);
sqlQuery.addEntity("customer",Customer.class);

 

result :
Hibernate: SELECT customerTank.customerId as customerId0_, customerTank.tankId as tankId0_, customerTank.ownQuantity as ownQuant3_111_0_, customerTank.borrowQuantity as borrowQu4_111_0_, customerTank.mortgageQuantity as mortgage5_111_0_, customerTank.mortgagePrice as mortgage6_111_0_, customerTank.oweQuantity as oweQuant7_111_0_, customerTank.discountPrice as discount8_111_0_, customerTank.distancePrice as distance9_111_0_, customerTank.storeyPrice as storeyP10_111_0_,customer.customerId as customerId1_, customer.customerName as customer2_109_1_, customer.contact as contact109_1_, customer.tel as tel109_1_, customer.address as address109_1_, customer.remark as remark109_1_, customer.creationUser as creation7_109_1_, customer.creationDate as creation8_109_1_, customer.chargeType as chargeType109_1_, customer.stationId as stationId109_1_, customer.salesman as salesman109_1_, customer.busId as busId109_1_, customer.settlementType as settlem13_109_1_, customer.settlementDay as settlem14_109_1_, customer.receipt as receipt109_1_, customer.creditAmount as creditA16_109_1_, customer.customerType as custome17_109_1_, customer.distroId as distroId109_1_, customer.arrearsAmount as arrears19_109_1_, customer.leftovergasType as leftove20_109_1_, customer.leftovergasPrice as leftove21_109_1_, customer.numberIndex as numberI22_109_1_, customer.deliveryPrice as deliver23_109_1_, customer.pickupPrice as pickupP24_109_1_, customer.degreeConvert as degreeC25_109_1_, customer.degreePrice as degreeP26_109_1_, customer.lastSellDate as lastSel27_109_1_, customer.overRecAmount as overRec28_109_1_, customer.mortgageAmount as mortgag29_109_1_, customer.mortgageUnRecAmount as mortgag30_109_1_, customer.leftovergasAmount as leftove31_109_1_, customer.customerNewOld as custome32_109_1_, customer.degreeNo as degreeNo109_1_, customer.modifyUser as modifyUser109_1_, customer.modifyDate as modifyDate109_1_ FROM Customer_Tank customerTank , Customer customer WHERE customerTank.customerId = customer.customerId
result length = 15
 [1]: [0]buddyworks.hibernate.cust.CustomerTank@75c744 [1]buddyworks.hibernate.cust.Customer@17361e2
 [2]: [0]buddyworks.hibernate.cust.CustomerTank@a50da4 [1]buddyworks.hibernate.cust.Customer@229ed4
 [3]: [0]buddyworks.hibernate.cust.CustomerTank@e9a7c2 [1]buddyworks.hibernate.cust.Customer@229ed4
 [4]: [0]buddyworks.hibernate.cust.CustomerTank@1503458 [1]buddyworks.hibernate.cust.Customer@9ca1fb
 [5]: [0]buddyworks.hibernate.cust.CustomerTank@14e9851 [1]buddyworks.hibernate.cust.Customer@9ca1fb
 [6]: [0]buddyworks.hibernate.cust.CustomerTank@f1fad1 [1]buddyworks.hibernate.cust.Customer@89ec59
 [7]: [0]buddyworks.hibernate.cust.CustomerTank@1c7d56b [1]buddyworks.hibernate.cust.Customer@89ec59
 [8]: [0]buddyworks.hibernate.cust.CustomerTank@8c858a [1]buddyworks.hibernate.cust.Customer@1933acb
 [9]: [0]buddyworks.hibernate.cust.CustomerTank@f9104a [1]buddyworks.hibernate.cust.Customer@1933acb
 [10]: [0]buddyworks.hibernate.cust.CustomerTank@19c9f16 [1]buddyworks.hibernate.cust.Customer@1909385
 [11]: [0]buddyworks.hibernate.cust.CustomerTank@c51614 [1]buddyworks.hibernate.cust.Customer@12ca580
 [12]: [0]buddyworks.hibernate.cust.CustomerTank@257b34 [1]buddyworks.hibernate.cust.Customer@bbbd0e
 [13]: [0]buddyworks.hibernate.cust.CustomerTank@178efd8 [1]buddyworks.hibernate.cust.Customer@bbbd0e
 [14]: [0]buddyworks.hibernate.cust.CustomerTank@ca5bff [1]buddyworks.hibernate.cust.Customer@bbbd0e
 [15]: [0]buddyworks.hibernate.cust.CustomerTank@15dd32a [1]buddyworks.hibernate.cust.Customer@bbbd0e
張貼在 未分類 | 發表留言

XSL 使用 CSS 與 JavaScript 範例

<style type="text/css">
<![CDATA[
.tableHeaderC {background-color:#308DBB; color:white; font-size:16px; font-weight:bold; text-align:center;}
.tableHeaderR {background-color:#308DBB; color:white; font-size:16px; font-weight:bold; text-align:right;}
.tableRegionC {font-size:16px; text-align:center;}
.tableRegionR {font-size:16px; text-align:right;}
input{font-size:16px; font-family:arial,helvetica,clean,sans-serif;}
]]>
</style>
<script type="text/javascript">
<![CDATA[
function countCashAmt(){
 document.getElementById(‘cashAmt’).innerHTML = (document.getElementById(‘cashQtyText’).value * document.getElementById(‘cashAmtSingleText’).value)+";
}
function updateCashAmt(index){
 opener.setCashAmount(index, document.getElementById(‘cashQtyText’).value,
     document.getElementById(‘cashAmtSingleText’).value);window.close();
 window.close();
}
]]>
</script>
張貼在 XML | 發表留言

顯示 javascript 物件 所有屬性

var actionData = {a:"aa", b:"bb", ……};
for(x in actionData) alert( x + "-" + actionData[ x ] );
張貼在 JavaScript | 發表留言

Hibernate主鍵生成方式 Hibernate generator

Hibernate主鍵生成方式 Key Generator

主鍵產生器可選項說明:

1) assigned
主鍵由外部程序負責生成,無需Hibernate參與。

2) hilo
通過hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。

3) seqhilo
與hilo 類似,通過hi/lo 算法實現的主鍵生成機制,只是主鍵歷史狀態保存在Sequence中,適用於支持Sequence的數據庫,如Oracle。

4) increment
主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存著當前的最大值,之後每次需要生成主鍵的時候將此值加1作為主鍵。
這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那麼由於各個實例各自維護主鍵狀態,
不同實例可能生成同樣的主鍵,從而造成主鍵重複異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用。

5) identity
採用數據庫提供的主鍵生成機制。如DB2、SQL Server、MySQL 中的主鍵生成機制。

6) sequence
採用數據庫提供的sequence 機制生成主鍵。如Oralce 中的Sequence。

7) native
由Hibernate根據底層數據庫自行判斷採用identity、hilo、sequence其中一種作為主鍵生成方式。

8) uuid.hex
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼後以長度32 的字符串表示)作為主鍵。

9) uuid.string
與uuid.hex 類似,只是生成的主鍵未進行編碼(長度16)。在某些數據庫中可能出現問題(如PostgreSQL)。

10) foreign
使用外部表的字段作為主鍵。
一般而言,利用uuid.hex方式生成主鍵將提供最好的性能和數據庫平台適應性。

另外由於常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。
我們可以在數據庫提供的主鍵生成機制上,採用generator-class=native的主鍵生成方式。
不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,大量並發insert數據時可能會引起表之間的互鎖。
數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀態(如對於自增型主鍵而言,此內部表中就維護著當前的最大值和遞增量),
之後每次插入數據會讀取這個最大值,然後加上遞增量作為新記錄的主鍵,之後再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據
庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生了較大影響。
因此,對於並發Insert要求較高的系統,推薦採用uuid.hex 作為主鍵生成機制。

from http://letle.javaeye.com/blog/78530

UUID : http://zh.wikipedia.org/zh-tw/UUID

java.util.UUID類別 : http://java.sun.com/javase/6/docs/api/java/util/UUID.html

張貼在 java | 發表留言

Connecting to the JMX Agent Programmatically

Connecting to the JMX Agent Programmatically

Once you have enabled the JMX agent, a client can use the following URL to access the service:

service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi

where hostName is the host name and portNum is the port number specified when the JMX agent was enabled.

A client can create a connector to the agent by instantiating an javax.management.remote.JMXServiceURL object using the URL, and then creating a connection using the JMXConnectorFactory.connect method as follows:

JMXServiceURL u = new JMXServiceURL(
  "service:jmx:rmi:///jndi/rmi:// “ + hostName + ":" + portNum +  "/jmxrmi");
  JMXConnector c = JMXConnectorFactory.connect(u); 
From : http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html
張貼在 java | 發表留言

Hibernate在session關閉之後取得相關物件

如果您使用了延遲初始,而在某些時候仍有需要在session關閉之後取得相關物件,則可以使用Hibernate.initialize()來先行載入相關物件,例如:
 
   Hibernate.initialize(user.getAddrs());    
   session.close();
   Set add = user.getAddrs();
   Object[] addo = user.getAddrs().toArray(); 
 
延遲初始只是Hibernate在取得資料時的一種策略,目的是為了調節資料庫存取時的時機以取得一些效能,
除了延遲初始之外,還有其它的策略來調整資料庫存取的方法與時機,這部份牽涉的討論範圍很大,有興趣的話,可以參考Hibernate in Action的4.4.5。
 
From :
張貼在 Java EE 5 | 發表留言

Java 如何設定.dll 或 .so 的PATH

VM参数处通过-Djava.library.path将加载路径指定到自己的lib目录
-Djava.library.path
On Android, you must use System.load and provide a full path instead of using System.loadLibrary.
This is because loadLibrary only checks /system/lib; it does not search LD_LIBRARY_PATH or your current working directory.
Unfortunately, applications can’t write to the /system/lib directory (without root).
張貼在 java | 發表留言

撰寫Makefile教學

 
這裡我們討論當你在Unix like的系統之中如何透過GNU tool幫你建立你整個專案,也許你的程式只有幾個檔案,慢慢用手編是簡單也沒問題,但是如果是大型的專案,超過幾十個檔案而且需要連結不少的函式庫,那你應該怎麼做呢?最方便的就是學習makefile和make指令,使用這個工具幫你做編譯和連結的動作。

※ 使用make好處

* 透過你所設定的條件幫你編譯好
* 方便專案管理
* 會透過檔案比對,依照相依性來編譯,不會全都編浪費時間
* 可以同時編譯函式庫或是檔案

※ make常用指令

* make -k: 會讓make在遇到錯誤的時候仍然運行,而不會停在第一個問題
* make -n: 只印出將會進行的工作,而不會真的去執行
* make -f makefile_name: 告訴make需要用那個makefile檔案。當你的make檔不是叫makefile的時候,需要自行透過-f加上你檔案名字,make才找的到你的makefile

※ make指令格式

make [option] [target] option就是上面的設定項目,而target等等會講到,就是我們將要產生出來的目標,可以接很多個目標,如果目標不寫的話預設是all。

Example:

make -n all clean
make install
make
make -f makefile2 install

※ 撰寫makefile檔案

makefile是由一堆「目標」和其「相依性檔案」還有「法則」所組成的,而法則在寫的時候前面不可以使用空格,只能使用Tab鍵,而且同一法則要換行的話需要使用"字元,而要加入註解的話要用’#’為開頭字元。

* [target] 目標 – 產生出來的東西或某個項目
* [dependency] 相依性項目 – 目標受相依檔案改變需要重新產生目標
* [rule] 法則 – 如何讓相依性項目編譯和連結來產生目標

Example:

#這是makefile的格式(註解)
[target]: [dependency] [dependency]
[TAB][rule]
[TAB][rule]
[target]: [dependency]
[TAB][rule]

整個makefile就是利用上面的格式,目標和相依性項目還有法則,組合之後就可以編出一個執行檔了,我們下面就來舉個最容易的範例。

Example:

all: myapp app.doc
myapp: main.o a.o b.o
[tab]gcc main.o a.o b.o -o myapp
main.o: main.c a.h
[tab]gcc -c main.c
a.o: a.c a.h
[tab]gcc -c a.c
b.o: b.c b.h
[tab]gcc -c b.c

make (呼叫make執行)

這是個最簡單的範例,我們來看一下它怎麼運做的,首先執行make的時候都會執行all這個目標,如果沒有設定all這個目標,它就會拿第一個目標來產生,在這邊看到要產生all的話,需要兩個檔案myapp和app.doc(主程式和說明檔),make開始會去找尋如何產生myapp和 app.doc的方法,所以myapp會成為下一個要產生出來的目標,所以要產生出myapp的話需要有main.o, a.o, b.o這三個檔連結在一起才可以產生myapp執行檔,那該怎麼產生呢?我們的法則有寫要使用gcc main.o a.o b.o -o myapp來產生,但是我們連main.o, a.o, b.o都沒有了,怎麼可能可以產生myapp呢?所以現在要先產生出這些目的檔,以main.o來看,它就成為下一個目標,它需要main.c和a.h才可以產生出來,而產生的法則是gcc -c main.c就可以產生出main.o檔了而a.o, b.o也是同樣的方式產生,一旦main.o a.o b.o都產生了,那麼目標myapp就可以透過法則來產生出來了。

所以寫makefile最重要的事情就是先搞清楚你最後產生什麼東西,該怎麼產生,那它需要什麼檔,再依它需要的檔怎麼產生,寫它的法則,一直追到最後的結果就是怎麼產生.c檔,就是本來的source了,那就要自己寫了^^。

※ 多重target(目標)

目標就是我們所定最後要產生的結果,所以我們可以定一些目標,讓shell script幫我們做很多事情,而常用makefile裡面會寫的目標如。

* install 產生完可執行檔之後怎麼將程式安裝到指定位置
* clean 只想產生執行檔,剩下的目的檔不需要可以刪除
* uninstall 從系統之中整個移除你安裝的所有檔案

Example:

all: myapp app.doc
myapp: main.o a.o b.o
[tab]gcc main.o a.o b.o -o myapp
main.o: main.c a.h
[tab]gcc -c main.c
a.o: a.c a.h
[tab]gcc -c a.c
b.o: b.c b.h
[tab]gcc -c b.c
#install 安裝套件
install: myapp app.doc
[tab]cp myapp app.doc /usr/local/myapp/
#clean 刪除產生出來的目的檔
clean:
[tab]rm -f *.o

make install (呼叫make執行install target)

在範例中我們增加了install和clean兩個目標,install主要就是把產生出來的檔案複製到我們想要安裝的地方,而clean的話則是把目標下面有的.o檔都移除或是要重新建立專案的時候,先把所有的檔都移除。

※ make的巨集(macro)

想想如果一個專案檔案好幾十個的話,那你不就目標相依性還有法則一行一行打到死嗎?所以make可以使用巨集讓你很方便的更改你的資料,或是編譯器或是參數等等的使用方法。

Example:

CC = gcc 指定
$(CC) 叫用
CFLAGS = -ansi -Wall -g 指定
$(CFLAGS) 叫用

還可以使用一種將副檔名改成別的副檔名的巨集使用方式,可以讓你輕鬆的將本來的副檔名改成另一個副檔名,且指定給某巨集。

Example:

SRC = a.c b.c
OBJ = $(SRC:.c=.o)

有幾個特別的內部巨集,讓makeifle 更加簡明,每個巨集都是在使用之前才被展開,所以巨集的意義隨makefile的處理而有所不同。

* $? 代表需要重建的相依性項目
* $@ 目前的目標項目名稱
* $< 代表第一個相依性項目
* $* 代表第一個相依性項目,不過不含副檔名

還有兩個有用的特別字元,可以加在要執行的命令之前。

* – make會忽略命令的錯誤。
* @ make不會在標準輸出上,顯示要執行的命令。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#object
OBJS = main.o a.o b.o
#install path
INSTALL_PATH = /usr/local/myapp/

all: myapp app.doc
myapp: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
main.o: main.c a.h
[tab]$(CC) $(CFLAGS) -c -o $@ $<
a.o: a.c a.h
[tab]$(CC) $(CFLAGS) -c -o $@ $<
b.o: b.c b.h
[tab]$(CC) $(CFLAGS) -c -o $@ $<
#install 安裝套件
install: myapp app.doc
[tab]cp myapp app.doc $(INSTALL_PATH)
#clean 刪除產生出來的目的檔
clean:
[tab]rm -f *.o

make install (呼叫make執行install target)

這樣是不是方便多了,使用了$@ $<可以讓你少打很多字,而且把目的檔使用一個巨集表示,可以讓你方便管理,不會忘了打某個目的檔讓你一直編不出來而且在編譯的時候在CFLAGS可以設定編出來的模式為那一種,方便加入編譯的參數。

※ make內建的法則

到目前為止我們都很成功的寫出makefile可以幫我們編譯和連結出執行檔,但是其實我們還是重覆打了很多很類似的指令,浪費了不少的時間,然而make提供我們很多內建的法則。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#object
OBJS = main.o a.o b.o

all: myapp app.doc
myapp: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
main.o: main.c a.h
a.o: a.c a.h
b.o: b.c b.h

而make已經幫我們做了gcc -Wall -ansi -g -c -o main.o main.c(a.o b.o也一樣)的工作了為了什麼自動加入-Wall -ansi -g呢?因為我們巨集有設定CFLAGS這是make內件就有的巨集名稱,所以一旦設好了,使用內建法則的時候,就會自動的加入你要的編譯參數。

※ make檔尾的法則

使用檔尾的延伸檔名估為一個法則,所以當一個檔案有吻合檔尾法則的時候,make就知道要使用什麼法則去產生目標。

Example:

格式 .[old_suffix].[new_suffix]:
.c.o:
[tab]$(CC) $(CFLAGS) -c -o $@ $<
.cpp.o:
[tab]g++ -c $<

如此就會把這目錄下面所有的.c檔變成.o檔,而法則就是去編譯它,而如果你想更懶一點的話還可以完全不寫,直接使用內建的法則,這樣也可以直接把目錄下面的所有檔都編好,為什麼呢?因為你要編出myapp的時候需要使用到$(OBJS)所以,就算你不寫.c.o或是任何的法則,make預設都會自己產生.o檔讓你可以連結出主程式。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -s
#object
OBJS = main.o a.o b.o

all: myapp app.doc
myapp: $(OBJS)
[tab]$(CC) $(OBJS) -o $@

那幹麻還要寫什麼檔尾法則呢?其實使用預設的法則有一些缺點,就是資料夾或是檔案相依性的問題,這樣預設法則根本就會有問題,因為你要 include的資料根本不在本目錄下面,所以這時候檔尾法則就很好用了,因為可以告訴make,針對所有的.c要變成.o都要以下面的rule來做。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -s
#object
OBJS = main.o a.o b.o
#include path
INCLUDE_PATH = include

all: myapp.exe app.doc
myapp.exe: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
.c.o:
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<

上例使用檔尾法則告訴make我在編譯的時候,要用到的.h檔位置在include裡面,要去裡面找,這樣程式就不會說找不到標頭檔的問題了,但是如果你使用內件的法則,它只會選擇目前目錄下面的檔案而已。

此外在更新的版本裡還有另一種語法,就是利用萬用字元的語法,它不限用在檔尾,還可以用在全部檔名的比對上。上範例可以使用萬用字元改寫。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -s
#object
OBJS = main.o a.o b.o
#include path
INCLUDE_PATH = include

all: myapp.exe app.doc
myapp.exe: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
%.o: %.c
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<

其實感覺沒有什麼差別對吧!但是後面討論專案的時候,就會感覺到差別了,其實萬用字元法則比較適合用於編譯一個大型的函式庫,而檔尾法則適合編譯一個目錄下面所有的檔案。

※ 專案討論1

專案目錄配置如下:

* + include (目錄)
– a.h
– b.h
– c.h
– d.h
* – main.c
* – a.c
* – b.c
* Makefile

檔案相依如下:

* main.c include a.h d.h
* a.c include a.h
* b.c include b.h

建立要求如下:

* 建立二元檔main
* clean target移除全部目的檔

決定好上面的目錄結構之後還有檔案相依之後我們就開始來寫我們的makefile,但是有幾個巨集是非常建議,先寫出來的,而且請多多利用註解,可以幫助未來你看檔的時候不會不知道你在寫什麼東西。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#include path
H_PATH = include
#source
SRCS = main.c a.c b.c
#object
OBJS = $(SRCS:.c=.o)

all: main
main: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
main.o: main.c $(H_PATH)/a.h $(H_PATH)/d.h
[tab]$(CC) $(CFLAGS) -I$(H_PATH) -c -o $@ $<
a.o: a.c $(H_PATH)/a.h
[tab]$(CC) $(CFLAGS) -I$(H_PATH) -c -o $@ $<
b.o: b.c $(H_PATH)/b.h
[tab]$(CC) $(CFLAGS) -I$(H_PATH) -c -o $@ $<
clean:
[tab]-rm -f *.o

雖然是寫好了,但怎麼覺得多寫好多東西,所以呢?就要善用隱含法則幫我做最多事情,所以將上面改寫如下。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#include path
H_PATH = include
#source
SRCS = main.c a.c b.c
#object
OBJS = $(SRCS:.c=.o)

all: main
main: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
main.o: main.c $(H_PATH)/a.h $(H_PATH)/d.h
a.o: a.c $(H_PATH)/a.h
b.o: b.c $(H_PATH)/b.h
clean:
[tab]-rm -f *.o

什麼??編不出來,它說我的標頭檔都找不到,哇列,該怎辦呢?因為我們使用隱含法則幫我們做最簡單的產生.o檔的方式,它只用在同一目錄下面的檔案,但是本目錄以外,就會找不到了,所以我們就使用檔尾法則來告訴make如果要產生.o檔的話,需要的標頭檔,應該在$(H_PATH),請去那裡找。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#include path
H_PATH = include
#source
SRCS = main.c a.c b.c
#object
OBJS = $(SRCS:.c=.o)

all: main
main: $(OBJS)
[tab]$(CC) $(OBJS) -o $@
.c.o:
[tab]$(CC) $(CFLAGS) -I$(H_PATH) -c -o $@ $<
main.o: main.c $(H_PATH)/a.h $(H_PATH)/d.h
a.o: a.c $(H_PATH)/a.h
b.o: b.c $(H_PATH)/b.h
clean:
[tab]-rm -f *.o

如果就可以成功的依照makefile所寫的內容一步步的把程式產生出來了,當然你也可以用喜歡萬用字元來做把.c.o改成%.o: %.c就可以了。

※ 專案討論2

這邊我們要編譯不同目錄裡面的檔案,來建立我們自己的函式庫,而且將它移動到某個目錄之中,這是有點困難的,我們來看看以下的一些設定。

專案目錄配置如下:

* + include (目錄)
– gear_calendar.h
– gear_io.h
– gear_color.h
– gear_string.h
– trax_file.h
– trax_name.h
* + source (實作檔)
– gear_calendar.c
– gear_io.c
– gear_string.c
– trax_file.c
– trax_name.c
* + library (放函式庫的目錄)
* Makefile

檔案相依如下:

* gear_calendar.c include gear_calendar.h
* gear_io.c include gear_io.h
* gear_string.c include gear_string.h
* trax_file.c include trax_file.h
* trax_name.c include trax_name.h

建立要求如下:

* 建立libtrax.a, libgear.a兩個函式庫
* clean target移除全部目的檔
* install target移動函式庫到library目錄下

因為目前要編的是函式庫,而且還不單只有一個函式庫,所以我們把標頭檔全都放在同一個資料夾裡面,而且屬於那個函式庫的檔案就以函式庫名稱為檔名的第一部份命名,如此我們方便分類我們的檔案,而實作檔就放在另一個目錄裡面,而且以其對應的標頭檔來命名實作檔,目錄檔案分配好之後我們就可以開始設計 makefile了。

Example:

#compiler
CC = gcc
#option
CFLAGS = -Wall -ansi -s
#library path
LIBRARY_PATH = library
#include path
INCLUDE_PATH = include
#source path
SOURCE_PATH = source
#library name
ALL_LIB = libgear.a libtrax.a
#gear library need objects
GEAR_OBJS = gear_calendar.o gear_io.o gear_string.o
TRAX_OBJS = trax_name.o trax_file.o

all: $(ALL_LIB)
libgear.a: $(GEAR_OBJS)
[tab]ar rcs $@ $(GEAR_OBJS)
libtrax.a: $(TRAX_OBJS)
[tab]ar rcs $@ $(TRAX_OBJS)
gear_calendar.o: $(SOURCE_PATH)/gear_calendar.c $(INCLUDE_PATH)/gear_calendar.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
gear_string.o: $(SOURCE_PATH)/gear_string.c $(INCLUDE_PATH)/gear_string.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
gear_io.o: $(SOURCE_PATH)/gear_io.c $(INCLUDE_PATH)/gear_io.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
trax_name.o: $(SOURCE_PATH)/trax_name.c $(INCLUDE_PATH)/trax_name.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
trax_file.o: $(SOURCE_PATH)/trax_file.c $(INCLUDE_PATH)/trax_file.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
install: $(ALL_LIB)
[tab]-cp $(ALL_LIB) $(LIBRARY_PATH)
clean:
[tab]-rm -f $(GEAR_OBJS) $(ALL_LIB)

經過一番的辛苦,終於寫完了,從頭到尾一直在剪剪貼貼,我們可不可以用別的方法呢?用隱含法則好了,之先前的專案有說過了,隱含法則沒有 include path會造成編譯錯誤,那可以用.c.o的檔尾法則阿,但是又想到一個問題,檔尾法則只可以用在本目錄也,但是我們實作標(.c)和介面檔(.h)都放在不同的目錄也,我們該怎麼辦呢?那就用萬用字元法則吧!

Example:

#compiler
CC = gcc
#option
CFLAGS = -Wall -ansi -s
#library path
LIBRARY_PATH = library
#include path
INCLUDE_PATH = include
#source path
SOURCE_PATH = source
#library name
ALL_LIB = libgear.a libtrax.a
#gear library need objects
GEAR_OBJS = gear_calendar.o gear_io.o gear_string.o
TRAX_OBJS = trax_name.o trax_file.o

all: $(ALL_LIB)
libgear.a: $(GEAR_OBJS)
[tab]ar rcs $@ $(GEAR_OBJS)
libtrax.a: $(TRAX_OBJS)
[tab]ar rcs $@ $(TRAX_OBJS)
%.o: $(SOURCE_PATH)/%.c $(INCLUDE_PATH)/%.h
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
install: $(ALL_LIB)
[tab]-cp $(ALL_LIB) $(LIBRARY_PATH)
clean:
[tab]-rm -f $(GEAR_OBJS) $(ALL_LIB)

我們先來看看%.o: $(SOURCE_PATH)/%.c $(INCLUDE_PATH)/%.h以這個相依來說,make會先看看本目錄有沒有gear_calendar.o檔,如果沒有的話,會相依於我們同檔名在source/和include/的實作檔和介面檔,所以make可以找到實作檔且將它編譯出來。而%代表所有目錄下的檔名,在這裡有的檔名是 gear_calendar.o gear_io.o gear_string.o trax_name.o trax_file.o這些包在$(GEAR_OBJS)和$(TRAX_OBJS)兩個巨集裡面。

最後在透過ar指示將產生出來的.o檔依造我們設定的$(GEAR_OBJS)和$(TRAX_OBJS)兩個巨集,包在不同的static library之中,如果有函式庫不會包的話,可以參考本部落格的文章(Make Library for Linux),裡面會教三種函式庫(static library, shared library, dynamic library)。

因為只是產生兩個函式庫而已,但是我們還沒有真的安裝到library裡面可以讓別人使用,所以使用make install來安裝,請注意一下install: $(ALL_LIB)這個相依性是libgear.a libtrax.a要有存在,因為需要存在,所以它需要先去編出這兩個函式庫才可以安裝,所以不論你直接make install 或是make,它都會去產生兩個函式庫,而make install只是把函式庫產生出來,並且安裝到指定的目錄而已,其實你可以改成如下。

Example:

install: all
[tab]cp $(ALL_LIB) $(LIBRARY_PATH)

效果是一樣的,所以寫makefile最重要的是對此專案要很了解需要編什麼檔,什麼函式庫等等,而拿到別人的source通常也是透過看makefile可以了解它整個專案是怎麼產生出來,什麼介面和實作有相依性。

※ 專案討論3

這邊我們寫了一個檔案來測試我們先前建立的函式庫,使用我們自己的介面,所以討論2的部份需要真的完全了解。

專案目錄配置如下:

* + libgear (函式庫)
+ include (介面標頭檔)
+ source (介面實作檔)
+ library (函式庫使用檔)
* space.c
* Makefile

檔案相依如下:

* space.c include gear_io.h gear_color.h gear_string.h

建立要求如下:

* 建立space執行檔
* clean target移除全部目的檔
* 如果函式庫還沒有建立的話,要自動建立函式庫

這邊的要求還滿難的,因為如果函式庫libgear.a libtrax.a沒有的話根本不能編space.c所以產生函式庫是很重要的,所以我們要想個辦法讓它先去確認函式庫有沒有存在,有的話才可以直接連結使用,但是不在的話,也沒有關係,我們可以讓剛剛討論2的makefile幫我們來產生函式庫。

Example:

#compiler
CC = gcc
#cflags
CFLAGS = -Wall -ansi -g
#include path
INCLUDE_PATH = libgear/include
#library path
LIBRARY_PATH = libgear/library
#use library
USE_LIB = $(LIBRARY_PATH)/libgear.a $(LIBRARY_PATH)/libtrax.a
#objects
OBJECTS = space.o

all: space
space: $(OBJECTS) $(USE_LIB)
[tab]$(CC) $(OBJECTS) $(USE_LIB) -o $@
$(USE_LIB):
[tab]cd libgear; make install
space.o: space.c
[tab]$(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
clean:
[tab]rm -f $(OBJECTS)

這邊最重要的就是確認有沒有libgear.a libtrax.a這兩個函式庫,沒有的話一切都不用搞了,所以設了一個巨集$(USE_LIB)因為路徑不一樣,所以要自己設定好,而在連結的時候需要$(USE_LIB)如果它不存在的話,就成為一個目標了,而這個目標就是叫libgear目錄下面的makefile去做,把libgear.a libtrax.a產生出來,而其它的部份怎麼編譯space.o我相信大一定已經非常熟悉了,所以這邊就不講下去了。

張貼在 Linux | 發表留言

EJB 3:Session beans

EJB 3 : Session beans

Session beans type

Session beans 有兩種: stateful and stateless.

  • stateful session bean 能自動儲存 bean 的狀態(state).也就是說 container 讓每一個client擁有自己的 session bean. 典型的範例為 shopping cart.
  • stateless session bean 故名思義為將不會管理狀態, container 不保證 client 會於 session bean pool 中取到上次所使用的 bean. 典型的範例為 checking customer credit history.

A session bean can be invoked either locally or remotely using Java RMI. Astateless session bean can be exposed as a web service.

 

The programming rules

以下為所有的 session beans 所需依照的規則:

  • A session bean 至少要有一個 business interface.
  • The session bean class 不能為 final or abstract 否則 container 無法使用它.
  • A session bean class 必須要有一個 no-argument constructor. 因為 container 利用 no-argument constructor 來 create a bean instance.( Note that the compiler inserts a default noargument constructor if there is no constructor in a Java class.)
  • A session bean class 可以繼承其他 session bean or POJO.

For example, a stateless session bean named BidManager can extend
another session bean PlaceBidBean in the following way:
@Stateless
public BidManagerBean extends PlaceBidBean implements BidManager {

}

  • A session bean class 可以繼承其他 session bean 所定義的 lifecycle callback methods 的 annotations 及 resource injections.
  • Business method 的名稱不能開頭為“ejb”.例如 "ejbCreate" or "ejbAddBid".因為可能會影響EJB內基礎操作
  • 所有的 business methods 必須為 public 且不能為 final or static.
  • 如果預期 method 是一個 remote business interface of the EJB ,則 arguments 及 return type 是為實作 the java.io.Serializable interface.

 

Coding the Enterprise Bean

The enterprise bean in this example needs the following code:
■ Remote business interface
■ Enterprise bean class

撰寫 Business Interface
Business interface 用來定義給 Client 端呼叫的 business methods. The business methods are implemented in the enterprise bean class. The source code for the Converter remote
business interface follows.

package com.starbooks.model;

import javax.ejb.Remote;

/* Note the @Remote annotation decorating the interface definition. This lets the container know that ConverterBean will be accessed by remote clients.*/

@Remote
public interface IDChecker {
     public boolean check(String id);
}

撰寫 Enterprise Bean Class
The enterprise bean class for this example is called
IDCheckerBean . This class implements the business methods ( check ) that the IDChecker remote business interface defines. The source code for the IDCheckerBean class follows.

package com.starbooks.model;

import javax.ejb.Stateless;
import com.starbooks.model.IDChecker;

/*
Note the @Stateless annotation decorating the enterprise bean class. This lets the container know that ConverterBean is a stateless session bean.
*/

@Stateless
public class IDCheckerBean implements IDChecker {

    @Override
    public boolean check(String id) {
        if(id.length()==10){
            return true;
        }
        return false;
    }

}

 

Testing the Enterprise Bean

開發測試環境:

  1. Java SE Development Kid 6 Update 11 : Java Development Kid
  2. Eclipse-jee-ganymede(Eclipse Platform Version: 3.4.2) : Java IDE Tool
  3. JBOSS AS 5.0.1GA : JAVA EE5 Application Server

在 Eclipse 建立 EJB 3.0 Service Project

 在 Eclipse 功能表裡的 File 中選擇 New ,Project,EJB,選擇 EJB Project,

image

點選Next,輸入 Project Name,Target RunTime 請選擇 JBoss 5.0 Runtime,EJB Model version 請選擇 3.0,Configuration 請選擇 Default Configuaration for JBoss 5.0 Runtime.

image

其餘設定使用預設值即可,點選 Finish 即完成 EJB 3.0 Project 的建立.

 

在 EJB 3.0 Service Project 中建立 Session Bean

1.在 EJBSservice Project 中選取 New > Other >  EJB3 Session Bean,點選 Next 鍵

image

2. Session Bean Type 我們選擇 Stateless ,Package 輸入 com.starbooks.model ,Bean Name 輸入 IDChecker ,工具會自動幫我們建立 Bean Class Name 為 IDCheckerBean 而 Remote Interface Name 為 IDChecker,點選 Finish 即完成. image 

3.在 EJBSservice Project 中選取 Run As > Run As Server  ,選擇執行的 Server ,點選 Finish 即可完成部署啟動.

image

image 

4.當 Consol 顯示如下Log即完成於 JBoss Server 的部署及啟動

image

 

在 Eclipse 建立 EJB 3.0 App Client Project

 在 Eclipse 功能表裡的 File 中選擇 New ,Project,Java EE,選擇 Application Client Project,

image

點選Next,輸入 Project Name,Target RunTime 請選擇 JBoss 5.0 Runtime,EJB Model version 請選擇 3.0,Configuration 請選擇 Default Configuaration for JBoss 5.0 Runtime.點選 Next

image 

Source Folder 選擇預設值即可.

image

 

在 EJB 3.0 App Client Project 中建立 Session Bean Client Class

1.將 EJBAppClient Project 與 EJBService Project 能建立關聯,在 EJBAppClient Project 的節點下點選右鍵,選取 Properties ,選擇 Java Bulid Path ,將 EJBService Project 加入即可.

image 

2.在 EJBAppClient Project中選取 New > Class ,Package 輸入 com.starbooks.client ,Name 輸入 IDCheckerClient,點選 Finish 即完成. 

image

程式碼如下: 

image

3.建立 jndi.properties 檔於 EJBAppClient Project 內,內容如下:

image

image

4. 在 IDCheckerClient 節點上選取 Run As > Java Application 結果將會如下:

image

Client Console Log 如下:

image

Server Console Log 如下:

12:08:10,689 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
12:08:10,689 WARN  [InterceptorsFactory] EJBTHREE-1246: Do not use InterceptorsFactory with a ManagedObjectAdvisor, InterceptorRegistry should be used via the bean container
12:08:10,689 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean com.starbooks.model.IDCheckerBean.check(java.lang.String)
12:08:10,709 WARN  [InterceptorRegistry] applicable interceptors is non-existent for public boolean com.starbooks.model.IDCheckerBean.check(java.lang.String)

即為成功完成第一個Sample.由此可知,EJB3.0的開發與以往EJB的開發方便不少,這對 Java EE 的開發人員則是一大幫助.

張貼在 未分類 | 1 則迴響

EJB 3.0

Enterprise JavaBeans 3.0

Enterprise JavaBeans (EJB) technology is the server-side component architecture for Java Platform, Enterprise Edition (Java EE). EJB technology enables rapid and simplified development of distributed, transactional, secure and portable applications based on Java technology.

以上的說明可知EJB主要是提供一個基於JAVA技術上可 迅速 (rapid)及簡單 (simplified) 方式用以開發 distributed, transactional, secure and portable 的應用程式,但這項目標在 EJB3.0 以前一直是一個笑話! 也因此在民間燃起了一股 Open Source Framework 的風潮.如 Struts,Hibernate,Spring,Axis.. ,如新EJB3.0改變了,讓我們來看看她有什麼改進.

What’s New in EJB 3.0

  • Using Annotations Instead of DeploymentDescriptors

        EJB 3.0 uses metadata annotations as an alternative to deployment descriptors.

            image

         plain old Java objects (POJOs) 

  • Callback Methods and Listener Classes

在EJB 2.1 時我們需實做 interface javax.ejb.SessionBean or javax.ejb.EntityBean. Methods名稱像 ejbCreate(), ejbPassivate(), and ejbActivate(), 雖然有時我們並不用到, 但EJB3.0並不需要.

在EJB3.0我們並不需要 implement 用不的 callback methods 及可以指名自訂的 method 為 callback method 來作為 SessionBean or MessageDrivenBean (MDB)的 lifecycle 中使用. 也就是說 Callback methods can be indicated using callback annotations.

Life-Cycle Callback Methods
Methods in the bean class may be declared as a life-cycle callback method by annotating the
method with the following annotations:

■ javax.annotation.PostConstruct
■ javax.annotation.PreDestroy
■ javax.ejb.PostActivate
■ javax.ejb.PrePassivate

Life-cycle callback methods must return void and have no parameters.

@PostConstruct methods are invoked by the container on newly constructed bean instances after all dependency injection has completed and before the first business method is invoked on the enterprise bean.

@PreDestroy methods are invoked after any method annotated @Remove has completed, and before the container removes the enterprise bean instance.

@PostActivate methods are invoked by the container after the container moves the bean from secondary storage to active status.

@PrePassivate methods are invoked by the container before the container passivates the enterprise bean, meaning the container temporarily removes the bean from the environment and saves it to secondary storage.


詳見:JavaTM Platform Enterprise Edition, v 5.0 API Specifications
annotation @CallbackListener 最後並無納入EJB3.0

  • Interceptors

 EJB 3.0 allows developers to write the custom interceptor methods that are called before and after the bean method.

@Interceptors(ActionBazaarLogger.class)
@Stateless
public class PlaceBidBean implements PlaceBid {
public void addBid (…
public void addTimeDelayedBid (…
}

@Interceptors({ActionBazaarLogger.class, BidStatisticsTracker.class})
public class PlaceBidBean { … }

  • Dependency Injection

 image

  • EntityBeans Made Easy

To create an EntityBean, a developer only needs to code a bean class and annotate it with appropriate metadata annotations. The bean class is a POJO.

@Entity
public class TestEntityBean{
    private String userId;
    private String name;

    @id(generate=AUTO)
    public String getUserId(){
        return this.userId;
    }
    public void setUserId(String userId){
        this.userId = userId;
    }
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }
}

  • Security Annotations

EJB 3.0 provides annotations to specify security options. The following are the security-related annotations defined in EJB 3.0:

@SecurityRoles
@MethodPermissions
@Unchecked
@Exclude
@RunAs

 

EJB 3.0 Types

EJB 將 beans 依使用方式分為三種 :

  • Session beans
  • Message-driven beans
  • Entities

session beans and message-driven beans (MDBs)使用在建立 business logic 物件,並且他們存在於 container 中受其管理.而 Entities 是為 application 提供在 Java Persistence API (JPA)規格下 persistence 用.

image

Overall organization of the EJB 3 API. The Java persistence API is completely separable from the EJB 3 container. The business logic processing is carried out by through two component types: session beans and message-driven beans. Both components are managed by the container. Persistence objects are called entities, which are managed by the persistent provider through the EntityManager interface.

張貼在 未分類 | 發表留言