進行資料庫測試,卻又不把資料寫入資料庫的方法就是使用 Transaction 交易機置,
在進行Unit測試時,開始一個 Transaction 並將之後Unit測試的資料庫操作都在 Transaction 中進行
,等到測試完畢再將 Transaction 給 rollback,如此一來即不會在資料庫中留下測試資料。
Spring提供了一個AbstractTransactionalSpringContextTests測試類別,該類別已經實作了
JUnit 的 TestCase,所以直接繼承他就可以開始寫測試程式,另外必須 override 他的:
//提供 spring bean 設定檔的位置
protected String[] getConfigLocations()
// 取代原本的 SetUp
protected void onSetUpInTransaction() throws Exception
// 取代原本的 TearDown
protected void onTearDownInTransaction() throws Exception
除此之外,由於AbstractTransactionalSpringContextTests會使用宣告式的交易,也就是說,
在 spring bean 設定檔裡必須提供一個bean
id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
並注入 SessionFactory (如:org.springframework.orm.hibernate3.LocalSessionFactoryBean)
property name="sessionFactory"
2008年11月26日 星期三
2008年11月23日 星期日
svn 使用merge 進行undo
假設當前 repository 版本為 50
假設之前 commit 了一個錯誤的資料進 repository ,版本為 48。
而現在才發現錯誤想進行 undo
意思就是 47->48 之間的 diff 是我不想要的部分
如果說47->48的diff是新增xxx反過來說 48->47的diff就是刪除xxx
因此,目前的workcopy就是要去merge 48->47的diff,就可以達到 undo的效果
svn merge -r 48:47 workcopy/
目前只是undo了workcopy還要進行commit
svn ci workcopy/ -m "undo"
假設之前 commit 了一個錯誤的資料進 repository ,版本為 48。
而現在才發現錯誤想進行 undo
意思就是 47->48 之間的 diff 是我不想要的部分
如果說47->48的diff是新增xxx反過來說 48->47的diff就是刪除xxx
因此,目前的workcopy就是要去merge 48->47的diff,就可以達到 undo的效果
svn merge -r 48:47 workcopy/
目前只是undo了workcopy還要進行commit
svn ci workcopy/ -m "undo"
2008年11月12日 星期三
vbox guest 與 host 分享資料夾
安裝完guest電腦後,啟動guest電腦。
選擇 "裝置" > "安裝客端額外功能"
vbox 會要求從網路下載 VBoxGuestAdditions_1.6.6.iso 檔案,
並存放在 ~/.VirtualBox 下。
下載完成後將此 iso 檔掛載到 guest 電腦的光碟機上,並 mount 到 /media/cdrom0。
在 cdrom0 中找到 VBoxLinuxAdditions.run 這一個 script
先確定guest電腦有安裝好 gcc 套件,再執行 VBoxLinuxAdditions.run。
安裝完成 VBoxLinuxAdditions.run 後先關閉 guest 電腦。
在 vbox 設定值 > 分享資料夾 右上角加入新的分享資料夾,例:
資料夾路徑:/home/muchu1983/vboxsf
名稱:vboxsf
重新啟動guest 電腦。
在guest電腦建立~/vboxsf 目錄,例:mkdir /home/vbox/vboxsf
編輯guest電腦的/etc/fstab,加上一行:
vboxsf /home/vbox/vboxsf vboxsf uid=vbox,rw,auto 0 0
重新開機或執行mount -a,如此,guest和host電腦就可以
透過各自的~/vboxsf 共享資料夾分享資料。
選擇 "裝置" > "安裝客端額外功能"
vbox 會要求從網路下載 VBoxGuestAdditions_1.6.6.iso 檔案,
並存放在 ~/.VirtualBox 下。
下載完成後將此 iso 檔掛載到 guest 電腦的光碟機上,並 mount 到 /media/cdrom0。
在 cdrom0 中找到 VBoxLinuxAdditions.run 這一個 script
先確定guest電腦有安裝好 gcc 套件,再執行 VBoxLinuxAdditions.run。
安裝完成 VBoxLinuxAdditions.run 後先關閉 guest 電腦。
在 vbox 設定值 > 分享資料夾 右上角加入新的分享資料夾,例:
資料夾路徑:/home/muchu1983/vboxsf
名稱:vboxsf
重新啟動guest 電腦。
在guest電腦建立~/vboxsf 目錄,例:mkdir /home/vbox/vboxsf
編輯guest電腦的/etc/fstab,加上一行:
vboxsf /home/vbox/vboxsf vboxsf uid=vbox,rw,auto 0 0
重新開機或執行mount -a,如此,guest和host電腦就可以
透過各自的~/vboxsf 共享資料夾分享資料。
2008年11月11日 星期二
bash下輸出命令到serial/parallel port
serial port
echo -e "\x9e123" > /etc/ttyS0
parallel port
echo -e "\x9e123" > /etc/lp0
-e 是 enable backslash escape 也就是 "\"
而字串中的 "\x" 是指16進位。
java 對 serial/parallel 支援的 api 為
RXTX:
RXTXcomm.jar 及一些 native lib
http://www.rxtx.org/
JCA:
http://java.sun.com/products/javacomm/index.jsp
echo -e "\x9e123" > /etc/ttyS0
parallel port
echo -e "\x9e123" > /etc/lp0
-e 是 enable backslash escape 也就是 "\"
而字串中的 "\x" 是指16進位。
java 對 serial/parallel 支援的 api 為
RXTX:
RXTXcomm.jar 及一些 native lib
http://www.rxtx.org/
JCA:
http://java.sun.com/products/javacomm/index.jsp
2008年11月6日 星期四
2008年11月5日 星期三
Debian backports
參考:http://wiki.debian.org/Backports
Debian下分為 stable testing unstable 三個主要版本,stable 最穩定但套件也最老舊。
backports 是一個Debian套件更新站,上面放著只有testing和unstable的套件,
但經由stable的環境重新compile而成。所以可以在stable環境中正常執行,
透過使用 backports 可以讓 stable 版本的 Debian 用到 testing 和 unstable 下才有的套件。
必須先安裝:debian-backports-keyring 套件,用來通過 backports 上的驗証。
在 /etc/apt/sources.list 加上
deb http://www.backports.org/debian/ etch-backports main contrib non-free
開啟aptitude並update即可安裝backports上的套件
aptitude -t etch-backports install "package"
Debian下分為 stable testing unstable 三個主要版本,stable 最穩定但套件也最老舊。
backports 是一個Debian套件更新站,上面放著只有testing和unstable的套件,
但經由stable的環境重新compile而成。所以可以在stable環境中正常執行,
透過使用 backports 可以讓 stable 版本的 Debian 用到 testing 和 unstable 下才有的套件。
必須先安裝:debian-backports-keyring 套件,用來通過 backports 上的驗証。
在 /etc/apt/sources.list 加上
deb http://www.backports.org/debian/ etch-backports main contrib non-free
開啟aptitude並update即可安裝backports上的套件
aptitude -t etch-backports install "package"
Linux 下的 VirtualBox bridge 模式
安裝 VirtualBox:
先設定好backports
安裝 virtualbox-ose、virtualbox-ose-source 兩個套件
編譯並載入vboxdrv模組:
# cd /usr/src
# tar xvjf virtualbox-ose.tar.bz2
# cd modules/virtualbox-ose
# make
# make install
# modprobe vboxdrv
# lsmod | grep vbox
vboxdrv 55344 0
VirtualBox 有兩種模式 NAT 以及 Bridge 。
Bridge 設定方式如下。
停止eth0
#ifconfig eth0 down
修改/etc/network/interfaces檔案,註解掉eth0相關設定。
並加上br0設定。
# allow-hotplug eth0
# iface eth0 inet dhcp
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_fd 2.5
要先安裝 bridge-utils uml-utilities 兩個套件
sudo apt-get install bridge-utils uml-utilities
設定方式
tunctl -t tap0 -u
brctl addbr br0
ifconfig eth0 0.0.0.0 promisc
brctl addif br0 eth0
dhclient br0
brctl addif br0 tap0
ifconfig tap0 up
chmod 666 /dev/net/tun
上面可以寫成shell script 存檔,記得用 root 身份執行這些指令,
完成後 ifconfig 會多 br0 , tap0 。
而在 VirtualBox 網路設定為 “Host Interface” 而 Interface Name 為 tap0。
而 guest os 就可以互連 host os 。
若要關掉 bridge 模式
brctl delif br0 eth0
brctl delif br0 tap0
brctl delbr br0
ifconfig tap0 down
ifconfig br0 down
ifconfig eth0 down
ifconfig eth0 up
不過 bridge 模式適合用在有線網卡,無線網卡部份還無法適用。
先設定好backports
安裝 virtualbox-ose、virtualbox-ose-source 兩個套件
編譯並載入vboxdrv模組:
# cd /usr/src
# tar xvjf virtualbox-ose.tar.bz2
# cd modules/virtualbox-ose
# make
# make install
# modprobe vboxdrv
# lsmod | grep vbox
vboxdrv 55344 0
VirtualBox 有兩種模式 NAT 以及 Bridge 。
Bridge 設定方式如下。
停止eth0
#ifconfig eth0 down
修改/etc/network/interfaces檔案,註解掉eth0相關設定。
並加上br0設定。
# allow-hotplug eth0
# iface eth0 inet dhcp
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_fd 2.5
要先安裝 bridge-utils uml-utilities 兩個套件
sudo apt-get install bridge-utils uml-utilities
設定方式
tunctl -t tap0 -u
brctl addbr br0
ifconfig eth0 0.0.0.0 promisc
brctl addif br0 eth0
dhclient br0
brctl addif br0 tap0
ifconfig tap0 up
chmod 666 /dev/net/tun
上面可以寫成shell script 存檔,記得用 root 身份執行這些指令,
完成後 ifconfig 會多 br0 , tap0 。
而在 VirtualBox 網路設定為 “Host Interface” 而 Interface Name 為 tap0。
而 guest os 就可以互連 host os 。
若要關掉 bridge 模式
brctl delif br0 eth0
brctl delif br0 tap0
brctl delbr br0
ifconfig tap0 down
ifconfig br0 down
ifconfig eth0 down
ifconfig eth0 up
不過 bridge 模式適合用在有線網卡,無線網卡部份還無法適用。
2008年10月23日 星期四
Live USB Debian 20g隨身碟筆電
製作自己的LiveUSB:
將Debian裝在隨身碟上,並將BIOS設定為USB開機
即可進入作業系統進行一般電腦操作。
下載live-helper套件並安裝:
http://packages.debian.org/sid/live-helper/all/download
dpkg -i live_helper_1.0~a31-1_all.deb
同時也必須安裝 live-helper 相依的 debootstrap
安裝完成後建立一工作目錄
mkdir liveusb
cd liveusb
使用lh_config設定參數,並以 lh_build 產生 image 檔 - binary.img
lh_config
-b usb-hdd
-d etch
-p xfce-desktop
--bootappend-live "local=zh_TW.UIF-8 keyb=us"
-m "http://ftp.tw.debian.org/debian"
&&
lh_build
(需要很長時間)
將usb隨身碟 umount
umount /dev/sda1
以 dd 將 binary.img 輸出到隨身碟上
dd if=binary.img of=/dev/sda bs=1M
注意要輸出到整個隨身碟(sda)而不是單一磁區(sda1)
將Debian裝在隨身碟上,並將BIOS設定為USB開機
即可進入作業系統進行一般電腦操作。
下載live-helper套件並安裝:
http://packages.debian.org/sid/live-helper/all/download
dpkg -i live_helper_1.0~a31-1_all.deb
同時也必須安裝 live-helper 相依的 debootstrap
安裝完成後建立一工作目錄
mkdir liveusb
cd liveusb
使用lh_config設定參數,並以 lh_build 產生 image 檔 - binary.img
lh_config
-b usb-hdd
-d etch
-p xfce-desktop
--bootappend-live "local=zh_TW.UIF-8 keyb=us"
-m "http://ftp.tw.debian.org/debian"
&&
lh_build
(需要很長時間)
將usb隨身碟 umount
umount /dev/sda1
以 dd 將 binary.img 輸出到隨身碟上
dd if=binary.img of=/dev/sda bs=1M
注意要輸出到整個隨身碟(sda)而不是單一磁區(sda1)
2008年10月22日 星期三
Spring i18n 設定
Spring使用MessageSource介面做為i18n資訊的存取介面,
而且ApplicationContext即實作了MessageSource介面,
只需要在bean-config.xml裡加上MessageSource的bean即可。
ApplicationContext在啟動時會自動尋找bean-config.xml裡id為messageSource的bean
並將ApplicationContext所收到的MessageSource介面的呼叫都轉到這個bean來實作,
MessageSource bean的 id 一定要稱為 messageSource
一般使用 ResourceBundleMessageSource 做為 MessageSource bean
並指定 property basename 假設 basename 為 message
則 ResourceBundleMessageSource 會尋找 classpath 下的
message_zh_TW.properties , message_en_US.properties, message_xx_XX.properties ...
做為 i18n的資料來源。
如果是webapp的環境下,想將 i18n的資料放在 WEB-INF 下 (非classpath)
則應該改用 ReloadableResourceBundleMessageSource 做為 MessageSource bean
並指定 basename 為 WEB-INF/i18n/message
如果有中文亂碼的情型,
使用 utf-8 儲存資料來源檔 (message_xx_XX.properties)
且 messageSource bean 加上 property defaultEncoding value當然是 UTF-8 即可。
而且ApplicationContext即實作了MessageSource介面,
只需要在bean-config.xml裡加上MessageSource的bean即可。
ApplicationContext在啟動時會自動尋找bean-config.xml裡id為messageSource的bean
並將ApplicationContext所收到的MessageSource介面的呼叫都轉到這個bean來實作,
MessageSource bean的 id 一定要稱為 messageSource
一般使用 ResourceBundleMessageSource 做為 MessageSource bean
並指定 property basename 假設 basename 為 message
則 ResourceBundleMessageSource 會尋找 classpath 下的
message_zh_TW.properties , message_en_US.properties, message_xx_XX.properties ...
做為 i18n的資料來源。
如果是webapp的環境下,想將 i18n的資料放在 WEB-INF 下 (非classpath)
則應該改用 ReloadableResourceBundleMessageSource 做為 MessageSource bean
並指定 basename 為 WEB-INF/i18n/message
如果有中文亂碼的情型,
使用 utf-8 儲存資料來源檔 (message_xx_XX.properties)
且 messageSource bean 加上 property defaultEncoding value當然是 UTF-8 即可。
2008年10月6日 星期一
svn dump 備份
備份:
svnadmin dump REPOS_PATH > back_file.dmp
回存:
svnadmin create NEW_REPOS
svnadmin load NEW_REPOS_PATH < back_file.dmp
svnadmin dump REPOS_PATH > back_file.dmp
回存:
svnadmin create NEW_REPOS
svnadmin load NEW_REPOS_PATH < back_file.dmp
2008年10月3日 星期五
2008年9月22日 星期一
2008年9月19日 星期五
Hibernate 自定 generator
Hibernate的generator tag 是用來定義如何Hibernate物件的主鍵
如:

