
2008年5月31日
var fixgeometry = function() {
/* Some orientation changes leave the scroll position at something
* that isn't 0,0. This is annoying for user experience. */
scroll(0, 0);
/* Calculate the geometry that our content area should take */
var header = $(".header:visible");
var footer = $(".footer:visible");
var content = $(".content:visible");
var viewport_height = $(window).height();
var content_height = viewport_height - header.outerHeight() - footer.outerHeight();
/* Trim margin/border/padding height */
content_height -= (content.outerHeight() - content.height());
content.height(content_height);
}; /* fixgeometry */
$(document).ready(function() {
$(window).bind("orientationchange resize pageshow", fixgeometry);
});
posted @
2013-01-28 10:59 The Matrix 閱讀(5192) |
評論 (1) |
編輯 收藏
http://java.dzone.com/articles/hibernate-tuning-queries-using?page=0,0
posted @
2012-05-14 14:28 The Matrix 閱讀(1214) |
評論 (0) |
編輯 收藏
環境:
Centos6.2(安裝在Vmware7.0中)
Magento1.6.2
Apache Httpd Server 2.2.15
MySql 5.1.61
PHP5.3.3
安裝過程:
apache http、mysql、php及相關擴展安裝:
其中apache http、Mysql、php都是利用centos的添加/刪除軟件功能進行安裝。同時使用該功能安裝"php-xml"、"php-gd"、"php-pdo"、"php-mbstring"、"php-mysql"擴展。
使用chkconfig配置httpd和mysql為系統服務。命令如下:
chkconfig httpd on
chkconfig -add mysqld
chkconfig mysqld on
使用chkconfig --list 可以查看所有的服務配置狀態
使用service httpd start、service mysqld start啟動httpd和mysqld服務。可以通過service httpd restart重啟相關服務。
此時訪問本機的http://localhost可以看到apache的歡迎界面,同時編輯index.php文件,其內容如下:
<?php
phpinfo();
?>
并將該文件置于/var/www/html目錄下,訪問http://localhost/index.php,此時應該不能看到php版本信息,僅能看到index.php的靜態文本內容。
修改/etc/httpd/conf/httpd.conf文件,修改如下:
DirectoryIndex index.html index.html.var -> DirectoryIndex index.html index.htm index.php
增加:
AddType application/x-httpd-php .php
AddDefaultCharset -> AddDefaultCharset off (解決中文亂碼問題)
增加一段VirtualHost描述,如下(在配置文件的最后):
<VirtualHost *:80>
DocumentRoot /var/www/smallfive
ServerName smallfive
ServerAlias smallfive.com *.smallfive.com
</VirtualHost>
此時訪問http://localhost/index.php,應該一切正常
設置數據庫:
使用mysqladmin -u root password 'newpassword'設置mysql數據庫的默認密碼
讓數據庫更安全:
mysql -u root -p 進入mysql
mysql> DROP DATABASE test; 刪除test數據庫
mysql> DELETE FROM mysql.user WHERE user = ''; 刪除匿名帳戶
mysql> FLUSH PRIVILEGES; 重載權限
創建magento數據庫
mysql> CR 訪問magento數據庫,確保一切正常
配置Magento:
解壓縮magento1.6.2版本至/var/www/smallfive/magento目錄
解壓命令:
EATE DATABASE magento;
mysql> GRANT ALL PRIVILEGES ON magento.* TO 'root'@'localhost' IDENTIFIED BY 'newpassword';
tar zxvf magento1.6.2.tar.gz
此時訪問http://localhost/magento,可根據magento的設置進行配置
注意如下問題:
1、確保當前用戶擁有對/var/www/smallfive/magento可讀可寫權限
2、還需安裝mcrypt庫,安裝這個庫比較繁瑣,mcrypt依賴于Libmcrypt庫和mhash庫,我們需要下載Libmcrypt庫和mhash庫安裝它們,然后再編譯Mcrypt。
在編譯之前,先做好如下準備工作:
a、安裝phpize:yum -y install php-devel
b、安裝C++腳本編譯模塊:
yum -y install gcc gcc-g++
yum -y install gcc gcc-c++
安裝mcrypt庫過程,如下:
a、下載libmcrypt和mhash庫
Libmcrypt:http://sourceforge.net/project/showfiles.php?group_id=87941&package_id=91774&release_id=487459
mhash:http://sourceforge.net/project/showfiles.php?group_id=4286&package_id=4300&release_id=645636
b、將上述兩個下載后,分別解壓,并執行如下命令編譯:
./configure
make && make install
c、下載php對應的源代碼,解壓,
進入php源代碼的 /ext/mcrypt目錄
執行phpize命令
./configure –with-php-config=/usr/bin/php-config
make && make install
d、在php.ini文件中增加如下內容:
extension=/usr/lib/php/modules/mcrypt.so
mcrypt.so文件路徑在php-config文件中可以找到
e、service httpd restart
end!
參考文章:
http://www.eexu.com/article.asp?id=1730
http://www.ruiwant.com/centos-6-0%E4%B8%8Bmagento%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E6%80%BB%E7%BB%93.html
http://zixun.www.net.cn/qita/2344.html
http://os.qudong.com/Linux/2010/0210/64441.html
posted @
2012-04-04 17:09 The Matrix 閱讀(3131) |
評論 (1) |
編輯 收藏
有時在vmware里面安裝的系統或應用有License時間的限制,可以通過修改虛擬機時間的方法來防止過期,此時需在.vmx文件中加入下面的內容:
tools.syncTime = "FALSE"time.synchronize.continue = "FALSE"time.synchronize.restore = "FALSE"time.synchronize.resume.disk = "FALSE"time.synchronize.shrink = "FALSE"rtc.startTime = 1183431600 #這是用來指定虛擬機啟動后的時間。數字是自1970年1月1日零時零分零秒以來的秒數,可以通過如下網址將某個時間轉換為該數字(Unix時間戳):http://www.onlineconversion.com/unix_time.htm
注意:同時還需在虛擬機操作系統的服務中,停用“VMware Tools Service”的服務。
在Windows Server 2003中操作系統自身也有時間同步功能,需在時間設定中停用,同時停用“Windows Timer”服務。
posted @
2012-03-02 10:51 The Matrix 閱讀(8684) |
評論 (0) |
編輯 收藏
主要參見:
http://blog.chenlb.com/2011/03/install-apache-php-wordpress-windows.html
在安裝好apache http server后,如果端口不正確,則修改"apache安裝目錄/conf/httpd.conf"文件中的如下信息:
#ServerName localhost:80 -> ServerName localhost:8060
Apache HTTP Server版本:2.2
PHP版本:5.3.8
WordPress版本:3.2.1
posted @
2011-11-27 21:28 The Matrix 閱讀(657) |
評論 (0) |
編輯 收藏
1. 打開工具Oracle SQL Plus 以dba身份登錄sys用戶
sqlplus /nolog
conn sys@url as sysdba
2. 創建用戶并指定表空間
使用客戶端工具或者Web管理控制臺創建表空間以及用戶
給用戶賦予connect、resource、dba權限
grant connect,resource,dba to username;
注意:給oracle用戶分配connect、resource角色時,此時connect 角色中有一個 UNLIMITED TABLESPACE 權限,也就是username這個用戶可以在其他表空間里隨意建表。
revoke unlimited tablespce from username; --撤銷username用戶在任意表空間建表的權限
alter user username quota 0 on users; --alter username quota 0 on Users; // 還不是很清楚具體含義???
alter user username quota unlimited on tablespacename; --賦予username用戶在tablespacename表空間任意建表的權限;
3. 使用imp工具導入dmp數據文件
imp username/password@url file=c:\db.dmp fromuser=username1 touser=username log=c:\log.txt
-------------------------------------------------------------------------------------------------------------
其它命令:
select * from dba_users; --查詢用戶
select * from dba_tables; --查詢表
select * from dba_views; --查詢視圖
select * from dba_tablespaces; --查詢表空間
oracle 10g,查詢表空間使用率
Select * from sys.DBA_TABLESPACE_USAGE_METRICS;
-------------------------------------------------------------------------------------------------------------
drop user username cascade;
ORA-01940:無法刪除當前已連接的用戶
select username, sid, serial# from v$session where username='username';
alter system kill session'sid,serial#'
posted @
2011-05-31 16:43 The Matrix 閱讀(3897) |
評論 (0) |
編輯 收藏
環境:Windows7 professional
1、下載redmine1.1.3.zip、ruby1.8.7、rubygems-1.3.7.zip、mysql 5.0
2、安裝MySQL5.0,cmd窗口下使用mysql -u root -p 登錄MySQL數據庫,執行如下語句創建redmine數據庫及用戶:
create database redmine character set utf8;
create user 'redmine'@'localhost' identified by 'my_password';
grant all privileges on redmine.* to 'redmine'@'localhost';
注:
使用MySQL5.5在后面進行初始數據時Ruby會提示連接有問題
在安裝完MySQL后,先不要進行配置,至“MySQL安裝路徑\bin”目錄下,修改MySQLInstanceConfig.exe為“以管理員成分執行此程序”,“以兼容模式運行該程序”
進行數據庫配置時,選擇字符集為utf8
3、運行ruby1.8.7安裝包,解壓至d:/ruby187,將d:/ruby187/bin添加至path環境變量中
安裝后可執行 ruby -v查看ruby版本以檢驗安裝是否正確
4、解壓rubygems-1.3.7.zip至d:/rubygems-1.3.7
進入d:/rubygems-1.3.7目錄,執行ruby setup.rb
注:Redmine需要rubygems 1.3.1 - 1.5.x,肯定不能用1.8.2版本
5、執行gem install rails -v=2.3.5 遠程安裝rails2.3.5版本
gem install mysql
gem install -v=0.4.2 i18n
6、解壓縮redmine1.1.3至d:/redmine1.1.3目錄
進入d:/redmine-1.1.3/config目錄,修改database.yml.example文件為database.yml,并修改該文件中的production數據庫連接配置為如下:
production:
adapter: mysql
database: redmine
host: localhost
username: redmine
password: my_password
encoding: utf8
進入d:/redmine1.1.3目錄,執行
rake config/initializers/session_store.rb
rake db:migrate RAILS_ENV="production"
7、加載默認配置數據
rake redmine:load_default_data RAILS_ENV="production"
默認語言選擇"zh"
8、運行
ruby script/server webrick -e production
9、訪問:http://localhost:3000
使用admin/admin進行登入
進入設置,把默認語言設為“簡體中文”,然后設置當前用戶的默認語言設為“簡體中文”,這樣就是中文界面了
-----------------------------------------
繼續,將redmine設置為windows 7的服務
1、首先需要配置mysql為windows 7的服務
2、Ruby提供一個安裝Ruby程序為服務的包:mongrel_service。安裝其實很簡單,運行:gem install mongrel_service
3、安裝redmine為服務,執行mongrel_rails service::install -N RedMine -c C:\redmine-1.1.3 -p 3000 –e production
注意:此處打開cmd窗口時,需要輸入cmd后,不是直接按Enter,而是按 Ctrl+Shift+Enter打開Cmd窗口,此時以管理員身份打開,否則安裝為服務時會提示拒絕訪問。
4、安裝服務后,需檢查服務-e后的參數是不是production,如果不是production而是development,則在注冊表中把參數手動改為production。修改方法是:打開“注冊表編輯器”,展開分支“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services”,選擇redmine服務,找到ImagePath項,修改保存后在服務列表中啟動服務,并把服務設置自動啟動。
OK!
posted @
2011-05-20 10:25 The Matrix 閱讀(2790) |
評論 (0) |
編輯 收藏
參見如下鏈接:
posted @
2011-03-25 21:33 The Matrix 閱讀(1208) |
評論 (0) |
編輯 收藏
沒仔細研究,先把項目地址記下:
http://arshaw.com/fullcalendar/
這個博客中另有幾個推薦的類似項目:
http://hi.baidu.com/freezesoul/blog/item/15c5d73fe4a315c17d1e71ec.html
posted @
2010-11-09 20:37 The Matrix 閱讀(1283) |
評論 (0) |
編輯 收藏
這幾天在看郎咸平的《誰在謀殺中國經濟》,這本書我基本看過一遍了,認為全書的重點在于中華文化的四大茫然,整本書都是圍繞這四大茫然展開論述,中華文化的四大茫然如下:
茫然之一:就知道賺錢
茫然之二:不了解世界
茫然之三:不了解別人為什么那么看你
茫然之四:不了解自己的缺點
大家有時間可以看看這本書,我覺得寫的不錯,至少我自己看完深有感觸,我覺得完全可以將這幾點套用到我們生活的很多方面,比如對于我們搞IT的技術人員來說,我認為現在很多人也存在四大茫然:
茫然之一:只知道完成任務。也許是我年齡大了點,但我覺得現在很多小朋友,尤其是85年以后出生的,工作的時候只是在完成任務,事情做完了,有時也不測試,或者就是匆匆測試,匆匆結束,并沒有好好的想為什么這件事老大要讓我這樣做,這樣做有什么好處,會不會有缺點,我是不是有更好的方法。當你不去想的時候,意味著你少了很多提高的機會。
茫然之二:不追究為什么。很多人做事情就象第一條說的那樣,只是完成任務,并不去想其中的原理是什么。面試過很多人,對于目前工作兩三年的大部分人來說(當然我面試的不是好的學校畢業的,基本學校為中等偏下點),一旦涉及到Spring、Hibernate、Struts等框架深入點東西的時候,大都回答不上來,只是對框架能熟練應用而已。這樣夠么?計算機的很多知識,當你熟悉了其運作原理,框架對于你來說,只是手到擒來,看看學學就會用了。我問過好幾個同事,平時晚上回去都干嘛,很多人都回答我晚上回去看看電視,稍微看看書就睡覺了。我有點驚訝,我想如果你想成為一個技術高手,一個能拿高薪的程序員,你又沒有天份,又不付出超過常人的努力,憑什么你比別人強呢?
茫然之三:不善于總結。很多人(又是很多人)過著做一天和尚撞一天鐘的日子,日子一天一天過去,基本不去總結,只是過了好長一段時間會發覺,原來最近我啥也沒有進步,啥也沒學到,還是老樣子。知識在于積累,你只有不斷總結,知識才能更好的積累,才能更好的為你服務。
茫然之四:沒有明確的目標。一個人沒有目標就決定了他不會有長足的進步。你都沒有想過自己要成為一個架構師,一個項目經理,一個部門經理,一個技術總監,都沒有想過要成為這樣的人需要具備什么樣的條件,你怎么可能知道自己欠缺什么?需要補充什么呢?長遠目標要明確,然后根據長遠目標進行分析,我要達到這樣的目標,還有什么欠缺,據此制定短期目標,短期目標一定要可實現可操作。這樣隨著你目標的一步一步實現,你各方面的能力也隨之提高了。
寫了幾點,也作為對自己的鞭策。
posted @
2010-04-14 22:05 The Matrix 閱讀(6163) |
評論 (10) |
編輯 收藏
2010年已經過去一個月了,趕在農歷春節前列一下今年的讀書清單,不能總把精力放在工作中了,也需要補充點新知識了,否則沒有新東西能貢獻出來了。
1、《OSGI原理與最佳實踐》,結合這本書并研究SpringDM,做一些實例。
2、《SQL語言藝術》
3、《Oracle9i&10g編程藝術》
4、《架構之美》
5、《UML和模式應用》
6、《UML彩色建模》
7、《領域驅動設計與模式實戰》
8、《敏捷軟件開發 原則、模式與實踐》
9、《軟件開發的邊界》
10、《軟件隨想錄》
11、《走出軟件作坊》
就這么多了,9、10、11去年都看過一遍了,但好多地方粗粗過了一下,還要仔細閱讀。
另外也對自己提個要求,看書要做讀書筆記。
2010年-我的讀書年!
posted @
2010-02-03 23:27 The Matrix 閱讀(2770) |
評論 (6) |
編輯 收藏
摘自《軟件隨想錄》
看了軟件隨想錄中下面一段話,覺得非常棒,作為一名軟件從業人員,不一定有機會能實現描述中的優秀軟件產品,但這樣的理念需要貫穿我們每個人的心田,時刻記在心中:
【創造一個有使用價值的軟件,你必須時時刻刻都在奮斗,每一次的修補,每一個功能,每一處小小的改進,你都在奮斗,目的只是為了再多創造一點空間,可以再多吸引一個用戶加入。沒有捷徑可走。你需要一點運氣,但是這不取決于你是否幸運。你之所以會有好運氣,那是因為你寸土必爭。
每天你前進一小步,將一件東西做得比昨天好一點點。這樣的改進幾乎看不出可以讓誰獲益,幾乎沒有變化。但是,你前進了一小步。
有無數個要做的這樣微小的改進。
為了發現可以改進的地方。你必須有一個思維定勢,始終如一的用批判的眼光看世界。隨便找一樣東西,如果你看不出它的缺點,那么你的思維轉型還沒有成功。當你成功的時候,你身邊親密的人會被你逼得發瘋。你的家人恨不得殺了你。當你步行上班的時候,看到一個司機漫不經心地開車,你幾乎用了所有的意志力才勉強忍不住沖上去告訴那個司機,他這樣開車差點兒要了旁邊坐在輪椅上的那個可憐小孩的命。
當你改正了一個又一個這樣的小細節后,當你磨光、定型、擦亮、修飾你的產品的每一個小邊角后,就會有神奇的事情發生。厘米變成分米,分米變成米,米變成了千米。你最后拿出來的是一件真正優秀的產品。它第一眼就讓人覺得震撼,出類拔萃,工作起來完全符合直覺。就算100萬個用戶中有一個用戶某天突然要用到一個他100萬次使用中才會用到一次的罕見功能,他發現了這個功能不僅能用,而且還很沒:在你的軟件中,即使是看門人的小屋都鋪著大理石的地板,配有實心的橡木門和桃花心木的壁板。
就是在這個時候,你意識到這是一個優秀軟件。】
posted @
2010-01-05 21:25 The Matrix 閱讀(2298) |
評論 (11) |
編輯 收藏
http://www.insideria.com/2009/05/flex-4-custom-layouts.html
http://www.insideria.com/2009/10/easy-flex-skinning-with-firewo.html
posted @
2009-11-25 12:25 The Matrix 閱讀(592) |
評論 (0) |
編輯 收藏
在Flash Builder 4 Beta 2版本中,使用mxml方式實現state的切換有了很大改進,使用起來更方便,具體可參見下文:
http://onflex.org/learn/fx4/index.php?page=States
看完這篇文章后,想到一個問題,如何用編程的方式實現切換呢,找了參考資料,實現了一個例子,代碼如下:
開發環境:Flash Builder 4 Beta2
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.states.SetProperty;
import mx.states.State;
import spark.components.Label;
import spark.components.Panel;
private var stateArray : Array;
private var state1 : State;
private var state2 : State;
protected function creationCompleteHandler(event:FlexEvent):void
{
state1 = new State();
state1.name="state1";
state2 = new State();
state2.name="state2";
var stateArray1:Array = new Array();
var stateArray2:Array = new Array();
state1.overrides = stateArray1;
state2.overrides = stateArray2;
stateArray = new Array();
stateArray.push(state1);
stateArray.push(state2);
this.states = stateArray;
var panel:Panel = new Panel();
group.addElement(panel);
var label:Label = new Label();
panel.addElement(label);
buildStates(stateArray1, stateArray2, panel, label);
this.currentState = "state1";
}
private function buildStates(stateArray1:Array, stateArray2:Array,
compenent1:UIComponent, compenent2:UIComponent) : void{
stateArray1.push(makeSetProp(compenent1, "title", "Panel1"));
stateArray1.push(makeSetProp(compenent2, "text", "One"));
stateArray2.push(makeSetProp(compenent1, "title", "Panel2"));
stateArray2.push(makeSetProp(compenent2, "text", "Two"));
}
private function makeSetProp(target:UIComponent, name:String, value:*):SetProperty{
var sp:SetProperty = new SetProperty();
sp.target = target;
sp.name = name;
sp.value = value;
return sp;
}
]]>
</fx:Script>
<s:VGroup autoLayout="true" horizontalAlign="center">
<s:HGroup horizontalCenter="0">
<s:Button label="One"
click="this.currentState='state1'"/>
<s:Button label="Two"
click="this.currentState='state2'"/>
</s:HGroup>
<s:HGroup id="group" horizontalCenter="0">
</s:HGroup>
</s:VGroup>
</s:Application>
posted @
2009-11-11 21:59 The Matrix 閱讀(1629) |
評論 (0) |
編輯 收藏
這是前幾天在別人的BLog上看到的一幅圖,覺得不錯,基本涵蓋了IT人員需要掌握的基礎知識這塊,從這幅圖中可以看出語言并不重要,關鍵是要搞明白整個環節,這樣遇到任何問題就能有目的、有方法的學習了。

