摘要: 前段時間對Spring的事務(wù)配置做了比較深入的研究,在此之間對Spring的事務(wù)配置雖說也配置過,但是一直沒有一個清楚的認(rèn)識。通過這次的學(xué)習(xí)發(fā)覺Spring的事務(wù)配置只要把思路理清,還是比較好掌握的。
總結(jié)如下:
Spring配置文件中關(guān)于事務(wù)配置總是由三個組成部分,分別是Data...
閱讀全文
posted @
2009-04-05 16:38 The Matrix 閱讀(332571) |
評論 (85) |
編輯 收藏
今天在Javaeye的新聞頻道看到一個界面原型繪制工具,叫做“wireframesketcher”,下載試了試,感覺有如下幾個好處:
1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用
2、集成在eclipse中,對于開發(fā)人員來說用起來更直接
3、其界面原型文件為xml格式,可以使用比較工具比較
唯一的缺點(diǎn):
不是免費(fèi)開源的工具,但是現(xiàn)在可以申請免費(fèi)的license
隨便畫了一個圖,如下:
感興趣的兄弟姐妹們可以到如下地址看看:
http://wireframesketcher.com/index.html
posted @
2009-03-28 21:55 The Matrix 閱讀(4605) |
評論 (1) |
編輯 收藏
由于要寫一個Spring的培訓(xùn)教材,要做Spring的事務(wù)樣例,于是開始寫樣例,寫好了一測,控制臺有SQL輸出,數(shù)據(jù)庫卻查詢不到數(shù)據(jù),查亞查亞,花了一個多小時,原來是獲取的Service不是經(jīng)過代理的Service,自然事務(wù)不起作用,數(shù)據(jù)庫里就沒有數(shù)據(jù)了,鄙視一下自己。
配置文件樣例如下(已經(jīng)修改了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>
<!-- 定義事務(wù)管理器(聲明式的事務(wù)) -->
<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">
<!-- 配置事務(wù)管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="generatorDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.GeneratorDao</value></property>
<!-- 配置事務(wù)屬性 -->
<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">
<!-- 配置事務(wù)管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantDaoTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.dao.PlantDao</value></property>
<!-- 配置事務(wù)屬性 -->
<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">
<!-- 配置事務(wù)管理器 -->
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref bean="plantGeneratorServiceTarget" /></property>
<property name="proxyInterfaces"><value>com.*.spring.service.PlantGeneratorService</value></property>
<!-- 配置事務(wù)屬性 -->
<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發(fā)送給數(shù)據(jù)庫的sql顯示出來 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- SQL方言,這邊設(shè)定的是MySQL -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!--連接數(shù)據(jù)庫的Driver-->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<!--數(shù)據(jù)庫連接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 {
/**
* 獲取所有機(jī)組數(shù)據(jù)
* @return
*/
public List<Generator> listGenerators();
/**
* 保存機(jī)組數(shù)據(jù)
* @param generator 機(jī)組數(shù)據(jù)
*/
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/
由于時間關(guān)系,這個程序還存在不少問題,所以只能供大家參考,有問題不要罵我就行了:)
簡要使用說明:
1、開發(fā)環(huán)境+運(yùn)行環(huán)境:MyEclipse6.0,JDK1.5,Tomcat6.0.14,MySQL5.0
2、準(zhǔn)備好上述環(huán)境后,使用下載代碼sql目錄中的easywork_init.sql腳本創(chuàng)建數(shù)據(jù)庫表和初始數(shù)據(jù)。
3、將項(xiàng)目導(dǎo)入Eclipse后,運(yùn)行Tomcat(此過程就不詳細(xì)描述了)。
4、使用http://localhost/easywork/system/login.jsp訪問登錄頁面,目前還沒有做index.html,默認(rèn)用戶名/密碼:admin/1。
存在問題如下:
1、任務(wù)管理功能還沒有完全完成,日志記錄還沒有做。
2、超時或者沒有登錄訪問頁面時,只是報(bào)不能訪問的異常,沒有轉(zhuǎn)入登錄頁面。
3、對資源類型(菜單、URL、字段、操作)的訪問限制還沒有做。
4、很多界面的輸入信息校驗(yàn)沒有做。
5、基本沒有美工。
6、總而言之,目前這個項(xiàng)目中的代碼只能做Struts2 + ExtJS如何使用的借鑒:)
posted @
2009-03-01 11:03 The Matrix 閱讀(6285) |
評論 (28) |
編輯 收藏
很近沒有更新BLog了,這一陣子忙著學(xué)習(xí)Struts2和ExtJS,使用這兩者做了一個小程序,使用RBAC實(shí)現(xiàn)了基本的權(quán)限管理功能,還做了一個任務(wù)管理和日志記錄,任務(wù)管理用于記錄當(dāng)前需要處理的事情,日志記錄用于記錄每天的工作情況。
用下來Struts2和ExtJS還是挺好用的。先貼幾張圖,后續(xù)再把學(xué)習(xí)過程中遇到的問題整理出來。
任務(wù)管理
添加組