使用increment可以使主鍵每次自動加一。
然而class也可以是自己設計的 java CustGenerator class
要設計一個generator class 必須 implement兩個interface:
public class GreenBookGroupGenerator implements IdentifierGenerator, Configurable
IdentifierGenerator interface 提供 的方法
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException
會在每次需要主鍵時被呼叫,obj即是要被指定id的Hibernate entity POJO
要return Serializable id回去。
Configurable interface 提供 的方法
public void configure(Type type, Properties props, Dialect dialect) throws MappingException
只會在SessionFactory建立時呼叫一次,如果generator有提供param會以 key-value pair把參數
放在Properties裡傳進來:
自從Hibernate 3.3 後複合主鍵才可以使用generator tag
如:

使用increment可以使主鍵每次自動加一。
然而class也可以是自己設計的 java CustGenerator class
要設計一個generator class 必須 implement兩個interface:
public class GreenBookGroupGenerator implements IdentifierGenerator, Configurable
IdentifierGenerator interface 提供 的方法
public Serializable generate(SessionImplementor session, Object obj) throws HibernateException
會在每次需要主鍵時被呼叫,obj即是要被指定id的Hibernate entity POJO
要return Serializable id回去。
Configurable interface 提供 的方法
public void configure(Type type, Properties props, Dialect dialect) throws MappingException
只會在SessionFactory建立時呼叫一次,如果generator有提供param會以 key-value pair把參數
放在Properties裡傳進來:
自從Hibernate 3.3 後複合主鍵才可以使用generator tag
2008年9月4日 星期四
hibernate 關連
2008年8月21日 星期四
Eclipse UML2 工具
在預設的Site Ganymede下的Models and Model Development下的UML2*
選擇 UML2 Tools 、 UML2 Tools SDK 、UML2 End-User Features 、UML2 Extender SDK四項,
安裝即可。
使用時New -> Others -> UML 2.1 Diagrams 就可以建立UseCase 等UML圖,
建立時會產生一個.uml的model xml檔案,及另一個.umlxxx的圖形render定義檔,
使用model可以產生各種的render圖,但如果多個圖共用同一個model要小心資料共用的問題。
選擇 UML2 Tools 、 UML2 Tools SDK 、UML2 End-User Features 、UML2 Extender SDK四項,
安裝即可。
使用時New -> Others -> UML 2.1 Diagrams 就可以建立UseCase 等UML圖,
建立時會產生一個.uml的model xml檔案,及另一個.umlxxx的圖形render定義檔,
使用model可以產生各種的render圖,但如果多個圖共用同一個model要小心資料共用的問題。
2008年8月20日 星期三
apache ftpserver-1.0-M2
apache ftpserver 可以加入自定的Ftplet來處理Ftp Event。
只要實作Ftplet interface 或 直接繼承DefaultFtplet。
再加入Ftplet到ftpserver,當Ftp command到來後就會自動呼叫對應的方法。
FtpServer ftpserver = new FtpServer();
ftpserver.setFtplets(getFtpletsMap());
ftpserver.start();
想使用DefaultFtplet來處理Ftp命令,可以override DefaultFtplet的onXXXStart方法。
卻找不到onListStart方法,來顯示檔案列表。
看了一下source code 發現DefaultFtplet的實作只是把beforeCommand根據,
request.getCommand()取得的命令來分支到其他方法,如下,
public FtpletResult beforeCommand(FtpSession session, FtpRequest request)
throws FtpException, IOException {
String command = request.getCommand().toUpperCase();
if ("DELE".equals(command)) {
return onDeleteStart(session, request);
} else if ("STOR".equals(command)) {
return onUploadStart(session, request);
} else if ("RETR".equals(command)) {
return onDownloadStart(session, request);
} else if ("RMD".equals(command)) {
return onRmdirStart(session, request);
} else if ("MKD".equals(command)) {
return onMkdirStart(session, request);
} else if ("APPE".equals(command)) {
return onAppendStart(session, request);
} else if ("STOU".equals(command)) {
return onUploadUniqueStart(session, request);
} else if ("RNTO".equals(command)) {
return onRenameStart(session, request);
} else {
// TODO should we call a catch all?
return null;
}
}
於是就可以自己重新override beforeCommand方法再增加LIST分支即可,
@Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException {
String command = request.getCommand().toUpperCase();
if ("LIST".equals(command)) {
return this.onListStart(session, request);
} else {
return super.beforeCommand(session, request);
}
}
只要實作Ftplet interface 或 直接繼承DefaultFtplet。
再加入Ftplet到ftpserver,當Ftp command到來後就會自動呼叫對應的方法。
FtpServer ftpserver = new FtpServer();
ftpserver.setFtplets(getFtpletsMap());
ftpserver.start();
想使用DefaultFtplet來處理Ftp命令,可以override DefaultFtplet的onXXXStart方法。
卻找不到onListStart方法,來顯示檔案列表。
看了一下source code 發現DefaultFtplet的實作只是把beforeCommand根據,
request.getCommand()取得的命令來分支到其他方法,如下,
public FtpletResult beforeCommand(FtpSession session, FtpRequest request)
throws FtpException, IOException {
String command = request.getCommand().toUpperCase();
if ("DELE".equals(command)) {
return onDeleteStart(session, request);
} else if ("STOR".equals(command)) {
return onUploadStart(session, request);
} else if ("RETR".equals(command)) {
return onDownloadStart(session, request);
} else if ("RMD".equals(command)) {
return onRmdirStart(session, request);
} else if ("MKD".equals(command)) {
return onMkdirStart(session, request);
} else if ("APPE".equals(command)) {
return onAppendStart(session, request);
} else if ("STOU".equals(command)) {
return onUploadUniqueStart(session, request);
} else if ("RNTO".equals(command)) {
return onRenameStart(session, request);
} else {
// TODO should we call a catch all?
return null;
}
}
於是就可以自己重新override beforeCommand方法再增加LIST分支即可,
@Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException {
String command = request.getCommand().toUpperCase();
if ("LIST".equals(command)) {
return this.onListStart(session, request);
} else {
return super.beforeCommand(session, request);
}
}
2008年8月11日 星期一
Spring 整合 Hibernate
classpath所需要的jar
===== postgresql ==========
pg74.216.jdbc3.jar
======= spring ===========
spring.jar
commons-logging.jar
======= hibernate =========
antlr-2.7.6.jar
asm.jar
c3p0-0.9.1.jar
cglib-2.1.3.jar
commons-collections-2.1.1.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
hibernate3.jar
jta.jar
log4j-1.2.13.jar
=======================
範例資料表DDL
CREATE TABLE tbl_user
(
id serial NOT NULL,
name character varying(20),
age integer,
CONSTRAINT tbl_user_pkey PRIMARY KEY (id)
)
使用HibernateTools產生TblUser.java POJO物件 及 TblUser.hbm.xml mapping file
建立IUserDAO介面
package idv.muchu.test.spring;
public interface IUserDAO {
public void insert(TblUser user);
public void update(TblUser user);
public void delete(TblUser user);
public TblUser find(Integer id);
}
實作IUserDAO介面(使用HibernateTemplate簡化實作)
package idv.muchu.test.spring;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class UserDAO implements IUserDAO {
private HibernateTemplate hibernateTemplate = null;
public void setSessionFactory(SessionFactory sf) {
this.hibernateTemplate = new HibernateTemplate(sf);
}
public void delete(TblUser user) {
hibernateTemplate.delete(user);
}
public TblUser find(Integer id) {
return (TblUser) hibernateTemplate.get(TblUser.class, id);
}
public void insert(TblUser user) {
hibernateTemplate.save(user);
}
public void update(TblUser user) {
hibernateTemplate.update(user);
}
}
spring bean設定檔透過DataSource設定SessionFactory物件並"注入"到UserDAO物件