posted @
2009-10-22 08:32 The Matrix 閱讀(968) |
評論 (0) |
編輯 收藏
1、下載Ruby并安裝,下載地址:http://rubyforge.org/frs/?group_id=167
下載了1.8.6-27 Release Candidate 2(ruby186-27_rc2.exe)版本
2、在windows的命令行下,輸入 ruby –v,檢查ruby是否正確安裝,應該出現如下信息:
ruby 1.8.6 (2008-08-11 patchlevel 287) [i386-mswin32]
3、安裝rails,執行gem install rails命令,安裝成功后,執行rails -v檢查。
我安裝了Rails2.3.2版本。使用gem install -version rails可以指定安裝的rails版本,具體如何使用gem,可以用gem help install查看幫助。
參考:Ruby On Rails(ROR)安裝(http://enjoylog.cn/?p=8)
裝好了便到Ruby On Rails的官方網站(http://rubyonrails.org/),找到了
Getting Started with Rails(http://guides.rubyonrails.org/getting_started.html)
開始一步一步follow up。
RubyOnRails的中文站上的翻譯文檔沒有完全跟進,還是看英文的吧。
我使用的是MySQL的數據庫,操作系統:Vista。
到創建POSTS應用的時候遇到了問題,創建數據后數據庫中有數據,但是到Listing posts界面無法查看,總是報錯。
網上Google了一下,果然有人遇到相同的問題,參照了如下解決方案,到
http://instantrails.rubyforge.org/svn/trunk/InstantRails-win/InstantRails/mysql/bin/ 上下載了libmySQL.dll文件放到RUBY_HOME/bin/目錄下,問題解決。
參考:升級2.2后mysql驅動的問題(http://www.javaeye.com/topic/283871?page=1)
感嘆一下,當Listing Posts這個CRUD小應用跑起來后,覺得Ruby On Rails的開發是比Java開發要快一些,看了一下它生成的代碼,貌似也不多。
今天晚了,明天繼續。
posted @
2009-07-19 00:42 The Matrix 閱讀(1799) |
評論 (0) |
編輯 收藏
最近在做一個很小的項目的功能改進,小小的項目中原來連接的是MySQL數據庫,現在需要新連接一個數據庫(Oracle),僅僅從一張表查詢數據即可,沒有添加、修改、刪除等等功能。本來這個小小的項目中用的是Hibernate,現在又要增加一個數據庫連接,覺得配置起來有點麻煩,忽然想起來,我干嗎還要用Hibernate呢,直接用JDBC不也挺好使么,想了便做,果然寫起JDBC來,很是快捷,一會就搞好了。
做好了以后,忽然覺得有點迷茫,感覺不用Hibernate不也挺好的么,咱為什么現在開口閉口都是Hibernate呢,于是便有了今天的題目。
很久以前沒有Hibernate的時候:
第一階段:我們寫程序都是直接用JDBC,甚至在JSP頁面中直接去createConnection,然后執行查詢,輸出到頁面。
第二階段:后來覺得每次都是創建一個連接,好像效率不高,于是看了別人的介紹,要用數據庫連接池,好的,那便用數據庫連接池吧,每次都從pool中獲得一個Connection,然后查詢數據。
第三階段:用了連接池,還是效率不高,那怎么辦呢?用緩存吧,自己實現緩存?可以,也可以用開源的緩存框架。
第四階段:到了OO大流行的時代了,一切都要OO,恰逢Hibernate降臨人世,于是一切都用Hibernate來實現了,其實同期還是有不少其它ORMAP框架的,比如(TOPLINK、JDO、IBatis等,IBatis國內用的還比較多,另外兩個好像用的比較少)。
第五階段:忽然EJB大流行,事務的概念被廣為傳播(并不是原來沒有事務的概念,只是實現起來比較麻煩),借助EJB的廣為傳播,Spring+Hibernate的組合也慢慢占據了大半市場。此時事務用Spring AOP的聲明式事務來解決,緩存可以用開源的緩存框架(已經和Hibernate無縫集成了),數據庫連接池也是通過配置的方式在SpringContext.xml文件中配置,貌似一切都很完美。
真的到了第五階段,一切是不是真的完美了呢,如果一個很小的應用,需要從好幾個數據庫查詢數據,但是每個數據庫僅需要查詢那么一兩張表的數據,偶爾添加、刪除幾條數據,數據量也不大,此時我們是不是還用第一階段的方式會更好呢,好像有時配置多數據源也不是那么方便的事情。或者使用Spring中的JDBCTemplate,貌似也不錯。
再往后看,難道Spring+Hibernate的組合就天下無敵了么?難道就沒有新的框架了么?前段時間,JavaEye上關于充血模型、貧血模型的討論吸引了多少眼球,以后是不是會有這么一個框架用于實現充血模型呢?
說了這么多,最終只是想說明白這么一句:用恰當的技術做恰當的事情,這真是一個艱難的選擇……,至于未來,更是迷茫,因為我們只是跟隨者,而不是領導者。
posted @
2009-07-06 22:06 The Matrix|
編輯 收藏
前兩天出差在外,利用空余時間將《深入淺出EXT JS》這本書的前五章翻了一遍,后面的章節粗粗瀏覽了一下,覺得這本書寫的不錯,寫下自己的一點感悟:
1、適合的讀者
a、是一名Java開發程序員,做過WEB開發
b、對Ajax開發的基礎知識有所了解
2、書評:
這本書我覺得應該改成這個名字:《EXT JS CookBook》,可能使得書的內容和名稱更貼切,呵呵。
書中對Ext JS的基礎類、Grid、Form、Tree、布局管理器、數據獲取等各方面都做了詳細的描述,基本上開發中需要用到的知識點,在書中都會提到,而且書中的很多例子和實際工作還是非常貼切的,對于工作中需要用到EXT JS或者需要學習EXT JS的程序員來說還是會很有幫助的。
最后提點缺點,這本書中對EXT JS的知識點都做了比較詳細的描述,但是缺乏對EXT JS的框架的深入分析。
posted @
2009-04-19 13:36 The Matrix 閱讀(2403) |
評論 (2) |
編輯 收藏
前兩天在InfoQ上看到一篇文章:利用Clear Toolkit連接Flex與Java開發,今天下載了說明文檔粗略了翻了一遍,Clear Toolkit包含五個部分,分別是:
- Clear Data Builder,這是個Eclipse插件,可以根據SQL語句或Java數據傳輸對象為BlazeDS或LCDS自動生成CRUD應用。
- DTO2Fx,該插件會根據Java類型自動生成對應的ActionScript類。
- Log4Fx是個構建于Flex logging API之上的Eclipse插件,它會自動化日志處理并且更加靈活,也更加友好。
- Fx2Ant插件會為Flex Builder項目生成優化的Ant構建腳本。
- clear.swc是個增強的Flex組件庫。
暫時用不到這個工具,記錄留待備查。
posted @
2009-04-12 20:57 The Matrix 閱讀(673) |
評論 (0) |
編輯 收藏
這篇Blog是原來寫在別的地方的,今天將其轉到BlogJava上來。
-------------------------------------------------------------------------------
今天仔仔細細的看了一下Hibernate的緩存,并做了實例實踐了一把。google一下,網上的教程、文章很多。
自己小結一下:
Hibernate的緩存分為:
- 一級緩存:在Session級別的,在Session關閉的時候,一級緩存就失效了。
- 二級緩存:在SessionFactory級別的,它可以使用不同的緩存實現,如EhCache、JBossCache、OsCache等。
緩存的注釋寫法如下,加在Entity的java類上:
- @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
緩存的方式有四種,分別為:
- CacheConcurrencyStrategy.NONE
- CacheConcurrencyStrategy.READ_ONLY,只讀模式,在此模式下,如果對數據進行更新操作,會有異常;
- CacheConcurrencyStrategy.READ_WRITE,讀寫模式在更新緩存的時候會把緩存里面的數據換成一個鎖,其它事務如果去取相應的緩存數據,發現被鎖了,直接就去數據庫查詢;
- CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,不嚴格的讀寫模式則不會的緩存數據加鎖;
- CacheConcurrencyStrategy.TRANSACTIONAL,事務模式指緩存支持事務,當事務回滾時,緩存也能回滾,只支持JTA環境。
另外還有如下注意事項:
1、查詢緩存需要在Query的相應方法執行前加上這么一句:
query.setCacheable(true);
在使用Hibernate時,獲得的query有setCacheable方法,可以設置使用緩存,但當使用JPA時,javax.persistence.Query并沒有setCacheable方法,此時如果JPA的實現是Hibernate時,可以將其進行如下轉化,再調用setCacheable方法(如果JPA的實現是其它ORMAP框架,就不知道怎么做了)。
if (query instanceof org.hibernate.ejb.QueryImpl) {
((org.hibernate.ejb.QueryImpl) query).getHibernateQuery().setCacheable(true);
}
2、還有就是查詢緩存的查詢執行后,會將查詢結果放入二級緩存中,但是放入的形式是以ID為Key,實例作為一個Value。
3、hibernate的配置文件中需加入如下信息:
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />
posted @
2009-04-07 22:54 The Matrix 閱讀(10137) |
評論 (3) |
編輯 收藏
摘要: 前段時間對Spring的事務配置做了比較深入的研究,在此之間對Spring的事務配置雖說也配置過,但是一直沒有一個清楚的認識。通過這次的學習發覺Spring的事務配置只要把思路理清,還是比較好掌握的。
總結如下:
Spring配置文件中關于事務配置總是由三個組成部分,分別是Data...
閱讀全文
posted @
2009-04-05 16:38 The Matrix 閱讀(332572) |
評論 (85) |
編輯 收藏
今天在Javaeye的新聞頻道看到一個界面原型繪制工具,叫做“wireframesketcher”,下載試了試,感覺有如下幾個好處:
1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用
2、集成在eclipse中,對于開發人員來說用起來更直接
3、其界面原型文件為xml格式,可以使用比較工具比較
唯一的缺點:
不是免費開源的工具,但是現在可以申請免費的license
隨便畫了一個圖,如下:
感興趣的兄弟姐妹們可以到如下地址看看:
http://wireframesketcher.com/index.html
posted @
2009-03-28 21:55 The Matrix 閱讀(4605) |
評論 (1) |
編輯 收藏
由于要寫一個Spring的培訓教材,要做Spring的事務樣例,于是開始寫樣例,寫好了一測,控制臺有SQL輸出,數據庫卻查詢不到數據,查亞查亞,花了一個多小時,原來是獲取的Service不是經過代理的Service,自然事務不起作用,數據庫里就沒有數據了,鄙視一下自己。
配置文件樣例如下(已經修改了dao和service的命名,減少了寫錯的可能性,以后命名問題一定要注意):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:annotation-config />
<context:component-scan base-package="com.*" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
</bean>
<!-- 定義事務管理器(聲明式的事務) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置DAO -->
<bean id="generatorDaoTarget" class="com.*.spring.dao.GeneratorDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="generatorDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事務管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="generatorDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.GeneratorDao</value></property>
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="plantDaoTarget" class="com.*.spring.dao.PlantDaoImpl">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="plantDao"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事務管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.PlantDao</value></property>
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 配置Service -->
<bean id="plantGeneratorServiceTarget"
class="com.*.spring.service.PlantGeneratorServiceImpl">
<property name="plantDao">
<ref bean="plantDao" />
</property>
<property name="generatorDao">
<ref bean="generatorDao" />
</property>
</bean>
<bean id="plantGeneratorService"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 配置事務管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantGeneratorServiceTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.service.PlantGeneratorService</value></property>
<!-- 配置事務屬性 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 各屬性的配置-->
<!-- 為true表示將Hibernate發送給數據庫的sql顯示出來 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- SQL方言,這邊設定的是MySQL -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--連接數據庫的Driver-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!--數據庫連接url-->
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<!--用戶名-->
<property name="connection.username">root</property>
<!--密碼-->
<property name="connection.password">123456</property>
<!-- 映射文件 -->
<mapping class="com.*.spring.domain.Generator" />
<mapping class="com.*.spring.domain.Plant" />
</session-factory>
</hibernate-configuration>
public interface GeneratorDao {
/**
* 獲取所有機組數據
* @return
*/
public List<Generator> listGenerators();
/**
* 保存機組數據
* @param generator 機組數據
*/
public void save(Generator generator);
}
public class GeneratorDaoImpl extends HibernateDaoSupport implements GeneratorDao {
@SuppressWarnings("unchecked")
public List<Generator> listGenerators() {
return this.getSession().createQuery("from Generator").list();
}
public void save(Generator generator) {
this.getSession().save(generator);
}
}
posted @
2009-03-16 22:24 The Matrix 閱讀(1550) |
評論 (0) |
編輯 收藏
給自己做的這個程序起了個名字叫EasyWork,代碼可以從Google Code上下載,具體地址如下:
http://easywork.googlecode.com/svn/trunk/
由于時間關系,這個程序還存在不少問題,所以只能供大家參考,有問題不要罵我就行了:)
簡要使用說明:
1、開發環境+運行環境:MyEclipse6.0,JDK1.5,Tomcat6.0.14,MySQL5.0
2、準備好上述環境后,使用下載代碼sql目錄中的easywork_init.sql腳本創建數據庫表和初始數據。
3、將項目導入Eclipse后,運行Tomcat(此過程就不詳細描述了)。
4、使用http://localhost/easywork/system/login.jsp訪問登錄頁面,目前還沒有做index.html,默認用戶名/密碼:admin/1。
存在問題如下:
1、任務管理功能還沒有完全完成,日志記錄還沒有做。
2、超時或者沒有登錄訪問頁面時,只是報不能訪問的異常,沒有轉入登錄頁面。
3、對資源類型(菜單、URL、字段、操作)的訪問限制還沒有做。
4、很多界面的輸入信息校驗沒有做。
5、基本沒有美工。
6、總而言之,目前這個項目中的代碼只能做Struts2 + ExtJS如何使用的借鑒:)
posted @
2009-03-01 11:03 The Matrix 閱讀(6285) |
評論 (28) |
編輯 收藏
很近沒有更新BLog了,這一陣子忙著學習Struts2和ExtJS,使用這兩者做了一個小程序,使用RBAC實現了基本的權限管理功能,還做了一個任務管理和日志記錄,任務管理用于記錄當前需要處理的事情,日志記錄用于記錄每天的工作情況。
用下來Struts2和ExtJS還是挺好用的。先貼幾張圖,后續再把學習過程中遇到的問題整理出來。
任務管理
添加組

添加權限
添加角色

posted @
2009-02-26 07:14 The Matrix 閱讀(4333) |
評論 (15) |
編輯 收藏
由于前段時間使用JSF做了一個項目,不少使用JSF的兄弟們對JSF評價并不好,因此在學習的過程中一直在想,JSF究竟是不是應該繼續學習繼續研究使用下去,在看完Seam In Action的第三章后,這個星期又對Struts2簡單學習了一下,終于決定結束JSF和JBoss Seam的學習了。
因為從JSF的學習和Struts2的學習對比中明顯覺得JSF復雜,對于一個技術力量不是非常強的項目組來說,使用JSF當你遇到一些問題時,絕對是一件痛苦的事情。
從自己的實踐中覺得JSF至少有兩個致命傷:
1、覺得JSF貌似把簡單的事情搞得復雜化了,在傳統的MVC框架如Struts中,從request中獲取param很容易,也可以將param封裝為對象,在JSF中,希望將這一切都模型化,一切都以組件為中心,類似于Swing的架構,但是http的無狀態以及web的本質,使得一般JSF只能將組件樹存放在服務端,同時又不能象CS程序那樣方便的查看組件的狀態、屬性等信息。對于通常情況來說,JSF將其封裝的很好,不用我們開發者操心,但是當遇到一些問題時,對于開發者想去調試查看問題時,問題就顯得很復雜了。
2、JSF的自定義組件感覺超復雜,難度應該比當年自定義JSP標簽更要高,試想一下,如果哪個組件不合意了,想改一下,還是比較困難的,除非對JSF組件有相當的深入了解。
順便把項目中遇到的一個RichFaces的缺點列出來:
RichFaces在生成組件的html時,大量使用了Div,曾經有過一個頁面有1千多行(在一個table中),頁面上還有一個RichFaces的下拉菜單,從而導致菜單響應非常之慢,后來只有將rich:datatable換為普通的html:table,就沒有問題了。
再看看Seam In Action中總結的JSF的缺點:
1、在JSF中初次請求的處理流程太過簡單,而后續請求則執行了完整的復雜的處理流程。在JSF中假設第一個調用應該是在頁面被渲染后執行,但實際中有時我們需要在第一次請求時就執行某些操作。在JSF中缺少象Struts中的Controller。
2、所有的請求都是POST。瀏覽器處理POST請求是比較草率,當用戶執行了一個JSF Action操作后,點擊瀏覽器的刷新按鈕時,瀏覽器會詢問用戶是否重新提交,這會令用戶非常困惑。
3、僅僅擁有簡單基礎的頁面導向機制。
4、過度復雜的生命周期。
JBossSeam宣稱對于JSF存在的缺點都提供了解決方法,但是有一種更復雜的感覺。
在Seam中,生成選擇的項目時,有EAR和WAR的選項,如果選擇了EAR選項,那么Seam會生成四個項目,分別為war、ear、ejb、test四個類型的項目。有一次我將生成的項目從一個目錄拷貝到另一個目錄,切換了Eclipse的workspace,此時問題來了,ejb項目提示編譯錯誤,提示無法找到某些class,找來找去找來找去......后來將項目關閉了一下,再打開錯誤提示就沒有了。
由這個問題我忽然想到,使用Seam集成JSF、EJB是不是太重量級了,如果采用EJB作為替代普通的POJO,對于一個小型的項目組來說,一般的規模就是三至五個人(我個人的理解),開發人員本來就不多,還要面對Seam劃分的四個項目,好像比較繁瑣,當然采用war模式另當別論。
相比較而言,這個星期看了一些Struts2的資料,覺得Struts2的架構非常清晰,易于理解。
翻了很早之前的JavaEye上的一個帖子,提到JSF是面向開發工具的,如果能做到象VB那樣,就大有前途了,4年過去了,不要提JSF的開發工具了,就是Java各個方面的GUI開發工具,又有哪個能和VB相比呢,看來選擇JSF作為一個方向不是一個好選擇........還是及早放棄吧,哎...
最后我覺得可以用這么一句話可以形容JSF,看起來很美,用起來不爽。
posted @
2008-12-25 23:35 The Matrix 閱讀(2329) |
評論 (6) |
編輯 收藏
這個事情去年做過一次,不過沒有留下記錄,今天又要做一次,記錄下來,呵呵
環境:
Spring版本為1.2,Tomcat為5.5.26,JDK為Jdk1.5.0_11。
1、下載Axis1.4,解壓后將其jar文件添加到web項目的lib目錄中。
2、配置Axis Servlet,在web.xml文件中加入如下信息:
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>
org.apache.axis.transport.http.AxisServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
3、編寫java類,樣例如下。
接口:
public interface InterchangeDataService {
public String getMonthInterchange(String marketDate);
}
實現類:
public class InterchangeDataServiceImpl extends ServletEndpointSupport implements InterchangeDataService {
public InterchangeDataServiceImpl() {
}
public String getMonthInterchange(String marketDate) {
return "getMonthInterchange";
}
}
注意實現類需要繼承ServletEndpointSupport類,該類是由Spring提供的。
4、配置service-config.wsdd。
<?xml version="1.0" encoding="utf-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
<service name="interchangeDataService" provider="java:RPC" style="rpc" use="literal">
<parameter name="wsdlTargetNamespace" value="urn:soap.axisspring"/>
<parameter name="className" value="com.ecgit.eccm.webservice.InterchangeDataServiceImpl"/>
<parameter name="allowedMethods" value="*"/>
</service>
<transport name="http">
<requestFlow>
<handler type="URLMapper"/>
<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
</requestFlow>
<parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
<parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
<parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
</transport>
<transport name="local">
<responseFlow>
<handler type="LocalResponder"/>
</responseFlow>
</transport>
</deployment>
5、測試web service服務,代碼如下。
至項目的WEB-INF目錄下,執行如下命令:
Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/interchangeDataService?WSDL
會在WEB-INF目錄中生成四個JAVA文件,它們分別是:
- InterchangeDataServiceImpl.java 定義了Web服務接口,接口中的方法與InterchangeDataService中的方法一致。
- InterchangeDataServiceImplService.java 定義了用于獲取Web服務接口的方法。
- InterchangeDataServiceImplServiceLocator.java 接口InterchangeDataServiceImplService的具體實現。
- InterchangeDataServiceImplSoapBindingStub.java Web服務客戶端樁,通過該類與服務器交互。
最后編寫一個Main方法,調用如下方法即可進行測試:
InterchangeDataServiceImplServiceLocator serviceLocator = new InterchangeDataServiceImplServiceLocator();
InterchangeDataServiceImpl service = serviceLocator.getinterchangeDataService();
String monthSchedule = service.getMonthInterchange("2008-05-30");
posted @
2008-12-19 17:16 The Matrix 閱讀(3417) |
評論 (1) |
編輯 收藏
上次使用Seam自動生成了一個CRUD的例子,后來想還是自己白手起家做一個例子看看,于是開始動手。
首先使用JBossTools工具生成項目,在生成項目的向導中,如果項目類型選擇ear,則會生成四個項目,分別對應war、ear、ejb、test,覺得這樣太過繁瑣,還是選擇war類型,又想要不使用tomcat作為運行服務器吧,因為JBoss也不太熟悉。沒想到這一試倒試出問題來了,如果完全使用向導生成項目,選擇tomcat作為運行服務器,則項目根本無法運行起來,總是提示缺少這個jar,那個jar。好,又換回JBoss,沒問題了。仔細看了一下,原來在自動生成項目的WebContent/WEB-INF/lib目錄中,只有大概十幾個jar,連Hibernate的jar都沒有,而在JBoss的Server/default/lib目錄下則什么jar都有,怪不得不出錯。
第一個教訓:還是先使用JBoss作為運行環境,等整個Seam都搞熟了,再配一個Tomcat的運行環境。
繼續,將原來項目中的一個通用DAO和一個UserService拷貝過來,代碼如下,啟動服務器報錯。分別為如下錯誤信息:
第二個錯誤解決:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao
既然提示@PersistenceContext只能用在SessionBean中,因為原來的代碼是使用的Spring框架,想了好長時間,在WebContent/WEB-INF/component.xml中看到這么一段,那么是不是通過@In來注入entityManager呢,修改@PersistenceContext為@In,編輯器自動提示沒有發現名稱為em的Component(這點好像不錯),于是再修改為@In("entityManager") ,重啟服務器,該問題解決。
<persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{testEntityManagerFactory}"/>
第三個錯誤解決:Caused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao"
將UserService中的@In修改為@In(create = true, required = true)解決此問題。
解決上述幾個問題后,自己的例子終于運行起來了 :-)
下一篇關于Seam In Action中對JSF的介紹及Seam如何增強JSF。
-------------------------------------------------------------------------------------------------
項目生成的代碼被分為兩個目錄,分別為Action和Model目錄,檢查JBoss中項目部署的目錄,發覺Action目錄下的代碼編譯生成的class文件被存放至WEB-INF/dev目錄下,Model目錄下的代碼編譯生成的class文件被存放至WEB-INF/classes目錄下,google了一下,發現在Seam Reference中提到這是Seam的增量式重部署,支持對JavaBean組件的增量重部署,可以加快編輯/編譯/測試的速度。
代碼如下:
public interface GenericDao {
public Object get(Class clazz, Serializable id);
public void save(Object object);
public void update(Object object);
public void remove(Class clazz, Serializable id);
public void remove(Object obj);


}
@Name("genericDao")
public class GenericDaoImpl implements GenericDao {
@PersistenceContext ----> @In("entityManager")
private EntityManager em;
public Object get(Class clazz, Serializable id) {
if (id == null) return null;
else return em.find(clazz, id);
}


}
public interface UserService {
public void findAllUsers();
}
@Name("userService")
public class UserServiceImpl implements UserService, SecurityUserService {
@In ----> @In(create = true, required = true)
protected GenericDao genericDao;
private List<User> resultList = null;
public List<User> getResultList() {
if (resultList == null) {
this.findAllUsers();
}
return resultList;
}
public void setResultList(List<User> resultList) {
this.resultList = resultList;
}
public void findAllUsers() {
String hql = "from User order by userCode";
resultList = this.genericDao.query(hql);
}
}
// 實體類
@Entity
@Table(name = "USER")
public class User implements IUser, Serializable {
// 用戶編碼
@Id
private String userCode;
// 用戶姓名
private String userName;
}
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="layout/template.xhtml">
<ui:define name="body">
<rich:panel>
<f:facet name="header">User Search Results</f:facet>
<rich:dataTable id="userServiceTable"
var="user"
value="#{userService.resultList}">
<h:column>
<f:facet name="header">
<h:outputText value="UserCode"/>
</f:facet>
<h:outputText value="#{user.userCode}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="UserName"/>
</f:facet>
<h:outputText value="#{user.userName}"/>
</h:column>
</rich:dataTable>
</rich:panel>
</ui:define>
</ui:composition>
通過這個實踐,小結一下:
1、發覺Seam確實簡化了JSF開發,但由于它涉及的新東西相對較多,與傳統的SSH走的路線不太一致,還是覺得其學習曲線比較陡峭,需要對Seam熟練掌握后(包括開發環境的搭建等)才能真正提高開發效率。
2、Seam提供了IOC的功能,有時需要跳出Spring,從一個新的角度去審視Seam。
posted @
2008-12-18 23:46 The Matrix 閱讀(2165) |
評論 (0) |
編輯 收藏
這個星期的后半周主要搞了kettle的試驗,做了兩個例子出來,在后續工作中這兩個例子應該也能派上用場,本來以為kettle的文檔不多,后來單獨下載了kettle的doc壓縮包,發覺里面的內容還是不少的,真要將kettle搞熟的話,這些文檔還是需要仔細研讀一番的。另外kettle doc解壓后文檔目錄挺奇怪的,都是數字命名的目錄名,不知有啥具體含義。
下周的學習重點還是要轉回到JBoss Seam中了 :-)
posted @
2008-12-14 22:13 The Matrix 閱讀(1278) |
評論 (3) |
編輯 收藏
需求:
kettletest1數據庫中有table_source數據表,結構如下:
- Id 主鍵
- t_id 數據時間
- part_id 實例ID
- yg 數據字段1
- wg 數據字段2
該表中的數據對于不同的實例ID,一分鐘一條數據,t_id字段表示數據的時間,精確到分鐘。
kettletest2數據庫中有table_target數據表,結構如下:
- Id 主鍵
- marketdate 數據日期,格式為 yyyy-MM-dd
- pointtime 時間,格式為 HH:mm
- pointnumber 時間的數字表示,00:01表示為1,00:00表示為1440
- plantcode 實例Code
- yg 數據字段1
- wg 數據字段2
需定期將table_source表中的數據獲取至table_target表中,并進行如下處理:
1、將t_id數據時間字段拆分為三個字段,分別為marketdate、pointtime、pointnumber。
a、marketdate取t_id的日期部分。
b、pointtime取t_id的時間部分。
c、pointnumber為時間的數字表示,等于hour*60+minute。
d、但當t_id的時間為某日的00:00時,需將其轉化為24:00,并且marketdate需取日期的前一天。如t_id為2008-12-04 00:00,則marketdate為2008-12-03,pointtime為24:00,pointnumber為1440。
2、將part_id字段映射為plantcode字段,并根據如下規則進行轉換:
part_id plantcode
3206 P01
3207 P02
3208 P03
測試中使用的數據庫均為mysql數據庫。
實戰:
整個轉換工作共分為三個步驟,如下圖:

1、定義需獲取的數據的日期
2、刪除table_target表中已有數據,注意一定要將“執行SQl語句”面板中的“變量替換”要選上,否則SQL語句中的變量不會被替換,我剛開始沒注意到這個地方,找問題找了半天。
3、獲取table_source中的數據,并將其插入table_target表
3-1、獲取table_source表的數據
3-2、值映射
3-3、字段選擇
3-4、對t_id字段進行處理,增加了pointnumber字段。在這一步驟中發現kettle的一個bug,就是不能在JavaScript中使用str2date函數,錯誤的具體信息參見:http://jira.pentaho.com/browse/PDI-1827。這個問題也折騰了好長時間,剛開始怎么也想不通這個函數使用時怎么會報錯呢,后來只好從字符串中截取年、月、日信息。
該步驟中還存在另外一個使人困惑的問題,就是點擊“測試腳本”按鈕,會報錯,但是執行job和transformation時則不會報錯。
3-5、增加pointnumber字段至輸出結果中
3-6、插入數據至table_target表
3-4步驟中的JavaScript代碼如下:
var pointTimeStr = pointtime.getString();
var pointnumber = 1;
if (pointTimeStr == "00:00") {
var marketDateStr = marketdate.getString();
var marketDateYear = substr(marketDateStr, 0, 4);
var marketDateMonth = str2num(substr(marketDateStr, 5, 2))-1;
var marketDateDay = substr(marketDateStr, 8, 2);
var date = new Date();
date.setYear(marketDateYear);
date.setMonth(marketDateMonth);
date.setDate(marketDateDay);
var temp1 = dateAdd(date, "d", -1);
marketdate.setValue(date2str(temp1, "yyyy-MM-dd"));
pointtime.setValue("24:00");
pointnumber = 1440;
} else {
var hourStr = pointTimeStr.substr(0, 2);
var hour = str2num(hourStr);
var minuteStr = pointTimeStr.substr(3, 5);
var minute = str2num(minuteStr);
pointnumber = hour * 60 + minute;
}
至此,整個轉換工作完成,小結一下:
如果對kettle等etl工具比較熟悉的話,使用etl工具進行數據轉換、抽取等事情還是比較方便的,比起寫程序還是有優勢的。但是這個轉換過程中遇到的kettle的兩個bug比較讓人頭疼,覺得kettle好像還不是很穩定。
posted @
2008-12-14 21:55 The Matrix 閱讀(34333) |
評論 (5) |
編輯 收藏
這個實踐其實不難,主要是有一個地方要注意,就是文件名通配符的寫法,如果文件名格式為“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS開頭的文本文件,在kettle中要寫成這樣:TRANS_.*[0-9].txt。
最后在windows操作系統中配置定時任務就可以定期執行該Job了。
Job的圖:
FTP配置信息:

posted @
2008-12-12 15:20 The Matrix 閱讀(17070) |
評論 (0) |
編輯 收藏
一定要給SQL Server2000打上sp3a補丁,打上補丁后,使用telnet訪問1433端口一切正常。
另外學了一個查詢SQL Server版本的語句:select @@version
posted @
2008-12-12 12:07 The Matrix 閱讀(1447) |
評論 (1) |
編輯 收藏
DATE_FORMAT(date,format)
根據format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 數字, 4 位
%y 年, 數字, 2 位
%a 縮寫的星期名字(Sun……Sat)
%d 月份中的天數, 數字(00……31)
%e 月份中的天數, 數字(0……31)
%m 月, 數字(01……12)
%c 月, 數字(1……12)
%b 縮寫的月份名字(Jan……Dec)
%j 一年中的天數(001……366)
%H 小時(00……23)
%k 小時(0……23)
%h 小時(01……12)
%I 小時(01……12)
%l 小時(1……12)
%i 分鐘, 數字(00……59)
%r 時間,12 小時(hh:mm:ss [AP]M)
%T 時間,24 小時(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一個星期中的天數(0=Sunday ……6=Saturday )
%U 星期(0……52), 這里星期天是星期的第一天
%u 星期(0……52), 這里星期一是星期的第一天
%% 一個文字“%”。
posted @
2008-12-10 09:18 The Matrix 閱讀(737) |
評論 (0) |
編輯 收藏
看了Seam的例子,也看了Seam的簡介,禁不住手癢,還是先做一個例子吧,遵照《seam_reference》第三章中的指導,使用JBossTool生成了自己的第一個例子,過程如下:
1、生成Sem web項目
2、輸入項目的相關信息,如下圖:
注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。
3、然后一路next,到最后一步時,如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下圖。最后點擊finish按鈕,即可創建Seam項目。
4、生成項目后,在Eclipse中共出現了四個項目,如下:
- seamfirst (web項目)
- seamfirst-ear (ear項目,集成web和ejb)
- seamfirst-jar (ejb項目)
- seamfirst-test (測試項目,進行單元測試)
此時運行JBossServer服務器,訪問http://localhost:8080/seamfirst鏈接,出現如下圖頁面,此時Seam幫我們生成了一個框架,包含了基本的登錄和退出功能,還有一個首頁。
5、繼續!使用Seam生成單表的CRUD操作。本步驟前提,有一個mysql數據庫,數據庫中有一個Customer表,該表有ID(int類型)、customername(varchar2類型)、customerdesc(varchar2類型)、createdate(date類型)、email(varchar2類型)五個字段。在seamfirst項目上點擊右鍵,選擇Seam Generate Entities菜單,彈出界面如下圖:
單擊finish按鈕后,再運行JBoss Server服務器,訪問http://localhost:8080/seamfirst,發覺菜單欄上多了一個Customer List菜單,單擊此鏈接,即可進行Customer的添加、刪除、修改、查詢操作,雖然生成的界面不是很好看,也不是很符合我自己的操作習慣,但是功能倒是完備。
以后若是修改了Seam提供的代碼自動生成的模板,然后再使用該功能,想必生成的頁面就符合自己的項目要求了,記下一筆,先不管它。
生成的代碼分析:
生成的代碼主要有兩部分,一部分為Java代碼,一部分為頁面代碼。
Java代碼包括如下三個類:
- Customer.java ---- 實體類,映射到數據庫中的Customer表。
- CustomerHome.java ---- SessionBean,提供了Customer類的創建、更新、刪除功能。繼承了org.jboss.seam.framework.EntityHome類,EntityHome類中提供創建、更新、刪除等基本功能。
- CustomerList.java ---- SessionBean,提供了Customer類的查詢功能。繼承了org.jboss.seam.framework.EntityQuery類,EntityQuery類中提供了查詢功能。
CustomerHome和CustomerList類中都使用了@Name annotation,這樣在頁面中就可以直接訪問Session Bean中的方法了,達到了Seam將表現層和業務層直接融合的目標。
頁面代碼包括如下文件:
- Customer.xhtml
- Customer.page.xml
- CustomerEdit.xhtml
- CustomerEdit.page.xml
- CustomerList.xhtml
- CustomerList.page.xml
剛開始看這段代碼時,困惑我的有兩個地方
- 一個是CustomerList.xhtml中rich:dataTable的value為"#{customerList.resultList}",customerList我明白指的是CustomerList SessionBean,但是我看遍了其代碼,也沒有發現有resultList屬性,后來仔細一看,才發覺該屬性在其父類EntityQuery中。
- 另一個是每一個xhtml文件都有一個對應的page.xml文件,想了半天也沒整明白這是怎么回事,后來只好繼續看Seam in Action的第三章,看著看著終于明白了,原來這是Seam對JSF的一個擴展,增強了JSF的功能,具體含義后面詳細解釋。
至此第一個使用JBossTools生成的Seam例子完成了,好像很簡單 :-)
posted @
2008-12-09 22:40 The Matrix 閱讀(2137) |
評論 (1) |
編輯 收藏
需求:Oracle的數據庫文件都存放在C盤,由于數據文件越來越大,所以想把一些數據文件移至D盤
環境:Oracle9i
操作步驟:
- sqlplus /nolog
- connect / as sysdba;
- shutdown immediate;
- startup mount;
- alter database rename file 'c:\ora92\oradata\trans\trans.dbf' to 'd:\ora92\oradata\trans\trans.dbf';
- alter database open;
注意點:
附Oracle的幾種啟動方式
1、startup nomount
非安裝啟動,這種方式啟動下可執行:重建控制文件、重建數據庫。
讀取init.ora文件,啟動instance,即啟動SGA和后臺進程,這種啟動只需要init.ora文件。
2、startup mount dbname
安裝啟動,這種方式啟動下可執行:數據庫日志歸檔、數據庫介質恢復、使數據文件聯機或脫機、重新定位數據文件、重做日志文件。
執行“nomount”,然后打開控制文件,確認數據文件和聯機日志文件的位置,但此時不對數據文件和日志文件進行校驗檢查。
3、startup open dbname
先執行“nomount”,然后執行“mount”,再打開包括Redo log文件在內的所有數據庫文件,這種方式下可訪問數據庫中的數據。
4、startup,等于以下三個命令
startup nomount
alter database mount
alter database open
posted @
2008-12-09 10:16 The Matrix 閱讀(2768) |
評論 (1) |
編輯 收藏
用JBossTools生成項目,生成CRUD的代碼,然后訪問就報了如下異常:
Exception during request processing:
Caused by java.lang.IllegalStateException with message: "No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed)"
org.jboss.seam.contexts.PageContext.getPhaseId(PageContext.java:163)
org.jboss.seam.contexts.PageContext.isBeforeInvokeApplicationPhase(PageContext.java:175)
org.jboss.seam.contexts.PageContext.getCurrentWritableMap(PageContext.java:91)
org.jboss.seam.contexts.PageContext.remove(PageContext.java:105)
org.jboss.seam.Component.newInstance(Component.java:2102)
org.jboss.seam.Component.getInstance(Component.java:1987)
org.jboss.seam.Component.getInstance(Component.java:1966)
org.jboss.seam.Component.getInstance(Component.java:1960)
org.jboss.seam.Component.getInstance(Component.java:1933)
org.jboss.seam.Component.getInstance(Component.java:1928)
org.jboss.seam.faces.FacesPage.instance(FacesPage.java:92)
org.jboss.seam.core.ConversationPropagation.restorePageContextConversationId(ConversationPropagation.java:84)
org.jboss.seam.core.ConversationPropagation.restoreConversationId(ConversationPropagation.java:57)
org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:389)
org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:228)
org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:194)
com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114)
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507)
org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:54)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432)
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
java.lang.Thread.run(Thread.java:619)
Google了一下,有人講是JBoss4.2.3GA版本的BUG,趕緊下載了JBoss4.2.2GA,再測試一切正常!
不知還會不會有其它莫名的BUG了......
posted @
2008-12-07 22:03 The Matrix 閱讀(1028) |
評論 (0) |
編輯 收藏
把環境配好之后,Seam的例子也運行起來了,看了seam_reference第一章中如下幾個例子講解:
- the registration example
- the messages example
- the todo list example
- the numberguess example
又在滿江紅的網站上找了seam_reference2.0的中文文檔,主要看了《the contextual component model》一章,看完以后感覺Seam最核心的地方就是其contextual component model了,不過看完這一章以后只是對Seam有個大概的了解,對其具體的內容,細節還缺乏進一步的了解,對其優點、缺點也缺乏進一步的認識。
然后又找到了《Seam in Action》的電子書,看了一點之后還是覺得這本電子書寫得好,內容組織的很好,不象seam_reference后面的章節僅僅是羅列seam的各項功能。
今天把Seam in Action的第一章草草看了一遍,將第一章講述的內容總結如下:
1、什么是Seam
在Seam in Action中,沒有將Seam稱之為web framework,而是將其稱為application stack。Seam將Java EE中的EJB3、JSF、JPA/Hibernate、JAAS等技術融合在一起,提供了更容易使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、email組合、charting、file uploads、Groovy integration等,用以簡化web開發。
2、Seam的目標
簡化web開發
3、Seam如何集成各類技術
Seam集成了JSF、JPA和POJO Component
在Seam中將EJB3.0中的Session Bean作為JSF的managed bean,直接將表現層和業務層銜接在一起,使得Session Bean可以直接訪問web相關數據,比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam時,一般都是使用JSF back bean來作為表現層和業務層之間的中介。
使用annotation中的@Name標注替代了JSF的faces-config.xml中關于managed bean的配置。
Seam不一定必須使用EJB和JPA,也可以使用POJO、Hibernate作為替代。如下圖:
上下文相關的組件模型(Seam中的核心概念)
Seam提供了7種類型的上下文,其中屬于Seam特有的兩種上下文類型分別為:Conversation Context、Business process Context。
Seam提供了統一的組件注冊、annotation、異常配置、方法攔截、統一的EL表達式等功能。其中Seam對其管理的組件攔截過程如下圖:
4、Seam的核心競爭力
更好的JSF
增強的JSF
- Seam對JSF最被認可的改進就是消除了在配置文件中聲明managed bean。
- Prerender page actions
- Managed request parameters (for a given page)
- Intelligent stateless and stateful navigation
- Transparent JSF data model and data model selection handling
- Fine-grained exception handling
- Page-level security (per view ID)
- 基于Annotation的表單驗證
- Bookmarkable command links (solving the “everything is a POST” problem)
- Entity converter for pick lists
- Conversation controls
- Support for preventing lazy initialization exceptions and nontransactional data access in the view
消除了連接Bean(ELIMINATING CONNECTOR BEANS)
用一幅圖可以很好的說明這句話的含義
引入了有狀態的變量范圍(INTRODUCING STATEFUL VARIABLE SCOPES)
擴展的Persistence Context
Spring中提供了The Session In View Filter,使得persistence manage可以在一個請求中存在,避免了常見的LazyInitializationException。在Seam中,擴展的Persistence Context可以跨越多個請求。其實擴展的Persistence Context是Conversation Context、Business Process Context的基礎。
get rich quick
Seam提供了兩種方式將Ajax集成到Seam應用中,一種是使用具有Ajax特性的JSF組件,如RichFaces和ICEFaces,另一種是可以在瀏覽器中使用JavaScript直接調用服務端的組件。
Seam還提供了另外一種意義上的Rich,即將PDF、mail等功能集成到Seam應用中。
提供了一個快速開發環境
代碼自動生成
熱部署
Seam調試頁面
不部署即可以進行單元測試
從目前我個人的理解來看,Seam的作用與能力如下:
- Seam將EJB3與JSF整合在一起,消除了JSF與業務代碼之間的間隙,直接將表現層與業務層銜接在一起
- Seam提出了Conversation Context的概念,將Stateful EJB引入到web開發中,直接與Conversation Context對應
- Seam提供了與Jbpm、itext、mail等一系列開源框架的整合,對于需要使用的相關功能的用戶來說,提供了便利性
- 提供了開發工具的整合(Seam Gen與IDE),還可以自動生成部分代碼
但由于Seam整合了如此多的框架,帶來的一個最大的缺點:學習曲線陡峭,在SSH非常流行的今天,需要面對很多新技術(JSF、EJB3、JPA等),對于一個新手來說難度比較大,如果想使Seam被更多的開發人員使用,必須加強它的文檔,目前的文檔還是太少了。
posted @
2008-12-06 23:51 The Matrix 閱讀(2283) |
評論 (0) |
編輯 收藏
今天早上在網上看到了kettle發布了最新的版本,忽然想起最近其實做了不少工作應該是ETL工具的拿手好戲,趕緊下載下來看看,看是否能夠在實際的工作中應用起來。
順便講一下,為啥看到kettle會兩眼發光。
最近寫了好幾個小程序,用于從一個ftp去獲取數據,然后轉發至另一個ftp去,或者是從一個數據庫獲取數據然后保存至本地的數據庫中,使用的是jdk中的Timer實現的定時調度,本來也沒什么問題,連續運行幾個月都不會出錯。
可是最近網絡不是太好,周期性抽風,ping包時,每5分鐘大概會丟7-8個包,從而導致程序也會假死,過一段時間后就不正常干活了,估計是因為用了數據庫連接池的問題,要是每次發起數據庫連接可能就不會有問題了,偷懶也不想改了,因為網絡最終肯定是會修好的 :-) 但是想試試ETL工具,因為后面還有一些類似的東西要處理,不想寫代碼了,用別人的輪子感覺比較好,呵呵
首先下載了kettle的最新版,kettle3.1,解壓后即可運行,一般的開發人員稍微摸索一下,看看例子簡單的轉換還是會做的,今天小試了一把,有幾個注意點記下來。
- 使用資源庫(repository)登錄時,默認的用戶名和密碼是admin/admin
- 當job是存放在資源庫(一般資源庫都使用數據庫)中時,使用Kitchen.bat執行job時,需使用如下的命令行:
Kitchen.bat /rep kettle /user admin /pass admin /job job名
- 當job沒有存放在資源庫而存放在文件系統時,使用Kitchen.bat執行job時,需使用如下的命令行:
Kitchen.bat /norep /file user-transfer-job.kjb
- 可以使用命令行執行job后,就可以使用windows或linux的任務調度來定時執行任務了
在一開始使用命令行方式執行job時,總是報如下的錯誤,琢磨了好長時間總算整明白正確的方式了。
Unexpected error during transformation metadata load
No repository defined!
下一步準備按照實際情況定制Job,做好了再寫小結。
posted @
2008-12-04 22:48 The Matrix 閱讀(10359) |
評論 (13) |
編輯 收藏
JBoss Envers目的是根據對實體的設置,提供記錄執行數據變更歷史的功能(數據變更版本)。Envers的配置非常簡單,如果需要對某個實例進行歷史數據版本記錄,只需要在實例上配置@Versioned annotation即可。針對每個實體的版本的歷史數據,Envers都會創建一個單獨的數據表進行存儲。
目前Envers支持Hibernate和Hibernate-entitymanager(JPA實現).
這個特點在需要對歷史數據進行存檔時很實用,而且目前Envers已經合并到Hibernate的新版本中去了,使用起來更方便,具體Hibernate哪個不太清楚。
留個印記..............
posted @
2008-12-04 09:04 The Matrix 閱讀(298) |
評論 (0) |
編輯 收藏
準備深入學習JBossSeam,好好研究研究,具體學習路線基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。
學習JBossSeam之前最好對相關技術有一定的了解,比如:
然后下載相關的軟件,如下:
- jboss-seam-2.1.1.CR1
- jboss-4.2.3.GA
- JBossTools-3.0.0.Beta1-R200810311334-ALL-win32(開發環境)
- eclipse-jee-ganymede-SR1-win32(開發環境)
- apache-ant-1.7.0
- jdk1.6.0_06
環境的配置都比較簡單,基本都是解壓即可,有如下注意事項:
- 在系統的環境變量中設置JAVA_HOME、ANT_HOME
- JBossTools解壓后需拷貝至eclipse解壓后的目錄中。
- jboss-seam-2.1.1.CR1解壓后,需設置其bulid目錄下的default.build.properties文件中的jboss.home為JBOSS_HOME(假定為jboss-4.2.3GA的安裝目錄)。
上述配置好后,啟動JBoss Server,然后至SEAM_HOME(假定為Seam的安裝目錄)/examples/registration目錄下,運行ant explode命令,即可編譯部署registration應用至JBoss Server中,最后訪問:http://localhost:8080/seam-registration 即可體驗Seam提供的第一個example程序 :-)
posted @
2008-12-03 23:03 The Matrix 閱讀(964) |
評論 (0) |
編輯 收藏
考核系統快結束了,將此項目的經歷回憶如下,也小結一下,先談這個項目中值得提倡的地方:
1、在開發之前進行了完整的需求分析,形成了系統的需求文檔,需求文檔中最有用的部分感覺就是界面原型,還有系統的菜單,這樣給了用戶一個初步的直觀的印象,同時文檔中的一些對于界面原型的描述以及計算規則等內容在后期的開發中也起了指導作用。
2、在需求分析完成之后,進行了概要設計,包括完整的數據庫設計,這樣在后期的開發中對數據庫表結構方面沒有大的修改了,只是添加了一些表和視圖。
再談談項目中的缺點吧:
1、首先就說說需求文檔,雖說需求文檔寫了很多,大概有100頁左右(word),但由于一篇文檔中集中的內容太多,對于用戶來說只是關注了界面原型,系統菜單等部分,對于其它內容用戶關注度不高;同時由于篇幅太大,開發人員打開查看或者后續修改也比較麻煩。
對于以后的需求文檔是否可以這樣編寫:首先有一個正文,正文中包括大綱,然后將每一個具體的需求放在單獨的一個文檔中,最好能類似html鏈接那樣,這樣查看也方便,也一目了然。
原來用RobotHelp寫過幫助,照此看來,豈不可以用來寫需求文檔了,呵呵
2、再說數據庫設計,還不夠細致,很多應用場景由于設計的不夠細致,導致數據庫表也有所欠缺,因此對于以后的項目設計有兩個注意點:
a、加強應用場景設計,具體可以用流程圖,甚至序列圖描述清晰的業務流程,完善數據庫表設計。
b、要求一定先修改模型(這里指PowerDesigner中的數據庫設計),然后再去修改POJO類等具體代碼,最好不要先改代碼,再修改模型,這樣難免會有遺漏,時間久了,就會導致模型和代碼的不一致,慢慢的,模型文檔就沒有人看,也沒有人維護了。
c、順便提一下,模型文檔的好處一是方便后來者,二是可以方便的導出數據字典。
3、對于命名規范沒有在開發前考慮全面,雖然在開發前對命名規范有一定的規定,但是不夠全面,造成了后期開發中各人各人的命名有所偏差。
4、分層架構中的dao層和service層處理的不夠好,導致service層實際上是混雜了dao和service的功能,業務代碼不夠清晰。以后的項目考慮dao就是dao,提供數據訪問的操作,service層則提供業務處理方法,service與dao的關系應該是多對多的關系。
5、考核系統中使用了JSF/Richfaces做為表現層,好像不太好使,經常會出現多次重復訪問方法的問題,后續還需要加強對JSF的學習,避免類似問題。另外Richfaces在生成大數據量的頁面時,一個表格有1440行數據,頁面巨慢無比:(,后來沒有使用RichaFaces的表格,直接使用jstl+html標簽,速度倒是很快。
6、項目中的日志輸出、異常處理不夠明晰,這個和命名規范一樣應該在項目開始時給出清晰的思路,在具體開發中應該經常檢查。
posted @
2008-12-03 19:50 The Matrix 閱讀(1024) |
評論 (0) |
編輯 收藏
具體內容參見如下鏈接:
http://www.javaworld.com.tw/roller/ingramchen/entry/2005_9_20_JBossSeamKingofStateful_
posted @
2008-12-03 13:11 The Matrix 閱讀(633) |
評論 (0) |
編輯 收藏
今天在http://refcardz.dzone.com/上下載了《Getting Started with Hibernate Search》,乍一看標題,以為是講如何使用Hibernate進行查詢操作什么的,下載好以后打開一看,原來是Hibernate集成了lucene,用來對自己的數據庫進行全文檢索,真是厲害!
沒有仔細研究具體內容,先記下一筆,日后有時間時,可以實踐一把。
posted @
2008-12-01 12:59 The Matrix 閱讀(465) |
評論 (0) |
編輯 收藏
Template設計模式主要適用于需要按一定的步驟執行的場合,但有的步驟在不同的場合執行的內容有不相同。如下類圖中的TemplateClass中的execute()方法會按照如下的順序進行調用:
public void execute() {
step1();
step2();
}
但由于step1在不同的場合執行的內容不一樣,此時就將step1設為抽象方法,在TemplateConcreteClass1和TemplateConcreteClass2中分別實現,這樣就形成了Template設計模式,step1()方法也稱為模板方式。
類圖如下:

posted @
2008-11-29 22:54 The Matrix 閱讀(808) |
評論 (0) |
編輯 收藏
1、在菜單中選擇“Weblog”,然后選擇“Another Weblog Service”。
2、在Weblog Homepage URL中輸入你的Blog主頁地址。
3、輸入用戶名與密碼。
4、在“Type of weblog that you are using”中選擇“Custom(Metaweblog API)”。
5、“Remote posting URL for your weblog”中輸入“http://www.cnblogs.com/用戶名/services/metaweblog.aspx”。
posted @
2008-11-28 22:56 The Matrix 閱讀(230) |
評論 (0) |
編輯 收藏
具體過程參見:http://coenraets.org/flex-spring/
簡要描述一下:
1、首先要繼承FlexFactory,實現Spring與Flex的集成,上文中已經提供了具體實現,下載即可。
2、在web.xml中配置Spring,如下:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3、在service-config.xml配置文件中添加
<factories>
<factory id="spring" class="flex.samples.factories.SpringFactory"/>
</factories>
4、修改remote-config.xml中原有的destination配置,原為:
<properties>
<source>com.bluesky.flexpsp.PsPDataService</source>
</properties>
修改為:
<properties>
<factory>spring</factory><!-- spring為第三步中的factoryID-->
<source>pspDataService</source><!-- pspDataService為bean的id -->
</properties>
posted @
2008-08-09 23:58 The Matrix 閱讀(845) |
評論 (0) |
編輯 收藏
1、使用HTTPService
使用HTTPService可以直接訪問ASP.NET、JSP、Servlet、PHP等頁面,此種方式最為簡單直接。
2、使用WebService
使用WebService可以直接訪問互聯網上各大公司提供的WebService服務,該種方式對做互聯網應用開發可能用的比較多。
3、使用RemoteObject
此種方式可以直接訪問Java Class的method,可以采用此種方式構建 Flex + Spring + Hibernate的應用。
4、使用Message
此種方式彌補了WEB應用的缺點,使得瀏覽器和Server端可以進行雙向交互,可以用于構建復雜的C/S方式的企業應用。
不同方式的具體訪問方法在BlazeDS的Test中都有樣例。
第一、第二種方式不需要服務端有特殊設置,只要客戶端能夠解析服務端返回的信息即可。
第三、第四種方式需要使用BlazeDS進行配置后方可使用,或者使用ColdFusion。
posted @
2008-07-30 12:39 The Matrix 閱讀(486) |
評論 (0) |
編輯 收藏
至
http://opensource.adobe.com/ 可以下載BlazeDS,下載后解壓至本地。
BlazeDS includes the following Web Application Archive (WAR) files:
- blazeds.war - The primary BlazeDS WAR file: use this as a starting point for building your BlazeDS application.
- samples.war - Sample BlazeDS applications.
- ds-console.war - Simple monitoring application for BlazeDS deployments.
在訪問BlazeDS的Sample前,需要首先運行install_root/sampledb目錄下的HSQLDB數據庫,運行方式為啟動startdb.bat腳本
然后啟動tomcat,即可訪問http://localhost:8400/,體驗BlazeDS了。
如果沒有下載tomcat和BlazeDS的整合包,直接安裝BlazeDS的話,對于不同的應用服務器需要進行一些額外的配置,具體參見如下鏈接:
http://opensource.adobe.com/wiki/display/blazeds/Installation+Guide
posted @
2008-07-30 12:38 The Matrix 閱讀(2034) |
評論 (0) |
編輯 收藏
今天忽然想到這個題目----快速高效的開發軟件項目,將個人的一點體會記下來:
1、需求分析要做的充分,使用原型法和用戶進行溝通,這樣可以更好的把握用戶需求。
2、架構設計一定要做,解決項目中可能遇到的難點問題,其實架構設計也可以看作一個抽象的過程,從系統需求中抽取出共性的內容,然后進行設計。
3、多周期迭代,每次迭代的時間控制在兩個星期至一個月,每次迭代結束后一定需要進行測試。要牢記項目經理的職責不是編寫代碼,不是關注編碼的細節,要有全局觀,與用戶要有良好的溝通。
4、困難的問題、基礎的問題要先解決。
5、要有測試人員全程參與,并且測試人員對項目的目標、范圍、質量要求與項目主管、用戶理解一致。
6、確保開發人員理解需要解決的問題后才進行開發,可采用復述法、提問法確保理解。
7、不要采用大家不熟悉的技術,如果采用,那么需要對該技術盡早預研,并開展培訓工作。
8、建立一個強有力的、關系融洽的團隊。團隊中最好能有一個技術高手,最好能有一個活躍氣氛的人。
9、確保能夠有效的溝通,尤其是后期測試人員參與集成測試時。
10、不要把項目時間排的很滿,要留出機動的時間和資源。
11、對項目組成員能夠進行考核獎勵。
12、沒有完美的產品,只有合適的產品。
13、項目啟動前就編碼規范、溝通方式、在項目中采取何種管理方式等與項目組成員進行溝通。項目組每周召開簡短的例會,討論完成情況,分析存在問題,交流溝通其他技術問題。
14、不能姑息項目組中犯錯誤的同事,有問題要指出,方式要恰當。
15、最后一點,不要拘泥于形式,要能夠洞悉項目中已經存在、正在出現、即將發生的問題和風險,并采取適當的方法去解決,最近很喜歡孫子兵法中的一
句話“故兵無常勢,水無常形。能因敵變化而取勝者,謂之神。”。當然這不是說各項知識不需了解,僅憑感覺,這樣是做不好項目的。
posted @
2008-07-18 21:24 The Matrix 閱讀(531) |
評論 (0) |
編輯 收藏
1、專注于構建一個強有力的團隊,這一團隊能夠解決困難的問題,并為客戶創造真正的價值
團隊的定義:團隊就是一群擁有互補技能的人,他們為了一個共同的目標而努力,達成目的并固守相互間的責任
2、領導者鼓舞;管理者授權。要同時成為優秀的領導者和管理者,你需要就愿景進行溝通并理解其細節。
3、對可能出現的障礙有所準備,防微杜漸,在這些障礙尚未壯大時就清除它們。
4、花時間來仔細傾聽別人的意見,但不要過于擔心其他人的想法。
5、專注于事實。
6、充當一個衰減器,而不是放大器,為團隊提供穩定性。
7、永遠不要將不能解釋的事情歸咎于蓄意破壞。
8、培養幽默意識來作為嚴肅認真的一種平衡;對于工作一絲不茍,對自己輕松自如。
9、除了工作,還應該懂得享受生活,而且每年要讀25本書。
10、相信你的直覺:如果你感覺不妙,那么很可能預感就會成真。
摘自《軟件開發的邊界-管理成功的項目》
posted @
2008-07-06 21:26 The Matrix 閱讀(195) |
評論 (0) |
編輯 收藏
如何編寫高質量的Java代碼:
1、
養成良好的習慣及良好的編碼風格,比如當有代碼沒有徹底完成前,通過TODO、FIXME等方式進行標注,比如良好的命名規則、注釋、行間距等
2、
秉承設計模式的一個基本原則:單一職責,一個類不應過于龐大,如果過于龐大,則應分解
3、
避免Ctrl+C、Ctrl+V,當發生這樣的事情后,需要進行重構
4、
要敢于重構,敢于重構的一個質量保證手段就是要對代碼進行充分的測試
5、
注意異常處理、注意事務控制的范圍
6、
遇到問題不能總是求助于Google、其他同事,要自己能夠分析問題,解決問題
7、
不能僅僅滿足于編碼速度快,要時刻牢記需要編寫的是高質量的代碼,易于維護的代碼。一定要深刻理解高質量、易于維護。高質量就是說代碼需要在各種情況下都能正常工作,而不僅僅是正常流程no problem,易于維護就是說如果換了一個開發人員來修改代碼,是否能夠很容易的閱讀代碼,理解代碼,還是他會覺得這段代碼無藥可救了,重寫是最佳選擇,如果是后一種狀況的話,那么這段代碼就是最糟糕的了。
以下為摘自IBM <Java代碼質量專題>的一段話:
高質量的軟件通常具備了這樣一些特性:
- 滿足用戶的需求。
- 合理進度、成本、功能關系。
- 具備擴展性和靈活性,能夠適應一定程度的需求變化。
- 能夠足夠的強壯、足夠的魯棒,能夠有效的處理例外的情況。
- 保持成本和性能的平衡。
-
能夠可持續的發展。
posted @
2008-06-15 22:05 The Matrix 閱讀(897) |
評論 (0) |
編輯 收藏
首先需要明白的是,什么是架構設計,看了以前的培訓資料,也google了,也自己想了,總結下來:
架構設計:軟件系統是由組件以及它們之間的連接關系組成的,同時架構設計還要滿足軟件系統的易變性、可擴展性、可維護性等特性。
搞清楚了什么是架構設計之后,再想想怎么才能做好架構設計呢?
架構設計可大可小,回顧一下自己做過的項目,細想再小的項目其實也有一個架構設計,只不過這個架構設計可能很小,三言兩語就能描述清楚了,比如一個很小的BS系統,可能也要劃分一下,功能模塊如何劃分,哪些是公用的,目錄或package如何劃分,這個我覺得也是架構設計。
但是當系統變大時,架構設計就變得復雜了,因為需要考慮的東西就多了,一方面從系統的功能來說,系統功能點已經上百成千個了,光是搞清楚這些功能點就已經不容易了,如何從這些功能點中發掘共性,劃分組件,如何設計組件之間的聯系,實現分而治之就更復雜了,另一方面,系統變大了,系統的非功能性需求或約束更多了,一個小系統,可能不需要考慮大用戶量、并發、大數據量等問題,但一個大系統,即使用戶不提這些約束條件,一個好的項目經理或者架構師,必須替用戶考慮這些約束條件,有幾年的數據以后,系統會不會變慢,采取什么樣的方式可以解決這樣的問題,用戶如果要求5秒內,系統必須有響應,那么目前的架構設計能不能滿足這樣的要求呢?
同時從軟件系統的架構與建筑設計的類比來看,一個建筑設計,必定是先把建筑結構定下來,然后再按圖施工,如果想有創新性的設計,則必須廣聞博見,同時還必須功力深厚,否則怎么設計的出鳥巢呢?呵呵
同樣對于一個軟件架構的設計者來說,第一個層次,豐富的實踐知識,達到這樣,至少在一定的范圍內可以依葫蘆畫瓢了,同時還可以有一些局部性的創新設計。
第二個層次建立在第一個層次的基礎上,廣聞博見,精通十八般武藝,無論哪種兵器都能使得很趁手,比如BS架構很熟悉,CS架構很熟悉,銀行系統的架構設計做過,電信系統的架構見過研究過,嵌入式系統的架構也熟悉,操作系統、數據庫等基礎知識那更是不用說,至少熟悉多種主流編程語言,還能緊跟潮流趨勢,更要有自己的思想,理解能力深厚,這樣的大師我想應該能做出創新性的設計了。
回顧一下自己,只能是第一個層次了,其實第一個層次也不算很好,第二個層次只能算剛剛入門,看來要成為一個大師,很難,@_@
posted @
2008-06-01 13:18 The Matrix 閱讀(523) |
評論 (0) |
編輯 收藏
今天將以前參加的一個架構設計的培訓教材拿出來又翻了翻,忽然發現當時培訓的教材其實是按照RUP的開發思路來安排的。
首先來看看RUP的核心工作流,分別是:
- 商業建模(業務建模)
- 需求
- 分析與設計
- 實現
- 測試
- 發布
- 配置與變更管理
- 項目管理
- 環境
后面幾項與架構設計的關系不大,重點看前面幾個:商業建模、需求、分析與設計。
回過頭來再看看培訓教材的大綱:
- 架構師必備的全局觀
- 架構設計導論
- 架構設計過程概覽
- 需求分析 ---- RUP ---- 需求
- 領域建模 ---- RUP ---- 商業建模
- 打通軟件需求到架構師設計之墻 ---- RUP ---- 需求、分析與設計
- 概念性架構設計 ---- RUP ---- 分析與設計
- 細化架構設計 ---- RUP ---- 分析與設計
- 非功能需求設計方法論 ---- RUP ---- 分析與設計(重點在非功能需求的架構設計)
- 架構驗證 ---- RUP ---- 分析與設計(重點在驗證)
- UML實踐指南
- 面向對象架構設計
- 架構模式實踐
- 框架技術實踐
除了實踐部分與前面概要性的部分之外,其余部分基本可以對應起來。
有時候,會覺得寫小說是件容易的事情,設計好大綱,一篇一篇往里填充不就行了么,但是換做真的是自己動筆的話,確萬萬也寫不出來。
架構設計也是如此,簡單點說是如此簡單:熟悉需求、商業建模、分析與設計。但是真的遇到一個需要實現的系統時,確發現千頭萬緒,要想做一個好的架構,不是一件容易的事情。
要想做好架構設計,重點還在一個
分析,學習架構設計也是如此,那就是得分析開源框架、別人的代碼為什么要這么做?要分析我從中可以體會到什么?
架構設計師的知識面一定要廣,否則應用面就比較窄了。
說了半天,回頭一看,亂七八糟,其實最近在琢磨的一個問題是,如何才能搞好架構設計 ^_^
再想想,這是一個長期工程,需要不斷的分析積累。
posted @
2008-05-31 22:54 The Matrix 閱讀(487) |
評論 (0) |
編輯 收藏