添加權(quán)限
添加角色

posted @
2009-02-26 07:14 The Matrix 閱讀(4333) |
評論 (15) |
編輯 收藏
由于前段時間使用JSF做了一個項(xiàng)目,不少使用JSF的兄弟們對JSF評價(jià)并不好,因此在學(xué)習(xí)的過程中一直在想,JSF究竟是不是應(yīng)該繼續(xù)學(xué)習(xí)繼續(xù)研究使用下去,在看完Seam In Action的第三章后,這個星期又對Struts2簡單學(xué)習(xí)了一下,終于決定結(jié)束JSF和JBoss Seam的學(xué)習(xí)了。
因?yàn)閺腏SF的學(xué)習(xí)和Struts2的學(xué)習(xí)對比中明顯覺得JSF復(fù)雜,對于一個技術(shù)力量不是非常強(qiáng)的項(xiàng)目組來說,使用JSF當(dāng)你遇到一些問題時,絕對是一件痛苦的事情。
從自己的實(shí)踐中覺得JSF至少有兩個致命傷:
1、覺得JSF貌似把簡單的事情搞得復(fù)雜化了,在傳統(tǒng)的MVC框架如Struts中,從request中獲取param很容易,也可以將param封裝為對象,在JSF中,希望將這一切都模型化,一切都以組件為中心,類似于Swing的架構(gòu),但是http的無狀態(tài)以及web的本質(zhì),使得一般JSF只能將組件樹存放在服務(wù)端,同時又不能象CS程序那樣方便的查看組件的狀態(tài)、屬性等信息。對于通常情況來說,JSF將其封裝的很好,不用我們開發(fā)者操心,但是當(dāng)遇到一些問題時,對于開發(fā)者想去調(diào)試查看問題時,問題就顯得很復(fù)雜了。
2、JSF的自定義組件感覺超復(fù)雜,難度應(yīng)該比當(dāng)年自定義JSP標(biāo)簽更要高,試想一下,如果哪個組件不合意了,想改一下,還是比較困難的,除非對JSF組件有相當(dāng)?shù)纳钊肓私狻?/p>
順便把項(xiàng)目中遇到的一個RichFaces的缺點(diǎn)列出來:
RichFaces在生成組件的html時,大量使用了Div,曾經(jīng)有過一個頁面有1千多行(在一個table中),頁面上還有一個RichFaces的下拉菜單,從而導(dǎo)致菜單響應(yīng)非常之慢,后來只有將rich:datatable換為普通的html:table,就沒有問題了。
再看看Seam In Action中總結(jié)的JSF的缺點(diǎn):
1、在JSF中初次請求的處理流程太過簡單,而后續(xù)請求則執(zhí)行了完整的復(fù)雜的處理流程。在JSF中假設(shè)第一個調(diào)用應(yīng)該是在頁面被渲染后執(zhí)行,但實(shí)際中有時我們需要在第一次請求時就執(zhí)行某些操作。在JSF中缺少象Struts中的Controller。
2、所有的請求都是POST。瀏覽器處理POST請求是比較草率,當(dāng)用戶執(zhí)行了一個JSF Action操作后,點(diǎn)擊瀏覽器的刷新按鈕時,瀏覽器會詢問用戶是否重新提交,這會令用戶非常困惑。
3、僅僅擁有簡單基礎(chǔ)的頁面導(dǎo)向機(jī)制。
4、過度復(fù)雜的生命周期。
JBossSeam宣稱對于JSF存在的缺點(diǎn)都提供了解決方法,但是有一種更復(fù)雜的感覺。
在Seam中,生成選擇的項(xiàng)目時,有EAR和WAR的選項(xiàng),如果選擇了EAR選項(xiàng),那么Seam會生成四個項(xiàng)目,分別為war、ear、ejb、test四個類型的項(xiàng)目。有一次我將生成的項(xiàng)目從一個目錄拷貝到另一個目錄,切換了Eclipse的workspace,此時問題來了,ejb項(xiàng)目提示編譯錯誤,提示無法找到某些class,找來找去找來找去......后來將項(xiàng)目關(guān)閉了一下,再打開錯誤提示就沒有了。
由這個問題我忽然想到,使用Seam集成JSF、EJB是不是太重量級了,如果采用EJB作為替代普通的POJO,對于一個小型的項(xiàng)目組來說,一般的規(guī)模就是三至五個人(我個人的理解),開發(fā)人員本來就不多,還要面對Seam劃分的四個項(xiàng)目,好像比較繁瑣,當(dāng)然采用war模式另當(dāng)別論。
相比較而言,這個星期看了一些Struts2的資料,覺得Struts2的架構(gòu)非常清晰,易于理解。
翻了很早之前的JavaEye上的一個帖子,提到JSF是面向開發(fā)工具的,如果能做到象VB那樣,就大有前途了,4年過去了,不要提JSF的開發(fā)工具了,就是Java各個方面的GUI開發(fā)工具,又有哪個能和VB相比呢,看來選擇JSF作為一個方向不是一個好選擇........還是及早放棄吧,哎...
最后我覺得可以用這么一句話可以形容JSF,看起來很美,用起來不爽。
posted @
2008-12-25 23:35 The Matrix 閱讀(2329) |
評論 (6) |
編輯 收藏
這個事情去年做過一次,不過沒有留下記錄,今天又要做一次,記錄下來,呵呵
環(huán)境:
Spring版本為1.2,Tomcat為5.5.26,JDK為Jdk1.5.0_11。
1、下載Axis1.4,解壓后將其jar文件添加到web項(xiàng)目的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);
}
實(shí)現(xiàn)類:
public class InterchangeDataServiceImpl extends ServletEndpointSupport implements InterchangeDataService {
public InterchangeDataServiceImpl() {
}
public String getMonthInterchange(String marketDate) {
return "getMonthInterchange";
}
}
注意實(shí)現(xiàn)類需要繼承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服務(wù),代碼如下。
至項(xiàng)目的WEB-INF目錄下,執(zhí)行如下命令:
Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/interchangeDataService?WSDL
會在WEB-INF目錄中生成四個JAVA文件,它們分別是:
- InterchangeDataServiceImpl.java 定義了Web服務(wù)接口,接口中的方法與InterchangeDataService中的方法一致。
- InterchangeDataServiceImplService.java 定義了用于獲取Web服務(wù)接口的方法。
- InterchangeDataServiceImplServiceLocator.java 接口InterchangeDataServiceImplService的具體實(shí)現(xiàn)。
- InterchangeDataServiceImplSoapBindingStub.java Web服務(wù)客戶端樁,通過該類與服務(wù)器交互。
最后編寫一個Main方法,調(diào)用如下方法即可進(jìn)行測試:
InterchangeDataServiceImplServiceLocator serviceLocator = new InterchangeDataServiceImplServiceLocator();
InterchangeDataServiceImpl service = serviceLocator.getinterchangeDataService();
String monthSchedule = service.getMonthInterchange("2008-05-30");
posted @
2008-12-19 17:16 The Matrix 閱讀(3415) |
評論 (1) |
編輯 收藏
上次使用Seam自動生成了一個CRUD的例子,后來想還是自己白手起家做一個例子看看,于是開始動手。
首先使用JBossTools工具生成項(xiàng)目,在生成項(xiàng)目的向?qū)е校绻?xiàng)目類型選擇ear,則會生成四個項(xiàng)目,分別對應(yīng)war、ear、ejb、test,覺得這樣太過繁瑣,還是選擇war類型,又想要不使用tomcat作為運(yùn)行服務(wù)器吧,因?yàn)镴Boss也不太熟悉。沒想到這一試倒試出問題來了,如果完全使用向?qū)身?xiàng)目,選擇tomcat作為運(yùn)行服務(wù)器,則項(xiàng)目根本無法運(yùn)行起來,總是提示缺少這個jar,那個jar。好,又換回JBoss,沒問題了。仔細(xì)看了一下,原來在自動生成項(xiàng)目的WebContent/WEB-INF/lib目錄中,只有大概十幾個jar,連Hibernate的jar都沒有,而在JBoss的Server/default/lib目錄下則什么jar都有,怪不得不出錯。
第一個教訓(xùn):還是先使用JBoss作為運(yùn)行環(huán)境,等整個Seam都搞熟了,再配一個Tomcat的運(yùn)行環(huán)境。
繼續(xù),將原來項(xiàng)目中的一個通用DAO和一個UserService拷貝過來,代碼如下,啟動服務(wù)器報(bào)錯。分別為如下錯誤信息:
第二個錯誤解決:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao
既然提示@PersistenceContext只能用在SessionBean中,因?yàn)樵瓉淼拇a是使用的Spring框架,想了好長時間,在WebContent/WEB-INF/component.xml中看到這么一段,那么是不是通過@In來注入entityManager呢,修改@PersistenceContext為@In,編輯器自動提示沒有發(fā)現(xiàn)名稱為em的Component(這點(diǎn)好像不錯),于是再修改為@In("entityManager") ,重啟服務(wù)器,該問題解決。
<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)解決此問題。
解決上述幾個問題后,自己的例子終于運(yùn)行起來了 :-)
下一篇關(guān)于Seam In Action中對JSF的介紹及Seam如何增強(qiáng)JSF。
-------------------------------------------------------------------------------------------------
項(xiàng)目生成的代碼被分為兩個目錄,分別為Action和Model目錄,檢查JBoss中項(xiàng)目部署的目錄,發(fā)覺Action目錄下的代碼編譯生成的class文件被存放至WEB-INF/dev目錄下,Model目錄下的代碼編譯生成的class文件被存放至WEB-INF/classes目錄下,google了一下,發(fā)現(xiàn)在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);
}
}
// 實(shí)體類
@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>
通過這個實(shí)踐,小結(jié)一下:
1、發(fā)覺Seam確實(shí)簡化了JSF開發(fā),但由于它涉及的新東西相對較多,與傳統(tǒng)的SSH走的路線不太一致,還是覺得其學(xué)習(xí)曲線比較陡峭,需要對Seam熟練掌握后(包括開發(fā)環(huán)境的搭建等)才能真正提高開發(fā)效率。
2、Seam提供了IOC的功能,有時需要跳出Spring,從一個新的角度去審視Seam。
posted @
2008-12-18 23:46 The Matrix 閱讀(2165) |
評論 (0) |
編輯 收藏
這個星期的后半周主要搞了kettle的試驗(yàn),做了兩個例子出來,在后續(xù)工作中這兩個例子應(yīng)該也能派上用場,本來以為kettle的文檔不多,后來單獨(dú)下載了kettle的doc壓縮包,發(fā)覺里面的內(nèi)容還是不少的,真要將kettle搞熟的話,這些文檔還是需要仔細(xì)研讀一番的。另外kettle doc解壓后文檔目錄挺奇怪的,都是數(shù)字命名的目錄名,不知有啥具體含義。
下周的學(xué)習(xí)重點(diǎn)還是要轉(zhuǎn)回到JBoss Seam中了 :-)
posted @
2008-12-14 22:13 The Matrix 閱讀(1277) |
評論 (3) |
編輯 收藏
需求:
kettletest1數(shù)據(jù)庫中有table_source數(shù)據(jù)表,結(jié)構(gòu)如下:
- Id 主鍵
- t_id 數(shù)據(jù)時間
- part_id 實(shí)例ID
- yg 數(shù)據(jù)字段1
- wg 數(shù)據(jù)字段2
該表中的數(shù)據(jù)對于不同的實(shí)例ID,一分鐘一條數(shù)據(jù),t_id字段表示數(shù)據(jù)的時間,精確到分鐘。
kettletest2數(shù)據(jù)庫中有table_target數(shù)據(jù)表,結(jié)構(gòu)如下:
- Id 主鍵
- marketdate 數(shù)據(jù)日期,格式為 yyyy-MM-dd
- pointtime 時間,格式為 HH:mm
- pointnumber 時間的數(shù)字表示,00:01表示為1,00:00表示為1440
- plantcode 實(shí)例Code
- yg 數(shù)據(jù)字段1
- wg 數(shù)據(jù)字段2
需定期將table_source表中的數(shù)據(jù)獲取至table_target表中,并進(jìn)行如下處理:
1、將t_id數(shù)據(jù)時間字段拆分為三個字段,分別為marketdate、pointtime、pointnumber。
a、marketdate取t_id的日期部分。
b、pointtime取t_id的時間部分。
c、pointnumber為時間的數(shù)字表示,等于hour*60+minute。
d、但當(dāng)t_id的時間為某日的00:00時,需將其轉(zhuǎn)化為24:00,并且marketdate需取日期的前一天。如t_id為2008-12-04 00:00,則marketdate為2008-12-03,pointtime為24:00,pointnumber為1440。
2、將part_id字段映射為plantcode字段,并根據(jù)如下規(guī)則進(jìn)行轉(zhuǎn)換:
part_id plantcode
3206 P01
3207 P02
3208 P03
測試中使用的數(shù)據(jù)庫均為mysql數(shù)據(jù)庫。
實(shí)戰(zhàn):
整個轉(zhuǎn)換工作共分為三個步驟,如下圖:

1、定義需獲取的數(shù)據(jù)的日期
2、刪除table_target表中已有數(shù)據(jù),注意一定要將“執(zhí)行SQl語句”面板中的“變量替換”要選上,否則SQL語句中的變量不會被替換,我剛開始沒注意到這個地方,找問題找了半天。
3、獲取table_source中的數(shù)據(jù),并將其插入table_target表
3-1、獲取table_source表的數(shù)據(jù)
3-2、值映射
3-3、字段選擇
3-4、對t_id字段進(jìn)行處理,增加了pointnumber字段。在這一步驟中發(fā)現(xiàn)kettle的一個bug,就是不能在JavaScript中使用str2date函數(shù),錯誤的具體信息參見:http://jira.pentaho.com/browse/PDI-1827。這個問題也折騰了好長時間,剛開始怎么也想不通這個函數(shù)使用時怎么會報(bào)錯呢,后來只好從字符串中截取年、月、日信息。
該步驟中還存在另外一個使人困惑的問題,就是點(diǎn)擊“測試腳本”按鈕,會報(bào)錯,但是執(zhí)行job和transformation時則不會報(bào)錯。
3-5、增加pointnumber字段至輸出結(jié)果中
3-6、插入數(shù)據(jù)至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;
}
至此,整個轉(zhuǎn)換工作完成,小結(jié)一下:
如果對kettle等etl工具比較熟悉的話,使用etl工具進(jìn)行數(shù)據(jù)轉(zhuǎn)換、抽取等事情還是比較方便的,比起寫程序還是有優(yōu)勢的。但是這個轉(zhuǎn)換過程中遇到的kettle的兩個bug比較讓人頭疼,覺得kettle好像還不是很穩(wěn)定。
posted @
2008-12-14 21:55 The Matrix 閱讀(34331) |
評論 (5) |
編輯 收藏
這個實(shí)踐其實(shí)不難,主要是有一個地方要注意,就是文件名通配符的寫法,如果文件名格式為“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS開頭的文本文件,在kettle中要寫成這樣:TRANS_.*[0-9].txt。
最后在windows操作系統(tǒng)中配置定時任務(wù)就可以定期執(zhí)行該Job了。
Job的圖:
FTP配置信息:

