隨筆-75  評論-193  文章-5  trackbacks-0
           
               摘要:     前段時間對Spring的事務配置做了比較深入的研究,在此之間對Spring的事務配置雖說也配置過,但是一直沒有一個清楚的認識。通過這次的學習發覺Spring的事務配置只要把思路理清,還是比較好掌握的。     總結如下:     Spring配置文件中關于事務配置總是由三個組成部分,分別是Data...  閱讀全文
          posted @ 2009-04-05 16:38 The Matrix 閱讀(332566) | 評論 (85)編輯 收藏

          今天在Javaeye的新聞頻道看到一個界面原型繪制工具,叫做“wireframesketcher”,下載試了試,感覺有如下幾個好處:

          1、使用方便,可以很容易的做tree和table,比visio中的tree和table好用

          2、集成在eclipse中,對于開發人員來說用起來更直接

          3、其界面原型文件為xml格式,可以使用比較工具比較

          唯一的缺點:

          不是免費開源的工具,但是現在可以申請免費的license

           

          隨便畫了一個圖,如下:

          temp

           

          感興趣的兄弟姐妹們可以到如下地址看看:

          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 閱讀(1549) | 評論 (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還是挺好用的。先貼幾張圖,后續再把學習過程中遇到的問題整理出來。

          任務管理

          task

          添加組

          addgroup

          添加權限

          addprivilege

          添加角色

           addrole

          posted @ 2009-02-26 07:14 The Matrix 閱讀(4331) | 評論 (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 閱讀(3413) | 評論 (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 == nullreturn 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 閱讀(2164) | 評論 (0)編輯 收藏

              這個星期的后半周主要搞了kettle的試驗,做了兩個例子出來,在后續工作中這兩個例子應該也能派上用場,本來以為kettle的文檔不多,后來單獨下載了kettle的doc壓縮包,發覺里面的內容還是不少的,真要將kettle搞熟的話,這些文檔還是需要仔細研讀一番的。另外kettle doc解壓后文檔目錄挺奇怪的,都是數字命名的目錄名,不知有啥具體含義。

              下周的學習重點還是要轉回到JBoss Seam中了 :-)

          posted @ 2008-12-14 22:13 The Matrix 閱讀(1276) | 評論 (3)編輯 收藏

          需求:

          kettletest1數據庫中有table_source數據表,結構如下:

          1. Id                主鍵
          2. t_id             數據時間
          3. part_id        實例ID
          4. yg               數據字段1
          5. wg              數據字段2

          該表中的數據對于不同的實例ID,一分鐘一條數據,t_id字段表示數據的時間,精確到分鐘。

          kettletest2數據庫中有table_target數據表,結構如下:

          1. Id                     主鍵
          2. marketdate      數據日期,格式為 yyyy-MM-dd
          3. pointtime        時間,格式為 HH:mm
          4. pointnumber   時間的數字表示,00:01表示為1,00:00表示為1440
          5. plantcode        實例Code
          6. yg                    數據字段1
          7. 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數據庫。

          實戰:

          整個轉換工作共分為三個步驟,如下圖:

          job

          1、定義需獲取的數據的日期

          trans1

          2、刪除table_target表中已有數據,注意一定要將“執行SQl語句”面板中的“變量替換”要選上,否則SQL語句中的變量不會被替換,我剛開始沒注意到這個地方,找問題找了半天。

          trans2

          3、獲取table_source中的數據,并將其插入table_target表

          trans3

                  3-1、獲取table_source表的數據

          trans3-1

                  3-2、值映射

          trans3-2

                  3-3、字段選擇

          trans3-3

                  3-4、對t_id字段進行處理,增加了pointnumber字段。在這一步驟中發現kettle的一個bug,就是不能在JavaScript中使用str2date函數,錯誤的具體信息參見:http://jira.pentaho.com/browse/PDI-1827。這個問題也折騰了好長時間,剛開始怎么也想不通這個函數使用時怎么會報錯呢,后來只好從字符串中截取年、月、日信息。

                 該步驟中還存在另外一個使人困惑的問題,就是點擊“測試腳本”按鈕,會報錯,但是執行job和transformation時則不會報錯。

          trans3-4

                  3-5、增加pointnumber字段至輸出結果中

          trans3-5

                  3-6、插入數據至table_target表

          trans3-6

           

          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 閱讀(34330) | 評論 (5)編輯 收藏

          這個實踐其實不難,主要是有一個地方要注意,就是文件名通配符的寫法,如果文件名格式為“TRANS_yyyymmdd.txt”,如TRANS_20081101.txt。如果想匹配所有以TRANS開頭的文本文件,在kettle中要寫成這樣:TRANS_.*[0-9].txt。

          最后在windows操作系統中配置定時任務就可以定期執行該Job了。

          Job的圖:

          total

          FTP配置信息:

          get ftp config put ftp config

          posted @ 2008-12-12 15:20 The Matrix 閱讀(17068) | 評論 (0)編輯 收藏

          一定要給SQL Server2000打上sp3a補丁,打上補丁后,使用telnet訪問1433端口一切正常。

          另外學了一個查詢SQL Server版本的語句:select @@version

          posted @ 2008-12-12 12:07 The Matrix 閱讀(1446) | 評論 (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 閱讀(736) | 評論 (0)編輯 收藏

                  看了Seam的例子,也看了Seam的簡介,禁不住手癢,還是先做一個例子吧,遵照《seam_reference》第三章中的指導,使用JBossTool生成了自己的第一個例子,過程如下:

          1、生成Sem web項目

          step1

          2、輸入項目的相關信息,如下圖:

          step2

                注意,如果是第一次使用Eclipse,需要配置Target Runtime和Target Server。

          3、然后一路next,到最后一步時,如果是第一次使用,也要注意配置Seam Runtime和Connection Profile,如下圖。最后點擊finish按鈕,即可創建Seam項目。

          step3

          4、生成項目后,在Eclipse中共出現了四個項目,如下:

          • seamfirst (web項目)
          • seamfirst-ear (ear項目,集成web和ejb)
          • seamfirst-jar (ejb項目)
          • seamfirst-test (測試項目,進行單元測試)

                此時運行JBossServer服務器,訪問http://localhost:8080/seamfirst鏈接,出現如下圖頁面,此時Seam幫我們生成了一個框架,包含了基本的登錄和退出功能,還有一個首頁。

          step5

          5、繼續!使用Seam生成單表的CRUD操作。本步驟前提,有一個mysql數據庫,數據庫中有一個Customer表,該表有ID(int類型)、customername(varchar2類型)、customerdesc(varchar2類型)、createdate(date類型)、email(varchar2類型)五個字段。在seamfirst項目上點擊右鍵,選擇Seam Generate Entities菜單,彈出界面如下圖:

          step6

          step7

                單擊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 閱讀(2136) | 評論 (1)編輯 收藏

          需求:Oracle的數據庫文件都存放在C盤,由于數據文件越來越大,所以想把一些數據文件移至D盤

          環境:Oracle9i

          操作步驟:

          1. sqlplus /nolog
          2. connect / as sysdba;
          3. shutdown immediate;
          4. startup mount;
          5. alter database rename file 'c:\ora92\oradata\trans\trans.dbf' to 'd:\ora92\oradata\trans\trans.dbf';
          6. alter database open;
          注意點:
          • temp表空間的數據文件不能移動

           

          附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 閱讀(2766) | 評論 (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 閱讀(1027) | 評論 (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如何集成各類技術

              selected Seam集成了JSF、JPA和POJO Component

          selected1 在Seam中將EJB3.0中的Session Bean作為JSF的managed bean,直接將表現層和業務層銜接在一起,使得Session Bean可以直接訪問web相關數據,比如request、session、application、JSF的FacesMessage、Component Tree等。而在不使用Seam時,一般都是使用JSF back bean來作為表現層和業務層之間的中介。

          selected1 使用annotation中的@Name標注替代了JSF的faces-config.xml中關于managed bean的配置。

          selected1 Seam不一定必須使用EJB和JPA,也可以使用POJO、Hibernate作為替代。如下圖:

          seam 

              selected 上下文相關的組件模型(Seam中的核心概念)

          selected1 Seam提供了7種類型的上下文,其中屬于Seam特有的兩種上下文類型分別為:Conversation Context、Business process Context。

          selected1 Seam提供了統一的組件注冊、annotation、異常配置、方法攔截、統一的EL表達式等功能。其中Seam對其管理的組件攔截過程如下圖:

          seam1

          4、Seam的核心競爭力

              selected 更好的JSF

          selected1 增強的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

          selected1 消除了連接Bean(ELIMINATING CONNECTOR BEANS)

                用一幅圖可以很好的說明這句話的含義

          seam2

          selected1 引入了有狀態的變量范圍(INTRODUCING STATEFUL VARIABLE SCOPES)

          seam3

          selected1 擴展的Persistence Context

                Spring中提供了The Session In View Filter,使得persistence manage可以在一個請求中存在,避免了常見的LazyInitializationException。在Seam中,擴展的Persistence Context可以跨越多個請求。其實擴展的Persistence Context是Conversation Context、Business Process Context的基礎。

              selected get rich quick

                  Seam提供了兩種方式將Ajax集成到Seam應用中,一種是使用具有Ajax特性的JSF組件,如RichFaces和ICEFaces,另一種是可以在瀏覽器中使用JavaScript直接調用服務端的組件。

                  Seam還提供了另外一種意義上的Rich,即將PDF、mail等功能集成到Seam應用中。

              selected 提供了一個快速開發環境

          selected1 代碼自動生成

          selected1 熱部署

          selected1 Seam調試頁面

          selected1 不部署即可以進行單元測試

                  

          從目前我個人的理解來看,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 閱讀(2282) | 評論 (0)編輯 收藏

                  今天早上在網上看到了kettle發布了最新的版本,忽然想起最近其實做了不少工作應該是ETL工具的拿手好戲,趕緊下載下來看看,看是否能夠在實際的工作中應用起來。

                  順便講一下,為啥看到kettle會兩眼發光。

                  最近寫了好幾個小程序,用于從一個ftp去獲取數據,然后轉發至另一個ftp去,或者是從一個數據庫獲取數據然后保存至本地的數據庫中,使用的是jdk中的Timer實現的定時調度,本來也沒什么問題,連續運行幾個月都不會出錯。

                  可是最近網絡不是太好,周期性抽風,ping包時,每5分鐘大概會丟7-8個包,從而導致程序也會假死,過一段時間后就不正常干活了,估計是因為用了數據庫連接池的問題,要是每次發起數據庫連接可能就不會有問題了,偷懶也不想改了,因為網絡最終肯定是會修好的 :-) 但是想試試ETL工具,因為后面還有一些類似的東西要處理,不想寫代碼了,用別人的輪子感覺比較好,呵呵

                  首先下載了kettle的最新版,kettle3.1,解壓后即可運行,一般的開發人員稍微摸索一下,看看例子簡單的轉換還是會做的,今天小試了一把,有幾個注意點記下來。

          1. 使用資源庫(repository)登錄時,默認的用戶名和密碼是admin/admin
          2. 當job是存放在資源庫(一般資源庫都使用數據庫)中時,使用Kitchen.bat執行job時,需使用如下的命令行:
            Kitchen.bat /rep kettle /user admin /pass admin /job job名
          3. 當job沒有存放在資源庫而存放在文件系統時,使用Kitchen.bat執行job時,需使用如下的命令行:
            Kitchen.bat /norep /file user-transfer-job.kjb
          4. 可以使用命令行執行job后,就可以使用windows或linux的任務調度來定時執行任務了

                  在一開始使用命令行方式執行job時,總是報如下的錯誤,琢磨了好長時間總算整明白正確的方式了。

          Unexpected error during transformation metadata load
          No repository defined!

                  下一步準備按照實際情況定制Job,做好了再寫小結。

          posted @ 2008-12-04 22:48 The Matrix 閱讀(10357) | 評論 (13)編輯 收藏

                  JBoss Envers目的是根據對實體的設置,提供記錄執行數據變更歷史的功能(數據變更版本)。Envers的配置非常簡單,如果需要對某個實例進行歷史數據版本記錄,只需要在實例上配置@Versioned annotation即可。針對每個實體的版本的歷史數據,Envers都會創建一個單獨的數據表進行存儲。

                  目前Envers支持Hibernate和Hibernate-entitymanager(JPA實現).

                  這個特點在需要對歷史數據進行存檔時很實用,而且目前Envers已經合并到Hibernate的新版本中去了,使用起來更方便,具體Hibernate哪個不太清楚。

                  留個印記..............

          posted @ 2008-12-04 09:04 The Matrix 閱讀(296) | 評論 (0)編輯 收藏

          準備深入學習JBossSeam,好好研究研究,具體學習路線基本遵循jboss-seam-2.1.1.CR1中的<<seam_reference.pdf>>。

          學習JBossSeam之前最好對相關技術有一定的了解,比如:

          • JSF
          • EJB3.0
          • JPA

          然后下載相關的軟件,如下:

          • 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 閱讀(963) | 評論 (0)編輯 收藏
          僅列出標題
          共4頁: 上一頁 1 2 3 4 下一頁 
          主站蜘蛛池模板: 杭锦后旗| 武鸣县| 徐闻县| 新晃| 基隆市| 巴南区| 高碑店市| 拜城县| 盱眙县| 富顺县| 云林县| 山西省| 金门县| 南宁市| 岑巩县| 略阳县| 松潘县| 双流县| 通海县| 罗田县| 赣州市| 霍州市| 贵南县| 威远县| 商水县| 延寿县| 红安县| 余江县| 屏边| 宁强县| 寿光市| 香港 | 马关县| 榆中县| 南川市| 前郭尔| 庆云县| 茂名市| 大厂| 晋中市| 高密市|