Demo程式
package idv.muchu.test.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringHibernateDemo {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("dao-config.xml");
IUserDAO userDAO = (IUserDAO)context.getBean("userDAO");
TblUser user = new TblUser();
user.setAge(15);
user.setName("mars");
userDAO.insert(user); //新增
TblUser mark = userDAO.find(1); //查詢
System.out.println("mark's age:" + mark.getAge());
mark.setAge(30);
userDAO.update(mark); //修改
System.out.println("mark's age:" + mark.getAge());
userDAO.delete(mark); //刪除
}
}
===== postgresql ==========
pg74.216.jdbc3.jar
======= spring ===========
spring.jar
commons-logging.jar
======= hibernate =========
antlr-2.7.6.jar
asm.jar
c3p0-0.9.1.jar
cglib-2.1.3.jar
commons-collections-2.1.1.jar
dom4j-1.6.1.jar
ehcache-1.2.3.jar
hibernate3.jar
jta.jar
log4j-1.2.13.jar
=======================
範例資料表DDL
CREATE TABLE tbl_user
(
id serial NOT NULL,
name character varying(20),
age integer,
CONSTRAINT tbl_user_pkey PRIMARY KEY (id)
)
使用HibernateTools產生TblUser.java POJO物件 及 TblUser.hbm.xml mapping file
建立IUserDAO介面
package idv.muchu.test.spring;
public interface IUserDAO {
public void insert(TblUser user);
public void update(TblUser user);
public void delete(TblUser user);
public TblUser find(Integer id);
}
實作IUserDAO介面(使用HibernateTemplate簡化實作)
package idv.muchu.test.spring;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class UserDAO implements IUserDAO {
private HibernateTemplate hibernateTemplate = null;
public void setSessionFactory(SessionFactory sf) {
this.hibernateTemplate = new HibernateTemplate(sf);
}
public void delete(TblUser user) {
hibernateTemplate.delete(user);
}
public TblUser find(Integer id) {
return (TblUser) hibernateTemplate.get(TblUser.class, id);
}
public void insert(TblUser user) {
hibernateTemplate.save(user);
}
public void update(TblUser user) {
hibernateTemplate.update(user);
}
}
spring bean設定檔透過DataSource設定SessionFactory物件並"注入"到UserDAO物件