posted @
2008-12-12 15:20 The Matrix 閱讀(17069) |
評論 (0) |
編輯 收藏
一定要給SQL Server2000打上sp3a補(bǔ)丁,打上補(bǔ)丁后,使用telnet訪問1433端口一切正常。
另外學(xué)了一個查詢SQL Server版本的語句:select @@version
posted @
2008-12-12 12:07 The Matrix 閱讀(1446) |
評論 (1) |
編輯 收藏
DATE_FORMAT(date,format)
根據(jù)format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December)
%W 星期名字(Sunday……Saturday)
%D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。)
%Y 年, 數(shù)字, 4 位
%y 年, 數(shù)字, 2 位
%a 縮寫的星期名字(Sun……Sat)
%d 月份中的天數(shù), 數(shù)字(00……31)
%e 月份中的天數(shù), 數(shù)字(0……31)
%m 月, 數(shù)字(01……12)
%c 月, 數(shù)字(1……12)
%b 縮寫的月份名字(Jan……Dec)
%j 一年中的天數(shù)(001……366)
%H 小時(00……23)
%k 小時(0……23)
%h 小時(01……12)
%I 小時(01……12)
%l 小時(1……12)
%i 分鐘, 數(shù)字(00……59)
%r 時間,12 小時(hh:mm:ss [AP]M)
%T 時間,24 小時(hh:mm:ss)
%S 秒(00……59)
%s 秒(00……59)
%p AM或PM
%w 一個星期中的天數(shù)(0=Sunday ……6=Saturday )
%U 星期(0……52), 這里星期天是星期的第一天
%u 星期(0……52), 這里星期一是星期的第一天
%% 一個文字“%”。
posted @
2008-12-10 09:18 The Matrix 閱讀(737) |
評論 (0) |
編輯 收藏
看了Seam的例子,也看了Seam的簡介,禁不住手癢,還是先做一個例子吧,遵照《seam_reference》第三章中的指導(dǎo),使用JBossTool生成了自己的第一個例子,過程如下:
1、生成Sem web項(xiàng)目
2、輸入項(xiàng)目的相關(guān)信息,如下圖:
注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。
3、然后一路next,到最后一步時,如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下圖。最后點(diǎn)擊finish按鈕,即可創(chuàng)建Seam項(xiàng)目。
4、生成項(xiàng)目后,在Eclipse中共出現(xiàn)了四個項(xiàng)目,如下:
- seamfirst (web項(xiàng)目)
- seamfirst-ear (ear項(xiàng)目,集成web和ejb)
- seamfirst-jar (ejb項(xiàng)目)
- seamfirst-test (測試項(xiàng)目,進(jìn)行單元測試)
此時運(yùn)行JBossServer服務(wù)器,訪問http://localhost:8080/seamfirst鏈接,出現(xiàn)如下圖頁面,此時Seam幫我們生成了一個框架,包含了基本的登錄和退出功能,還有一個首頁。
5、繼續(xù)!使用Seam生成單表的CRUD操作。本步驟前提,有一個mysql數(shù)據(jù)庫,數(shù)據(jù)庫中有一個Customer表,該表有ID(int類型)、customername(varchar2類型)、customerdesc(varchar2類型)、createdate(date類型)、email(varchar2類型)五個字段。在seamfirst項(xiàng)目上點(diǎn)擊右鍵,選擇Seam Generate Entities菜單,彈出界面如下圖:
單擊finish按鈕后,再運(yùn)行JBoss Server服務(wù)器,訪問http://localhost:8080/seamfirst,發(fā)覺菜單欄上多了一個Customer List菜單,單擊此鏈接,即可進(jìn)行Customer的添加、刪除、修改、查詢操作,雖然生成的界面不是很好看,也不是很符合我自己的操作習(xí)慣,但是功能倒是完備。
以后若是修改了Seam提供的代碼自動生成的模板,然后再使用該功能,想必生成的頁面就符合自己的項(xiàng)目要求了,記下一筆,先不管它。
生成的代碼分析:
生成的代碼主要有兩部分,一部分為Java代碼,一部分為頁面代碼。
Java代碼包括如下三個類:
- Customer.java ---- 實(shí)體類,映射到數(shù)據(jù)庫中的Customer表。
- CustomerHome.java ---- SessionBean,提供了Customer類的創(chuàng)建、更新、刪除功能。繼承了org.jboss.seam.framework.EntityHome類,EntityHome類中提供創(chuàng)建、更新、刪除等基本功能。
- CustomerList.java ---- SessionBean,提供了Customer類的查詢功能。繼承了org.jboss.seam.framework.EntityQuery類,EntityQuery類中提供了查詢功能。
CustomerHome和CustomerList類中都使用了@Name annotation,這樣在頁面中就可以直接訪問Session Bean中的方法了,達(dá)到了Seam將表現(xiàn)層和業(yè)務(wù)層直接融合的目標(biāo)。
頁面代碼包括如下文件:
- 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,但是我看遍了其代碼,也沒有發(fā)現(xiàn)有resultList屬性,后來仔細(xì)一看,才發(fā)覺該屬性在其父類EntityQuery中。
- 另一個是每一個xhtml文件都有一個對應(yīng)的page.xml文件,想了半天也沒整明白這是怎么回事,后來只好繼續(xù)看Seam in Action的第三章,看著看著終于明白了,原來這是Seam對JSF的一個擴(kuò)展,增強(qiáng)了JSF的功能,具體含義后面詳細(xì)解釋。
至此第一個使用JBossTools生成的Seam例子完成了,好像很簡單 :-)
posted @
2008-12-09 22:40 The Matrix 閱讀(2137) |
評論 (1) |
編輯 收藏
需求:Oracle的數(shù)據(jù)庫文件都存放在C盤,由于數(shù)據(jù)文件越來越大,所以想把一些數(shù)據(jù)文件移至D盤
環(huán)境: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;
注意點(diǎn):
- temp表空間的數(shù)據(jù)文件不能移動
附Oracle的幾種啟動方式
1、startup nomount
非安裝啟動,這種方式啟動下可執(zhí)行:重建控制文件、重建數(shù)據(jù)庫。
讀取init.ora文件,啟動instance,即啟動SGA和后臺進(jìn)程,這種啟動只需要init.ora文件。
2、startup mount dbname
安裝啟動,這種方式啟動下可執(zhí)行:數(shù)據(jù)庫日志歸檔、數(shù)據(jù)庫介質(zhì)恢復(fù)、使數(shù)據(jù)文件聯(lián)機(jī)或脫機(jī)、重新定位數(shù)據(jù)文件、重做日志文件。
執(zhí)行“nomount”,然后打開控制文件,確認(rèn)數(shù)據(jù)文件和聯(lián)機(jī)日志文件的位置,但此時不對數(shù)據(jù)文件和日志文件進(jìn)行校驗(yàn)檢查。
3、startup open dbname
先執(zhí)行“nomount”,然后執(zhí)行“mount”,再打開包括Redo log文件在內(nèi)的所有數(shù)據(jù)庫文件,這種方式下可訪問數(shù)據(jù)庫中的數(shù)據(jù)。
4、startup,等于以下三個命令
startup nomount
alter database mount
alter database open
posted @
2008-12-09 10:16 The Matrix 閱讀(2767) |
評論 (1) |
編輯 收藏
用JBossTools生成項(xiàng)目,生成CRUD的代碼,然后訪問就報(bào)了如下異常:
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) |
編輯 收藏
把環(huán)境配好之后,Seam的例子也運(yùn)行起來了,看了seam_reference第一章中如下幾個例子講解:
- the registration example
- the messages example
- the todo list example
- the numberguess example
又在滿江紅的網(wǎng)站上找了seam_reference2.0的中文文檔,主要看了《the contextual component model》一章,看完以后感覺Seam最核心的地方就是其contextual component model了,不過看完這一章以后只是對Seam有個大概的了解,對其具體的內(nèi)容,細(xì)節(jié)還缺乏進(jìn)一步的了解,對其優(yōu)點(diǎn)、缺點(diǎn)也缺乏進(jìn)一步的認(rèn)識。
然后又找到了《Seam in Action》的電子書,看了一點(diǎn)之后還是覺得這本電子書寫得好,內(nèi)容組織的很好,不象seam_reference后面的章節(jié)僅僅是羅列seam的各項(xiàng)功能。
今天把Seam in Action的第一章草草看了一遍,將第一章講述的內(nèi)容總結(jié)如下:
1、什么是Seam
在Seam in Action中,沒有將Seam稱之為web framework,而是將其稱為application stack。Seam將Java EE中的EJB3、JSF、JPA/Hibernate、JAAS等技術(shù)融合在一起,提供了更容易使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、email組合、charting、file uploads、Groovy integration等,用以簡化web開發(fā)。
2、Seam的目標(biāo)
簡化web開發(fā)
3、Seam如何集成各類技術(shù)
Seam集成了JSF、JPA和POJO Component
在Seam中將EJB3.0中的Session Bean作為JSF的managed bean,直接將表現(xiàn)層和業(yè)務(wù)層銜接在一起,使得Session Bean可以直接訪問web相關(guān)數(shù)據(jù),比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam時,一般都是使用JSF back bean來作為表現(xiàn)層和業(yè)務(wù)層之間的中介。
使用annotation中的@Name標(biāo)注替代了JSF的faces-config.xml中關(guān)于managed bean的配置。
Seam不一定必須使用EJB和JPA,也可以使用POJO、Hibernate作為替代。如下圖:
上下文相關(guān)的組件模型(Seam中的核心概念)
Seam提供了7種類型的上下文,其中屬于Seam特有的兩種上下文類型分別為:Conversation Context、Business process Context。
Seam提供了統(tǒng)一的組件注冊、annotation、異常配置、方法攔截、統(tǒng)一的EL表達(dá)式等功能。其中Seam對其管理的組件攔截過程如下圖:
4、Seam的核心競爭力
更好的JSF
增強(qiáng)的JSF
- Seam對JSF最被認(rèn)可的改進(jìn)就是消除了在配置文件中聲明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的表單驗(yàn)證
- 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)
用一幅圖可以很好的說明這句話的含義
引入了有狀態(tài)的變量范圍(INTRODUCING STATEFUL VARIABLE SCOPES)
擴(kuò)展的Persistence Context
Spring中提供了The Session In View Filter,使得persistence manage可以在一個請求中存在,避免了常見的LazyInitializationException。在Seam中,擴(kuò)展的Persistence Context可以跨越多個請求。其實(shí)擴(kuò)展的Persistence Context是Conversation Context、Business Process Context的基礎(chǔ)。
get rich quick
Seam提供了兩種方式將Ajax集成到Seam應(yīng)用中,一種是使用具有Ajax特性的JSF組件,如RichFaces和ICEFaces,另一種是可以在瀏覽器中使用JavaScript直接調(diào)用服務(wù)端的組件。
Seam還提供了另外一種意義上的Rich,即將PDF、mail等功能集成到Seam應(yīng)用中。
提供了一個快速開發(fā)環(huán)境
代碼自動生成
熱部署
Seam調(diào)試頁面
不部署即可以進(jìn)行單元測試
從目前我個人的理解來看,Seam的作用與能力如下:
- Seam將EJB3與JSF整合在一起,消除了JSF與業(yè)務(wù)代碼之間的間隙,直接將表現(xiàn)層與業(yè)務(wù)層銜接在一起
- Seam提出了Conversation Context的概念,將Stateful EJB引入到web開發(fā)中,直接與Conversation Context對應(yīng)
- Seam提供了與Jbpm、itext、mail等一系列開源框架的整合,對于需要使用的相關(guān)功能的用戶來說,提供了便利性
- 提供了開發(fā)工具的整合(Seam Gen與IDE),還可以自動生成部分代碼
但由于Seam整合了如此多的框架,帶來的一個最大的缺點(diǎn):學(xué)習(xí)曲線陡峭,在SSH非常流行的今天,需要面對很多新技術(shù)(JSF、EJB3、JPA等),對于一個新手來說難度比較大,如果想使Seam被更多的開發(fā)人員使用,必須加強(qiáng)它的文檔,目前的文檔還是太少了。
posted @
2008-12-06 23:51 The Matrix 閱讀(2283) |
評論 (0) |
編輯 收藏
今天早上在網(wǎng)上看到了kettle發(fā)布了最新的版本,忽然想起最近其實(shí)做了不少工作應(yīng)該是ETL工具的拿手好戲,趕緊下載下來看看,看是否能夠在實(shí)際的工作中應(yīng)用起來。
順便講一下,為啥看到kettle會兩眼發(fā)光。
最近寫了好幾個小程序,用于從一個ftp去獲取數(shù)據(jù),然后轉(zhuǎn)發(fā)至另一個ftp去,或者是從一個數(shù)據(jù)庫獲取數(shù)據(jù)然后保存至本地的數(shù)據(jù)庫中,使用的是jdk中的Timer實(shí)現(xiàn)的定時調(diào)度,本來也沒什么問題,連續(xù)運(yùn)行幾個月都不會出錯。
可是最近網(wǎng)絡(luò)不是太好,周期性抽風(fēng),ping包時,每5分鐘大概會丟7-8個包,從而導(dǎo)致程序也會假死,過一段時間后就不正常干活了,估計(jì)是因?yàn)橛昧藬?shù)據(jù)庫連接池的問題,要是每次發(fā)起數(shù)據(jù)庫連接可能就不會有問題了,偷懶也不想改了,因?yàn)榫W(wǎng)絡(luò)最終肯定是會修好的 :-) 但是想試試ETL工具,因?yàn)楹竺孢€有一些類似的東西要處理,不想寫代碼了,用別人的輪子感覺比較好,呵呵
首先下載了kettle的最新版,kettle3.1,解壓后即可運(yùn)行,一般的開發(fā)人員稍微摸索一下,看看例子簡單的轉(zhuǎn)換還是會做的,今天小試了一把,有幾個注意點(diǎn)記下來。
- 使用資源庫(repository)登錄時,默認(rèn)的用戶名和密碼是admin/admin
- 當(dāng)job是存放在資源庫(一般資源庫都使用數(shù)據(jù)庫)中時,使用Kitchen.bat執(zhí)行job時,需使用如下的命令行:
Kitchen.bat /rep kettle /user admin /pass admin /job job名
- 當(dāng)job沒有存放在資源庫而存放在文件系統(tǒng)時,使用Kitchen.bat執(zhí)行job時,需使用如下的命令行:
Kitchen.bat /norep /file user-transfer-job.kjb
- 可以使用命令行執(zhí)行job后,就可以使用windows或linux的任務(wù)調(diào)度來定時執(zhí)行任務(wù)了
在一開始使用命令行方式執(zhí)行job時,總是報(bào)如下的錯誤,琢磨了好長時間總算整明白正確的方式了。
Unexpected error during transformation metadata load
No repository defined!
下一步準(zhǔn)備按照實(shí)際情況定制Job,做好了再寫小結(jié)。
posted @
2008-12-04 22:48 The Matrix 閱讀(10358) |
評論 (13) |
編輯 收藏
JBoss Envers目的是根據(jù)對實(shí)體的設(shè)置,提供記錄執(zhí)行數(shù)據(jù)變更歷史的功能(數(shù)據(jù)變更版本)。Envers的配置非常簡單,如果需要對某個實(shí)例進(jìn)行歷史數(shù)據(jù)版本記錄,只需要在實(shí)例上配置@Versioned annotation即可。針對每個實(shí)體的版本的歷史數(shù)據(jù),Envers都會創(chuàng)建一個單獨(dú)的數(shù)據(jù)表進(jìn)行存儲。
目前Envers支持Hibernate和Hibernate-entitymanager(JPA實(shí)現(xiàn)).
這個特點(diǎn)在需要對歷史數(shù)據(jù)進(jìn)行存檔時很實(shí)用,而且目前Envers已經(jīng)合并到Hibernate的新版本中去了,使用起來更方便,具體Hibernate哪個不太清楚。
留個印記..............
posted @
2008-12-04 09:04 The Matrix 閱讀(298) |
評論 (0) |
編輯 收藏
準(zhǔn)備深入學(xué)習(xí)JBossSeam,好好研究研究,具體學(xué)習(xí)路線基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。
學(xué)習(xí)JBossSeam之前最好對相關(guān)技術(shù)有一定的了解,比如:
然后下載相關(guān)的軟件,如下:
- jboss-seam-2.1.1.CR1
- jboss-4.2.3.GA
- JBossTools-3.0.0.Beta1-R200810311334-ALL-win32(開發(fā)環(huán)境)
- eclipse-jee-ganymede-SR1-win32(開發(fā)環(huán)境)
- apache-ant-1.7.0
- jdk1.6.0_06
環(huán)境的配置都比較簡單,基本都是解壓即可,有如下注意事項(xiàng):
- 在系統(tǒng)的環(huán)境變量中設(shè)置JAVA_HOME、ANT_HOME
- JBossTools解壓后需拷貝至eclipse解壓后的目錄中。
- jboss-seam-2.1.1.CR1解壓后,需設(shè)置其bulid目錄下的default.build.properties文件中的jboss.home為JBOSS_HOME(假定為jboss-4.2.3GA的安裝目錄)。
上述配置好后,啟動JBoss Server,然后至SEAM_HOME(假定為Seam的安裝目錄)/examples/registration目錄下,運(yùn)行ant explode命令,即可編譯部署registration應(yīng)用至JBoss Server中,最后訪問:http://localhost:8080/seam-registration 即可體驗(yàn)Seam提供的第一個example程序 :-)
posted @
2008-12-03 23:03 The Matrix 閱讀(964) |
評論 (0) |
編輯 收藏