Demo程式
package idv.muchu.test.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringHibernateDemo {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("dao-config.xml");
IUserDAO userDAO = (IUserDAO)context.getBean("userDAO");
TblUser user = new TblUser();
user.setAge(15);
user.setName("mars");
userDAO.insert(user); //新增
TblUser mark = userDAO.find(1); //查詢
System.out.println("mark's age:" + mark.getAge());
mark.setAge(30);
userDAO.update(mark); //修改
System.out.println("mark's age:" + mark.getAge());
userDAO.delete(mark); //刪除
}
}
2008年7月26日 星期六
hibernate LazyInitializationException
hibernate 3 預設有啟動LazyInitialization
在Session.load(Class theClass,Serializable id)時
還不會將資料庫中的資料載入到物件中,一直要到物件屬性被改變時才會載入,
但修改物件時Session必須處於open狀態,否則會丟出LazyInitializationException
如果在Session關閉後才要使用物件則可以使用Hibernate.initialize(rec_obj);
來先行載入資料庫的資料到物件中
如:
Session session = HibernateUtil.getSessionFactory().openSession();
User user = (User) session.load(User.class, new Integer(1));
Hibernate.initialize(user);
session.close();
Hibernate的Session物件有兩個:
org.hibernate.Session 及 org.hibernate.classic.Session
classic版是為了相容於Hibernate 2.x的物件,已半棄用,建議新的開發要使用
org.hibernate.Session
使用Hql進行查詢時可以一次查詢多個資料表的物件,只要把資料TO物件extends/implements同一個class/interface即可,如:
Man implements Human ...
Woman implements Human ...
同時查找Man 及 Woman的資料:
Session.find("from Human ...");
透過ThreadLocal讓多個Thread各自管理自己的Session物件範例:
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}
在Session.load(Class theClass,Serializable id)時
還不會將資料庫中的資料載入到物件中,一直要到物件屬性被改變時才會載入,
但修改物件時Session必須處於open狀態,否則會丟出LazyInitializationException
如果在Session關閉後才要使用物件則可以使用Hibernate.initialize(rec_obj);
來先行載入資料庫的資料到物件中
如:
Session session = HibernateUtil.getSessionFactory().openSession();
User user = (User) session.load(User.class, new Integer(1));
Hibernate.initialize(user);
session.close();
Hibernate的Session物件有兩個:
org.hibernate.Session 及 org.hibernate.classic.Session
classic版是為了相容於Hibernate 2.x的物件,已半棄用,建議新的開發要使用
org.hibernate.Session
使用Hql進行查詢時可以一次查詢多個資料表的物件,只要把資料TO物件extends/implements同一個class/interface即可,如:
Man implements Human ...
Woman implements Human ...
同時查找Man 及 Woman的資料:
Session.find("from Human ...");
透過ThreadLocal讓多個Thread各自管理自己的Session物件範例:
public class HibernateUtil {
public static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = session.get();
if(s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = session.get();
if(s != null) {
s.close();
}
session.set(null);
}
}
2008年7月22日 星期二
debian下使用zhcon
沒有做任何設定直接執行zhcon會造成畫面錯亂當機的情型
只要在/boot/grub/menu.list檔案的最下面的kernel字串後加上vga=791再重新開機就可以了
title Debian GNU/Linux, kernel 2.6.18-4-k7
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-4-k7 root=/dev/hdd1 ro vga=791
initrd /boot/initrd.img-2.6.18-4-k7
savedefault
vga其他顯示模示代碼如下:
Screen 640x480 800x600 1024x768 1280x1024 1600x1200
Colors --------------------------- -------------------------------------------
256 | 769 771 773 775 796
32,768 | 784 787 790 793 797
65,536 | 785 788 791 794 798
16.8M | 786 789 792 795 799
只要在/boot/grub/menu.list檔案的最下面的kernel字串後加上vga=791再重新開機就可以了
title Debian GNU/Linux, kernel 2.6.18-4-k7
root (hd0,0)
kernel /boot/vmlinuz-2.6.18-4-k7 root=/dev/hdd1 ro vga=791
initrd /boot/initrd.img-2.6.18-4-k7
savedefault
vga其他顯示模示代碼如下:
Screen 640x480 800x600 1024x768 1280x1024 1600x1200
Colors --------------------------- -------------------------------------------
256 | 769 771 773 775 796
32,768 | 784 787 790 793 797
65,536 | 785 788 791 794 798
16.8M | 786 789 792 795 799
2008年7月21日 星期一
virtualbox
下載:
http://www.virtualbox.org/wiki/Downloads
安裝:
#dpkg --install virtualbox_1.6.2-31466_Debian_etch_i386.deb
加入群組:
#usermod -G vboxusers -a muchu1983
設定Host key:
檔案 -> 偏好設定 -> 輸入
複製一份.vdi硬體檔:
VBoxManage clonevdi /mnt/hdb1/debian-vbox.vdi /mnt/hdb1/debian-vbox-v2.vdi
複製完成即可再建立一台新的虛擬機來使用新的硬碟檔
虛擬機之間的網路互通:
啟用虛擬機的新網卡eth1並設定為掛附到內部網路及給定相同的network name
再分別設定各別虛擬機的eth1 ip (例:192.168.1.100 & 192.168.1.200)
#ifconfig eth1 192.168.1.100
主端分享資料夾給客端電腦:
需先安裝客端額外功能 -
#sh /media/cdrom0/VboxLinuxAdditions.run
在主端vbox程式的 設定值 -> 分享資料夾 -> 加入新的分享資料夾
啟動客端電腦,mount 分享資料夾
#mount -t vboxsf share /mnt/share
http://www.virtualbox.org/wiki/Downloads
安裝:
#dpkg --install virtualbox_1.6.2-31466_Debian_etch_i386.deb
加入群組:
#usermod -G vboxusers -a muchu1983
設定Host key:
檔案 -> 偏好設定 -> 輸入
複製一份.vdi硬體檔:
VBoxManage clonevdi /mnt/hdb1/debian-vbox.vdi /mnt/hdb1/debian-vbox-v2.vdi
複製完成即可再建立一台新的虛擬機來使用新的硬碟檔
虛擬機之間的網路互通:
啟用虛擬機的新網卡eth1並設定為掛附到內部網路及給定相同的network name
再分別設定各別虛擬機的eth1 ip (例:192.168.1.100 & 192.168.1.200)
#ifconfig eth1 192.168.1.100
主端分享資料夾給客端電腦:
需先安裝客端額外功能 -
#sh /media/cdrom0/VboxLinuxAdditions.run
在主端vbox程式的 設定值 -> 分享資料夾 -> 加入新的分享資料夾
啟動客端電腦,mount 分享資料夾
#mount -t vboxsf share /mnt/share
訂閱:
文章 (Atom)





