在线亚洲97se亚洲综合在线,91亚洲国产在人线播放午夜 ,亚洲中文字幕久久精品无码VAhttp://www.tkk7.com/superwei/category/4332.htmlzh-cnThu, 15 Nov 2012 10:08:10 GMTThu, 15 Nov 2012 10:08:10 GMT60SVN配置http://www.tkk7.com/superwei/articles/97256.html小辭猬小辭猬Thu, 01 Feb 2007 06:33:00 GMThttp://www.tkk7.com/superwei/articles/97256.htmlhttp://www.tkk7.com/superwei/comments/97256.htmlhttp://www.tkk7.com/superwei/articles/97256.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/97256.htmlhttp://www.tkk7.com/superwei/services/trackbacks/97256.html
下面是總結出來的SVN的配置方法:
一、服務器端的配置:
1.安裝Apache,安裝文件名為apache_2.0.58-win32-x86-no_ssl.msi,端口設為80,安裝過程中的NetWork Domain和Server Name都設為本機的IP地址(假設你的IP地址為192.168.0.1)
2.編輯Apache的配置文件(C:\Program Files\Apache Group\Apache2\conf\httpd.conf)
去掉下面兩行的"#"

#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_module modules/mod_dav.so
3.安裝SVN,安裝文件名為svn-1.3.2-setup.exe,直接點[下一步]就OK了
如果在Apache的配置文件中的LoadModule區域下面出現下面兩句:
LoadModule dav_svn_module "C:/Program
Files/Subversion/bin/mod_dav_svn.so"
LoadModule authz_svn_module "C:/Program Files/Subversion/bin/mod_authz_svn.so"?
就說明到此為止你的安裝沒有出現錯誤
4.安裝TortoiseSVN,安裝文件名為TortoiseSVN-1.3.2.5840-svn-1.3.0.msi,直接點[下一步]就搞定了,安裝完了之后重新啟動一下,然后還可以安裝一個語言補丁,安裝文件名為LanguagePack_1.3.2_zh_CN.exe
5.建立版本庫。例如在E盤下面新建一個文件夾svn,右鍵點擊文件夾svn,在TortoiseSVN中選擇命令[在此創建文件庫],文件庫類型就選擇本地文件系統[FSFS]
6.編輯新建版本庫的配置文件(E:\svn\conf\svnserve.conf)
去掉下面四行的"#"
# [general]
# anon-access = read
# auth-access = write
# password-db = passwd
8.創建用戶。在命令行中輸入cd C:\Program Files\Apache Group\Apache2\Bin
然后輸入htpasswd,就看看到bin目錄下面的htpasswd可執行文件有哪些參數,
輸入htpasswd -c e:\svn\passwd myloginame,表示在版本庫e:\svn中創建一一個存放用戶信息的文件passwd,然后在這個文件中添加了一個叫myloginame的用戶,回車后就可以設置該用戶的密碼了,這是創建第一個用戶的方法,之后再創建用戶切記一定要-c改了,可以改成-m,如htpasswd -m e:\svn\passwd myloginame2,這樣就可以創建很多個用戶
7.重新編輯Apache的配置文件,在最后面加入下面的語句
<Location /svn>
DAV svn
SVNPath "e:\svn"
AuthType Basic
AuthName "Subversion repository"
AuthUserFile "e:\svn\passwd"
Require valid-user
</Location>
至此服務器端就全部配置好了
二、客戶端的配置
服務器端配置好了之后,客戶端的配置就相對簡單了,只需安裝兩個文件SVN和TortoiseSVN,就是服務器配置中的步驟3和4。客戶端安裝好了之后,即可訪問服務器上的版本庫了,使用方法如下:
1.建立自己的版本庫拷貝。在E盤新建一個文件夾Mysvn,右鍵點擊該文件夾,選擇SVN取出命令,在文件庫URL中輸入 http://192.168.0.1/svn ,這個URL是由服務器端的配置得到的,192.168.0.1是步驟1設置,/svn是步驟7設置的,然后點確定就可以了


小辭猬 2007-02-01 14:33 發表評論
]]>
Log4j基本使用方法http://www.tkk7.com/superwei/articles/75723.html小辭猬小辭猬Tue, 17 Oct 2006 11:29:00 GMThttp://www.tkk7.com/superwei/articles/75723.html

  Log4j由三個重要的組件構成:日志信息的優先級,日志信息的輸出目的地,日志信息的輸出格式。日志信息的優先級從高到低有ERROR、WARN、INFO、DEBUG,分別用來指定這條日志信息的重要程度;日志信息的輸出目的地指定了日志將打印到控制臺還是文件中;而輸出格式則控制了日志信息的顯示內容。

  一、定義配置文件

  其實您也可以完全不使用配置文件,而是在代碼中配置Log4j環境。但是,使用配置文件將使您的應用程序更加靈活。Log4j支持兩種配置文件格式,一種是XML格式的文件,一種是Java特性文件(鍵=值)。下面我們介紹使用Java特性文件做為配置文件的方法:

  1.配置根Logger,其語法為:

  log4j.rootLogger = [ level ] , appenderName, appenderName, …

  其中,level 是日志記錄的優先級,分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定義的級別。Log4j建議只使用四個級別,優先級從高到低分別是ERROR、WARN、INFO、DEBUG。通過在這里定義的級別,您可以控制到應用程序中相應級別的日志信息的開關。比如在這里定義了INFO級別,則應用程序中所有DEBUG級別的日志信息將不被打印出來。 appenderName就是指定日志信息輸出到哪個地方。您可以同時指定多個輸出目的地。

  2.配置日志信息輸出目的地Appender,其語法為:

  log4j.appender.appenderName = fully.qualified.name.of.appender.class
  log4j.appender.appenderName.option1 = value1
  …
  log4j.appender.appenderName.option = valueN

  其中,Log4j提供的appender有以下幾種:
  org.apache.log4j.ConsoleAppender(控制臺),
  org.apache.log4j.FileAppender(文件),
  org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件),
  org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件),
  org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方)

  3.配置日志信息的格式(布局),其語法為:

  log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
  log4j.appender.appenderName.layout.option1 = value1
  …
  log4j.appender.appenderName.layout.option = valueN

  其中,Log4j提供的layout有以下幾種:
  org.apache.log4j.HTMLLayout(以HTML表格形式布局),
  org.apache.log4j.PatternLayout(可以靈活地指定布局模式),
  org.apache.log4j.SimpleLayout(包含日志信息的級別和信息字符串),
  org.apache.log4j.TTCCLayout(包含日志產生的時間、線程、類別等等信息)

  Log4J采用類似C語言中的printf函數的打印格式格式化日志信息,打印參數如下: %m 輸出代碼中指定的消息

  %p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL
  %r 輸出自應用啟動到輸出該log信息耗費的毫秒數
  %c 輸出所屬的類目,通常就是所在類的全名
  %t 輸出產生該日志事件的線程名
  %n 輸出一個回車換行符,Windows平臺為“\r\n”,Unix平臺為“\n”
  %d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921
  %l 輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10)

  二、在代碼中使用Log4j

  1.得到記錄器

  使用Log4j,第一步就是獲取日志記錄器,這個記錄器將負責控制日志信息。其語法為:

  public static Logger getLogger( String name)

  通過指定的名字獲得記錄器,如果必要的話,則為這個名字創建一個新的記錄器。Name一般取本類的名字,比如:

  static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

  2.讀取配置文件

  當獲得了日志記錄器之后,第二步將配置Log4j環境,其語法為:

  BasicConfigurator.configure (): 自動快速地使用缺省Log4j環境。
  PropertyConfigurator.configure ( String configFilename) :讀取使用Java的特性文件編寫的配置文件。
  DOMConfigurator.configure ( String filename ) :讀取XML形式的配置文件。

  3.插入記錄信息(格式化日志信息)

  當上兩個必要步驟執行完畢,您就可以輕松地使用不同優先級別的日志記錄語句插入到您想記錄日志的任何地方,其語法如下:

  Logger.debug ( Object message ) ;
  Logger.info ( Object message ) ;
  Logger.warn ( Object message ) ;
  Logger.error ( Object message ) ;



小辭猬 2006-10-17 19:29 發表評論
]]>
JAVA-STRUTS教程-Struts入門經驗http://www.tkk7.com/superwei/articles/74134.html小辭猬小辭猬Mon, 09 Oct 2006 09:31:00 GMThttp://www.tkk7.com/superwei/articles/74134.htmlhttp://www.tkk7.com/superwei/comments/74134.htmlhttp://www.tkk7.com/superwei/articles/74134.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/74134.htmlhttp://www.tkk7.com/superwei/services/trackbacks/74134.html

以下內容是我自己整理的一些 Struts 實施的入門,希望能對大家有所幫助

Struts
安裝:
首先請到 http://jakarta.apache.org/Struts 下載 Struts ,建議使用 release 版,現在最高版本為 1.1 ,下載后得到的是一個 ZIP 文件。
ZIP包解開,可以看到這個目錄:lib和webapps,webapps下有一些WAR文件。假設你的Tomcat裝在c:Tomcat下,則將那些WAR文件拷貝到C:\Tomcat\webapps,重新啟動Tomcat即可。打開瀏覽器,在地址欄中輸入:http://localhost:8080/struts-example/index.jsp,若能見到“powered by Struts”的深藍色圖標,即說明成功了。 這是 Struts 自帶的一個例子,附有詳細的說明文檔,可以做為初學者的入門教程。另外, Struts 還提供了一系統實用對象: XML 處理、通過 Java reflection APIs 自動處理 JavaBeans 屬性、國際化的提示和消息等

一個實例:
一個用戶注冊系統,用戶通過網頁輸入相關信息:注冊 ID 號,密碼, EMAIL ,若注冊成功,則返回成功提示信息,反之出現注冊失敗提示信息。
以下是相關文件的部分核心代碼。

項目建立:
正式開發前,需要在 Tocmat (我的 tomcat 裝在 c:tomcat )中建立此項目。比較快的一種建立方式為:在 C:tomcatwebapps 下新建目錄 test ,再將 C:tomcatwebappsStruts-example 下的
WEB-INF
目錄拷貝到 test 目錄下,然后將 testWEB-INF 下的 src classes 目錄清空,以及 Struts-config.xml 文件中內容清空即可。這樣,我們需要的 Struts 類包及相關的配置文件就都齊了。
開發時,將JSP文件放在test目錄下,Java原文件放在testWEB-INFsrc下,編譯后的類文件放在testWEB-INFclasses下。

注冊頁面:reguser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/Struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/Struts-html.tld" prefix="html" %>
<html:html locale="ue">
<head>
<title>RegUser</title>
<html:base/>
</head>
<body bgcolor="white">
<html:errors/>
<html:form action="/regUserAction" focus="logname">
< border="0" width="100%">
<>
<th align="right">
Logname:
</th>
< align="left">
<html:text property="logname" size="20" maxlength="20"/>
</>
</>
<>
<th align="right">
Password:
</th>
< align="left">
<html:password property="password" size="20" maxlength="20"/>
</>
</>
<>
<th align="right">
E-mail:
</th>
< align="left">
<html:password property="email" size="30" maxlength="50"/>
</>
</>
<>
< align="right">
<html:submit property="submit" value="Submit"/>
</>
< align="left">
<html:reset/>
</>
</>
</>
</html:form>
</body>
</html:html>

此JSP頁面不同于普通的JSP頁,因為它大量運用了taglib,這些taglib對初學者而言,可能難于掌握,可這卻是Struts的精華之一。
靈活運用,將大大提高開發效率。

Struts-config.xml:

<Struts-config>
<form-beans>
<form-bean name="regUserForm"
type="org.cjea.Struts.example. RegUserForm "/>
</form-beans>
<action-mappings>
<action path="/regUserAction"
type=" org.cjea.Struts.example.RegUserAction "
atibute=" regUserForm "
scope="request"
validate="false">
<forward name="failure" path="/ messageFailure.jsp"/>
<forward name="success" path="/ messageSuccess.jsp"/>
</action>
</action-mappings>
</Struts-config>

Struts的核心是Conoller,即ActionServlet,而ActionServlet的核心就是Struts-config.xml,Struts-config.xml集中了所有頁面的導航定義。
對于大型的 WEB 項目,通過此配置文件即可迅速把握其脈絡,這不管是對于前期的開發,還是后期的維護或升級都是大有裨益的。掌握 Struts-config.xml 是掌握 Struts 的關鍵所在。

FormBean
RegUserForm

package org.cjea.Struts.example;

import javax.Servlet.http.HttpServletRequest;
import org.apache.Struts.action.ActionForm;
import org.apache.Struts.action.ActionMapping;

public final class RegUserForm extends ActionForm{

private Sing logname;
private Sing password;
private Sing email;

public RegUserForm(){
logname = null;
password = null;
email = null;
}

public Sing getLogName() {
return this.logname;
}
public void setLogName(Sing logname) {
this.logname = logname;
}
public void setPassWord(Sing password) {
this.password = password;
}
public Sing getPassWord() {
return this.password;
}
public void setEmail(Sing email) {
this.email = email;
}
public Sing getEmail() {
return this.email;
}

public void reset(ActionMapping mapping, HttpServletRequest request)
{
logname = null;
password = null;
email = null;
}
}

每一個 FormBean 都必須繼承 ActionForm 類, FormBean 是對頁面請求的封裝。即把 HTTP request 封裝在一個對象中,需要說明的一點就是多個 HTTP request 可以共用一個 FormBean ,便于維護和重用。

ActionBean:RegUserAction

package org.cjea.Struts.example;

import javax.Servlet.http.*;
import org.apache.Struts.action.*;

public final class RegUserAction extends Action
{

public ActionForward perform(ActionMapping mapping,
ActionForm form, HttpServletRequest req,
HttpServletResponse res)
{
Sing title = req.getParameter("title");
Sing password = req.getParameter("password");
Sing email = req.getParameter("email");
/*
取得用戶請求,做相應數據庫操作,略
*/
}
}

FormBean的產生是為了提供數據給ActionBean,在ActionBean中可以取得FormBean中封裝的數據,經相應的邏輯處理后,調用業務方法完成相應業務要求。

Servlet的演變:在常規的 JSP,Servlet,JavaBean三層結構中,JSP實現View的功能,Servlet實現Conoller的功能,JavaBean實現Model的實現。

在Struts中,將常規情況下的Servlet拆分與ActionServlet、FormBean、ActionBean三個部分。ActionServlet配合Struts-config.xml,專職完成頁面導航,而不再負責具體的數據獲取與相應邏輯,這兩部分功能由FormBean和ActionBean來完成。

Struts 優缺點
優點:
Struts
Tomcat Turbine 等諸多 Apache 項目一樣,是開源軟件,這是它的一大優點。使開發者能更深入的了解其內部實現機制。
除此之外, Struts 的優點主要集中體現在兩個方面: Taglib 和頁面導航。 Taglib Struts 的標記庫,靈活動用,能大大提高開發效率。另外,就目前國內的 JSP 開發者而言,除了使用 JSP 自帶的常用標記外,很少開發自己的標記,或許 Struts 是一個很好的起點。
關于頁面導航,我認為那將是今后的一個發展方向,事實上,這樣做,使系統的脈絡更加清晰。通過一個配置文件,即可把握整個系統各部分之間的聯系,這對于后期的維護有著莫大的好處。尤其是當另一批開發者接手這個項目時,這種優勢體現得更加明顯。
缺點:
Taglib
Struts 的一大優勢,但對于初學者而言,卻需要一個持續學習的過程,甚至還會打亂你網頁編寫的習慣,但是,當你習慣了它時,你會覺得它真的很棒。
Struts
MVC Conoller 一分為三,在獲得結構更加清晰的同時,也增加了系統的復雜度。
Struts
從產生到現在還不到半年,但已逐步越來越多運用于商業軟件。雖然它現在還有不少缺點,但它是一種非常優秀的 J2EE MVC 實現方式,如果你的系統準備采用 J2EE MVC 架構,那么,不妨考慮一下 Struts

Struts實施經驗:
1、基于Struts架構的項目開發,首先需要有一個很好的整體規劃,整個系統中包括哪幾個模塊,每個模塊各需要多少FormBean和ActionBean等,而且最好有專人負責Struts-config.xml的管理。
開發基于 Struts 的項目的難點在于配置管理,尤其是對 Struts-config.xml 的管理

2
、如果你的項目非常緊,并且項目組中又沒有富有經驗的 Struts 開發人員,建議不要冒然采用 Struts Struts 的掌握需要一個過程,對于一個熟練的 JSP 程序員,自學大概需要半個月左右的時間。如果結合 titls ,則需要更長的時間

3
、如果你在網頁中大量運用 taglib ,那么你的美工將做出部分犧牲。當你結合 Tiles ,功能增強的同時,這種犧牲尤為明顯。當然,你對功能和美觀的取舍由你自己決定

4
Taglib 是一個好東西,但靈活運用它卻需要一個過程,如果你不想在 Taglib 上花太多的時間,那么只需理解與 FORM 有關的幾個標記,其它的標記就放著吧,以后再看,先去研究 ActionServlet Struts-config.xml ,你會覺得很有成就感

5
Struts 是否只適合于大型項目呢? No Struts 適合于各種大小的項目,當然,對于大型項目,它所體現出來的優勢更加明顯。

?



小辭猬 2006-10-09 17:31 發表評論
]]>
J2ME程序開發新手入門九大要點http://www.tkk7.com/superwei/articles/28815.html小辭猬小辭猬Fri, 20 Jan 2006 09:41:00 GMThttp://www.tkk7.com/superwei/articles/28815.htmlhttp://www.tkk7.com/superwei/comments/28815.htmlhttp://www.tkk7.com/superwei/articles/28815.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/28815.htmlhttp://www.tkk7.com/superwei/services/trackbacks/28815.html J2ME程序開發新手入門九大要點

作者:佚名    來自:未知

  一、J2ME中需要的Java基礎知識

  現在有大部分人,都是從零開始學J2ME的,學習J2ME的時候,總是從Java基礎開始學習,而且現在講Java基礎的書籍中都是以J2SE來講基礎,這就給學習造成了一些不必要的麻煩,下面將J2ME中用到的和不需要的Java基礎知識做一個簡單的說明。

  J2ME中使用到的Java基礎知識:

   1、Java語法基礎:包括基本數據類型、關鍵字、運算符等等

   2、面向對象的思想:類和對象的概念,繼承和多態等等。

   3、異常處理

   4、多線程

  J2ME中沒有用到的Java基礎知識:

   1、JDK中javac和java命令的使用

   2、Java基礎中的很多類在J2ME中沒有,或者類中的方法做了大量的精簡。所以建議在J2ME中熟悉類庫。

   3、Applet、AWT、Swing這些知識在J2ME中根本使用不到。

  簡單說這么多,希望學J2ME的朋友們能少走一些彎路,不足之處希望大家積極指正和補充。

  二、J2ME中暫時無法完成的功能

  列一些J2ME中暫時無法完成的功能,希望大家能積極補充:

   1、在手機中不更改代碼實現移植,主要指游戲。

   2、動態修改按鈕文字。

   3、在Canvas上接受中文輸入。

   4、操作本地資源、例如地址本、已收短信息等。

   5、制作破壞性的手機病毒。

   6、其他等待大家來補充。

  三、J2ME的跨平臺性

  J2ME技術源于Java,所以也具有JVM的優勢,可以在支持Java的平臺上進行移植,但是現在的J2ME技術在跨平臺上卻做的很糟糕,我們來簡單看一下原因:

  1、手機的屏幕尺寸不一:

  這個主要在界面制作上。如果你使用的是高級用戶界面,比如你做的是應用開發或者用戶登陸、用戶注冊這樣的通用功能時,一般沒有什么問題。

  如果你使用的是低級用戶界面,比如你做的是游戲,那么你就需要考慮這個問題了。

  2、廠商的擴展API不統一:

  例如Nokia的擴展API類庫UI系列,在別的手機上或者沒有實現,或者包名不同等等。

  3、手機平臺上實現的bug:

  例如Nokia的7650在實現雙緩沖上有bug,那么在這種機型上運行的軟件就不能使用雙緩沖。其他NOKIA上的一些bug,可以參看:http://blog.csdn.net/Mailbomb/archive/2005/03/24/329123.aspx

  4、手機性能問題。

  不同手機的可用內存、最大jar文件都有要求,例如Nokia S40的大部分手機支持的最大jar文件為64K,最大可用內容為210K。

  所以現在的手機軟件,特別是游戲都提供支持的機型列表,也才有了手機游戲移植人員的存在。

  四、學習J2ME可以從事的工作種類

  現在J2ME技術可以說相當的火暴,這里介紹一些學好了J2ME之后可以從事的工作的種類:

  1、J2ME游戲開發人員

  根據游戲策劃或者文檔要求,在某種特定的機型(以Nokia S40或S60居多)開發游戲程序。這是現在大部分J2ME程序員從事的工作。

  需要熟練掌握:高級用戶界面、低級用戶界面、線程,如果是網絡游戲,還需要熟練網絡編程。

  2、J2ME應用開發人員

  現在的移動應用還不是很多,但是還是出現了一些,特別是移動定位以及移動商務相關的內容。需要熟練掌握:高級用戶界面、線程和網絡編程。

  3、J2ME游戲移植人員

  參照源代碼,將可以在一個平臺上可以運行的游戲移植到其他平臺上去。例如將Nokia S40的游戲移植到S60上,或者索愛的T618等等。主要是控制屏幕坐標,有些可能需要替換一些API。

  需要熟悉各平臺之間的差異以及相關的技術參數,比如屏幕大小、最大jar文件尺寸等等。

  五、J2ME程序設計的幾個原則

  1、使用面向對象編程。

  雖然使用面向過程編程可以減小文件的尺寸,但是為了以后維護的方便和利于擴展,還是要使用面向對象編程。

  2、使用MVC模式

  將模型、界面和控制分離。現在很多的程序將三者合一,但是如果你做的程序比較大的話,還是建議你進行分離。

  3、自動存儲用戶設定

  使用RMS來存儲用戶的信息,例如存儲用戶上次輸入的用戶名、密碼、用戶對于系統的設定等,這樣不僅可以減少用戶的輸入,而且對用戶友好。很多程序甚至做了自動登陸等。

  4、一些系統設置允許用戶關閉。如背景音樂、背景燈顯示等。

  5、將低級用戶界面的繪制動作放在一個獨立的線程里面去。

  6、在需要大量時間才能完成的工作時,給用戶一個等待界面。

  六、從模擬器到真機測試

  對于J2ME開發者來說,模擬器給我們帶來了很多方便,比如可以在模擬器中調試程序以及很方便的察看程序的效果,但是模擬器也給我們帶來了一些問題,比如模擬器實現的bug等等,所以進行真機測試是必須的。

  1、為什么要進行真機測試?

  因為模擬器程序可能存在bug,以及真機的性能有限,所以必須進行真機測試。

  2、如何將程序傳輸到機器中?

  將程序傳輸到機器中有如下方式:

   a) OTA下載
   b) 使用數據線傳輸
   c) 紅外傳輸
   d) 藍牙

  你可以根據條件,選擇合適的方式。

  3、 真機測試主要測什么?

  真機測試的內容很多,主要測試以下幾個方面:

   a) 程序的功能
   b) 程序的操作性,是否易操作
   c) 程序的大小,比如Nokia S40系列的手機大部分接受的最大文件尺寸為64K
   d) 程序運行速度,速度是否可以忍受。

  七、從WTK到廠商SDK

  對于J2ME愛好者來說,基本上大家都是從SUN的WTK(J2ME Wireless Toolkit)開始的,但是對于實際應用來說,僅僅使用WTK是遠遠不夠的,所以在學習過程中,必須完成從WTK到SDK的跨越。

  1、廠商SDK的下載地址?

  ·Nokia
  Nokia不愧為手機行業的老大,對于j2me的支持也是一流的,有專門的網站提供SDK和各種文檔說明。
  網址是:http://forum.nokia.com.cn/sch/index.html

  ·Siemens
  Siemens對于J2ME的支持也不錯,它提供了SDK,模擬器需要獨立安裝。下載地址如下:
  https://communication-market.siemens.de/portal/main.aspx?LangID=0&MainMenuID=2&LeftID=2&pid=1&cid=0&tid=3000&xid=0

  ·SonyEricsson
  SonyEricsson SDK以及自己的模擬器,下載地址為:
  http://developer.sonyericsson.com/site/global/docstools/java/p_java.jsp
  http://mobilityworld.ericsson.com.cn/development/download_hit.asp

  ·Motorola
  Motorola提供了專門的SDK,內部包含模擬器,下載地址為:
  http://www.motocoder.com/motorola/pcsHome.jsp

  ·SamSung
  SamSung也提供了專門的SDK和模擬器,下載地址為:
  http://developer.samsungmobile.com/eng/front_zone/bbs/bbs_main.jsp?p_menu_id=1500

  ·NEC:
  NEC也提供了集成模擬器的SDK,下載地址為:
  http://www.nec-mfriend.com/cn

  2、廠商SDK和WTK有什么不同?

  廠商SDK最簡單的理解就是在WTK的基礎上增加了自己的模擬器和自己的擴展API。也就是說,你在使用廠商的SDK時,可以使用廠商的擴展類庫,例如Nokia的UI類庫,和廠商自己的模擬器而已。每個廠商的擴展API都不多,而且不盡相同。

  3、如何使用?

  有些廠商SDK的使用都和WTK相同,例如SamSung。Nokia提供了獨立的界面來開發,但是這個界面在實際開發中使用不多。

  4、廠商SDK的問題

  廠商SDK實現過程中,有一些bug,而且和真機實現不一致。例如NOKIA的混音播放問題等等。

  八、在J2ME中獲得手機IMEI的方法

  IMEI是Internation mobile entity identification的簡稱,在手機中輸入*#06#可以顯示該數字,長度為15位,全球唯一,永遠不會沖突,所以可以作為識別用戶的一個標志。

  下面是在J2ME中獲得IMEI的方法:

  1、MOTO系列的手機可以通過讀取系統的IMEI屬性獲得,代碼如下:

   String imei = System.getProperty("IMEI");

  2、SIEMENS系列的手機可以通過讀取系統的com.siemens.IMEI屬性獲得,代碼如下:

   String imei = System.getProperty("com.siemens.IMEI");

  九、J2ME網絡連接中顯示問題的解決辦法

  在網絡編程中,有些時候會出現一些在沒有接收到網絡數據就顯示界面的,造成界面顯示不符合要求(例如公告顯示,會先顯示公告的背景圖片再顯示公告信息),這里提一個簡單的解決辦法給大家:

  解決這種情況的方法分成三個步驟:

  1、在需要顯示的界面中,調用發送網絡數據的方法。每次顯示時調用該構造方法,不調用Display的setCurrent方法顯示。

  2、顯示等待界面(例如進度條等),給用戶提示,在進行網絡連接。

  3、在處理網絡反饋的數據完以后,調用Display的setCurrent方法顯示顯示當前界面。



小辭猬 2006-01-20 17:41 發表評論
]]>
面向對象的思維方法http://www.tkk7.com/superwei/articles/21657.html小辭猬小辭猬Mon, 28 Nov 2005 05:19:00 GMThttp://www.tkk7.com/superwei/articles/21657.htmlhttp://www.tkk7.com/superwei/comments/21657.htmlhttp://www.tkk7.com/superwei/articles/21657.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/21657.htmlhttp://www.tkk7.com/superwei/services/trackbacks/21657.html作者:范凱
E-mail: robbin_fan@yahoo.com.cn

我是從學習Java編程開始接觸OOP(面向對象編程),剛開始使用Java編寫程序的時候感覺很別扭,因為我早以習慣用C來編寫程序,很欣賞C的簡潔性和高效性,喜歡C簡練而表達能力豐富的風格,特別忍受不了Java運行起來慢吞吞的速度,相對冗長的代碼,而且一個很簡單的事情,要寫好多類,一個類調用一個類,心里的抵觸情緒很強。

我對Java的面向對象的特性琢磨良久,自認為有所領悟,也開始有意識的運用OOP風格來寫程序,然而還是經常會覺得不知道應該怎樣提煉類,面對一個具體的問題的時候,會覺得腦子里千頭萬緒的,不知道怎么下手,一不小心,又會回到原來的思路上去。

舉個例子,要發廣告郵件,廣告郵件列表存在數據庫里面。倘若用C來寫的話,一般會這樣思考,先把郵件內容讀入,然后連接數據庫,循環取郵件地址,調用本機的qmail的sendmail命令發送。

然后考慮用Java來實現,既然是OOP,就不能什么代碼都塞到main過程里面,于是就設計了三個類:

一個類是負責讀取數據庫,取郵件地址,調用qmail的sendmail命令發送;
一個類是讀郵件內容,MIME編碼成HTML格式的,再加上郵件頭;
一個主類負責從命令讀參數,處理命令行參數,調用發email的類。

把一件工作按照功能劃分為3個模塊分別處理,每個類完成一件模塊任務。

仔細的分析一下,就會發現這樣的設計完全是從程序員實現程序功能的角度來設計的,或者說,設計類的時候,是自低向上的,從機器的角度到現實世界的角度來分析問題的。因此在設計的時候,就已經把程序編程實現的細節都考慮進去了,企圖從底層實現程序這樣的出發點來達到滿足現實世界的軟件需求的目標。

這樣的分析方法其實是不適用于Java這樣面向對象的編程語言,因為,如果改用C語言,封裝兩個C函數,都會比Java實現起來輕松的多,邏輯上也清楚的多。

我覺得面向對象的精髓在于考慮問題的思路是從現實世界的人類思維習慣出發的,只要領會了這一點,就領會了面向對象的思維方法。

舉一個非常簡單的例子:假使現在需要寫一個網頁計數器,客戶訪問一次頁面,網頁計數器加1,計數器是這樣來訪問的

http://hostname/count.cgi?id=xxx

后臺有一個數據庫表,保存每個id(一個id對應一個被統計訪問次數的頁面)的計數器當前值,請求頁面一次,對應id的計數器的字段加1(這里我們忽略并發更新數據庫表,出現的表鎖定的問題)。

如果按照一般從程序實現的角度來分析,我們會這樣考慮:首先是從HTTP GET請求取到id,然后按照id查數據庫表,獲得某id對應的訪問計數值,然后加1,更新數據庫,最后向頁面顯示訪問計數。

現在假設一個沒有程序設計經驗的人,他會怎樣來思考這個問題的呢?他會提出什么樣的需求呢?他很可能會這樣想:

我需要有一個計數器,這個計數器應該有這樣的功能,刷新一次頁面,訪問量就會加1,另外最好還有一個計數器清0的功能,當然計數器如果有一個可以設為任意值的功能的話,我就可以作弊了。

做為一個沒有程序設計經驗的人來說,他完全不會想到對數據庫應該如何操作,對于HTTP變量該如何傳遞,他考慮問題的角度就是我有什么需求,我的業務邏輯是什么,軟件應該有什么功能。

按照這樣的思路(請注意,他的思路其實就是我們平時在生活中習慣的思維方式),我們知道需要有一個計數器類 Counter,有一個必須的和兩個可選的方法:

getCount() // 取計數器值方法
resetCounter() // 計數器清0方法
setCount() // 設計數器為相應的值方法

把Counter類完整的定義如下:

public class Counter {
public int getCount(int id) {}
public void resetCounter(int id) {}
public void setCount(int id, int currentCount) {}
}

解決問題的框架已經有了,來看一下如何使用Counter。 在count.cgi里面調用Counter來計數,程序片斷如下:

// 這里從HTTP環境里面取id值
...
Counter myCounter = new Counter(); // 獲得計數器
int currentCount = myCounter.getCount(id); // 從計數器中取計數
// 這里向客戶瀏覽器輸出
...

程序的框架全都寫好了,剩下的就是實現Counter類方法里面具體的代碼了,此時才去考慮具體的程序語言實現的細節,比如,在getCount()方法里面訪問數據庫,更新計數值。

從上面的例子中看到,面向對象的思維方法其實就是我們在現實生活中習慣的思維方式,是從人類考慮問題的角度出發,把人類解決問題的思維方式逐步翻譯成程序能夠理解的思維方式的過程,在這個翻譯的過程中,軟件也就逐步被設計好了。

在運用面向對象的思維方法進行軟件設計的過程中,最容易犯的錯誤就是開始分析的時候,就想到了程序代碼實現的細節,因此封裝的類完全是基于程序實現邏輯,而不是基于解決問題的業務邏輯。

學習JDBC編程的經典錯誤問法是:“我怎樣封裝對數據庫的select操作?”

面向對象的設計是基于解決業務問題的設計,而不是基于具體編程技術的設計。我不會去封裝select語句的,我只封裝解決問題的業務邏輯,對數據庫的讀取是在業務邏輯的編碼實現階段才去考慮的問題。

回過頭看上面那個發廣告郵件的例子,應該如何應用面向對象的思維方法呢?

對于一個郵件來說,有郵件頭,郵件體,和郵件地址這三個屬性,發送郵件,需要一個發送的方法,另外還需要一個能把所有郵件地址列出來的方法。所以應該如下設計:

類JunkMail

屬性:
head
body
address
方法:
sendMail() // 發送郵件
listAllMail() // 列郵件地址

用Java來表示:

public class JunkMail {
private String head;
private String body;
private String address;
public JunkMain() { // 默認的類構造器
// 從外部配置文件讀郵件頭和郵件體
this.head=...;
this.body=...;
}

public static boolean sendMail(String address) {
// 調用qmail,發送email
}

public static Collection listAllMail() {
// 訪問數據庫,返回一個郵件地址集合
}
}

當把JunkMail設計好了以后,再調用JunkMail類完成郵件的發送,將是非常輕松的事情。

如果說傳統的面向過程的編程是符合機器運行指令的流程的話,那么面向對象的思維方法就是符合現實生活中人類解決問題的思維過程。

在面向對象的軟件分析和設計的時候,要提醒自己,不要一上來就去想程序代碼的實現,應該拋開具體編程語言的束縛,集中精力分析我們要實現的軟件的業務邏輯,分析軟件的業務流程,思考應該如何去描述和實現軟件的業務。畢竟軟件只是一個載體,業務才是我們真正要實現的目標。

但是在設計過程中,心里卻往往在擔心,如果我完全不去考慮程序代碼的實現的話,那么我怎么知道我的設計一定合理呢?我怎么知道我設計的類、接口一定可以實現呢?所以經常可以看到的現象就是:

在設計過程中,雖然知道不能過早考慮代碼實現,但是每設計一個類,一個接口,心里都要不知不覺的用自己熟悉的編程語言大概的評估一下,看看能否編出來,因此,一不小心,就會又回到按照程序功能實現的思路進行設計的老路上去了。

舉個例子來說明,在做Web程序設計的時候,經常要遇到分頁顯示數據的情況。比如說需要把系統中所有的用戶都列出來這樣的功能。假設使用User類來表示用戶,增加用戶addUser(),刪除用戶deleteUser(),查詢所有用戶listUsers()方法。而數據庫中有一個user表,一條記錄是一個用戶的信息。下面考慮一下User類的方法的實現:

addUser()和deleteUser()方法都好實現,就是對數據庫增加記錄和刪除記錄。對于listUsers()方法,其實就是對user表的select,取出一個記錄集。但是該怎么從listUsers()方法中得到所有用戶的列表呢?

一個方法調用的返回值只有一個,沒有多個,所以很多情況下采用的辦法就是返回值定義為集合類型,比如Vector。這樣就可以在listUsers()方法的具體代碼實現的時候,從數據庫依次取出一個個記錄,插入到Vector里面來。在主程序里面,調用listUsers()方法可以返回一個Vector,然后再對Vector遍歷操作,就可以得到用戶列表了。

public class User {

public static void addUser(...) {
// 數據庫insert一條記錄
}

public static void deleteUser(...) {
// 數據庫delete一條記錄
}

public Vector listUsers(...) {
// 數據庫select結果放到一個集合里面
}
}

這樣的設計基本合理,但是仍然有點小問題。因為在設計的時候,就考慮到了用Java的集合類Vector來實現對不定長數據集的存放,因而違反了面向對象設計的一個原則:在設計的時候不應過早的考慮具體程序語言的實現。所以必須用抽象的方法,和具體實現無關的方法來表達業務邏輯。

我們知道,通常對具有集合特征的數據結構進行遍歷通常可以使用next和hasNext方法,next實現取下一個用戶,hasNext判斷是否還有元素。 因此我們定義一個接口Iterator,這個接口中定義兩個方法next和hasNext:

public interface Iterator {
public boolean hasNext() {}
public Object next() {}
}

而User類的listUses方法返回值改為Iterator接口的實現類:

public class User {
...
public Iterator listUsers() {
}
...
}

這樣就把User類的設計和具體的實現方法分離開了,因為此時任何實現了next()和hasNext()方法的類都可以做為listUsers的返回值,都可以被用來表達“用戶列表”,而不僅僅可以使用Vector而已。比如,我可以用ArrayList來表達用戶列表,因為ArrayList也實現了Iterator,當然我也可以自己專門寫一個類來存放用戶列表,只要實現next()和hasNext()方法就行了。

這樣在具體的編寫代碼的時候,程序員具有了最大的靈活性,可以根據具體的情況,采用不同的編程方法來存放用戶列表。特別是降低了程序的耦合度,提高了程序的可移植性。對于上面那個JunkMail的listAllMail()方法也同樣應該改為接口類型。

然后,在主程序里面就這樣來使用User類的listUsers方法:

User myUser = new User();
Iterator iterator = myUser.listUsers();
while (iterator.hasNext()) {
iterator.next();
}

這樣就可以完全不用考慮程序代碼實現了,從高層次上把功能抽象出來,定義成為接口,同時又可以把系統設計的很合理,完全根據業務的需求來進行設計。

結語

通過上面的幾個例子的設計說明,使用面向對象的思維方法,其實是一個把業務邏輯從具體的編程技術當中抽象出來的過程,而這個抽象的過程是自上而下的,非常符合人類的思維習慣,也就是先不考慮問題解決的細節,把問題的最主要的方面抽象成為一個簡單的框架,集中精力思考如何解決主要矛盾,然后在解決問題的過程中,再把問題的細節分割成一個一個小問題,再專門去解決細節問題。

因而一旦牢牢的抓住了這一點,你就會發現在軟件設計和開發過程中,你自己總是會不知不覺的運用面向對象的思維方法來設計和編寫程序,并且程序的設計和開發也變得不再那么枯燥,而一個合理運用面向對象技術進行設計和架構的軟件,更是具備了思維的藝術美感。

最后,愿面向對象的思維方法也能給您的程序設計之路帶來創作的樂趣。

小辭猬 2005-11-28 13:19 發表評論
]]>
字符串中的正則表達式特殊符號 http://www.tkk7.com/superwei/articles/17523.html小辭猬小辭猬Mon, 31 Oct 2005 03:40:00 GMThttp://www.tkk7.com/superwei/articles/17523.htmlhttp://www.tkk7.com/superwei/comments/17523.htmlhttp://www.tkk7.com/superwei/articles/17523.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17523.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17523.html字符串中的正則表達式特殊符號

雙面提供 時時整理

問題:
String s1="111+222+333";
System.out.println(s1.split("+").length);
//輸出時提示錯誤:
java.util.regex.PatternSyntaxException: Dangling meta character '+' near index
問題出現在加號附近,查詢相關的資料顯示,+、*、|、\等符號在正則表達示中有相應的不同意義。

正則表達式的基本用法 zt
1、“.”為通配符,表示任何一個字符,例如:“a.c”可以匹配“anc”、“abc”、“acc”;
2、“[]”,在[]內可以指定要求匹配的字符,例如:“a[nbc]c”可以匹配“anc”、“abc”、“acc;
但不可以匹配“ancc”,a到z可以寫成[a-z],0到9可以寫成[0-9];

3、數量限定符號,表示匹配次數(或者叫做長度)的符號:

包括:“*”——0次或者多次
      “+”——1次或者多次
      “?”——0次或者1次
      “{n}”——匹配n次,n為整數
      “{n,m}”——匹配從n到m之間的某個數的次數;n和m都是整數;
      “{n,}”——匹配n到無窮次之間任意次數;
      “{,m}”——匹配0到m之間任意次數;
他們放到匹配格式的后面:
例如:
電話號碼:024-84820482,02484820482(假設前面3或者4位,后面7或者8位,并且中間的減號可有可無)

都是符合規定的,那么可以用如下格式來匹配:[0-9]{3,4} \-? [0-9]{7,8};
注意:“\”為轉義字符,因為“-”在正則表達式用有代表一個范圍的意義,例如:前面所說的[0-9],
所以它需要轉義字符“\”進行轉義才可使用;

4、“^”為否符號,表示不想匹配的符號,例如:[^z][a-z]+可以匹配所有除“z”開頭的以外的所有字

符串(長度大于2,因為“+”表示大于等于1的次數,從第二位開始都是小寫英文字符);
如果^放到[]的外邊則表示以[]開頭的字符串;^[az][a-z]+表示a或者z開頭的長度大于等于2的英文字符串;

5、“|”或運算符,例如:a[n|bc|cb]c可以匹配“abcc”,“anc”,“acbc”;
6、“$”以它前面的字符結尾的;例如:ab+$就可以被“abb”,“ab”匹配;

7、一些簡單表示方法:
\d表示[0-9];\D表示[^0-9];\w表示[A-Z0-9];\W表示[^A-Z0-9];\s表示[\t\n\r\f],就是空格字符包括tab,空格等等;\S表示[^\t\n\r\f],就是非空格字符;


明白了這些以后,我們再返回頭看看它們如何被運用呢?一般來講只需要加[]、或是\\即可。

舉例來講:
String s1="111+222+333";
System.out.println(s1.split("[+]").length);
或是
String s1="111+222+333";
System.out.println(s1.split("\\+").length);

其他用法類同。



小辭猬 2005-10-31 11:40 發表評論
]]>
Hibernate的原理與配置快速入門(4)http://www.tkk7.com/superwei/articles/17520.html小辭猬小辭猬Mon, 31 Oct 2005 03:31:00 GMThttp://www.tkk7.com/superwei/articles/17520.htmlhttp://www.tkk7.com/superwei/comments/17520.htmlhttp://www.tkk7.com/superwei/articles/17520.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17520.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17520.html創建一個SessionFactory對象

  為了能創建一個SessionFactory對象,你必須在Hibernate初始化時創建一個Configuration類的實例,并將已寫好的映射文件交由它處理。這樣,Configuration對象就可以創建一個SessionFactory對象,當SessionFactory對象創建成功后,Configuration對象就沒有用了,你可以簡單地拋棄它。如下是示例代碼:

Configuration cfg = new Configuration();
cfg.addResource("hello/Message.hbm.xml");
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();

  在以上代碼中,Message.hb.xml這個映射文件的位置比較特殊,它與當前的classpath相關。例如classpath包含當前目錄,那在上述代碼中的Message.hbm.xml映射文件就可以保存在當前目錄下的hello目錄中。

  作為一種約定,Hibernate的映射文件默認以.htm.xml作為其擴展名。另一個約定是堅持為每一個持久類寫一個配置文件,想一想如果你將所有持久類的映射寫入一個單獨的配置文件中的話,那這個配置文件肯定非常龐大,不易維護。但這里又出現了一個新問題:如果為每個類寫一個配置文件的話,這么多的配置文件應該存放在哪里呢?

  Hibernate推薦你將每個映射文件保存在與持久類相同的目錄下,并且與持久類同名。例如我們第一個示例程序中的Message持久類放在hello目錄下,那你必須在這個目錄下存放名為Message.hbm.xml的映射文件。這樣一個持久類都有自己的一個映射文件,避免了出現像struts項目中的“struts-config.xml地獄”的情況。如果你不遵循這種規定,那你必須手動地用addResource()方法將一個個的映射文件載入;但你如果遵循這種規定,那你可以方便地用addClass()方法同時將持久類和它的映射文件載入,以下是體現這種便利性的示例代碼:

SessionFactory sessions = new Configuration()
.addClass(org.hibernate.auction.model.Item.class)
.addClass(org.hibernate.auction.model.Category.class)
.addClass(org.hibernate.auction.model.Bid.class)
.setProperties( System.getProperties() )
.buildSessionFactory();

  當然,Hibernate的映射文件還有很多其它的配置選項,比如數據庫連接的設定,或是能夠改變Hibernate運行時行為的一些設定。所有的設置可能是非常龐雜的,足以讓你喘不過氣來,但是不必擔心,因為Hibernate為絕大多數值都設定了一個合理缺省值,你只需要修改這些配置文件中的極小一部分值。

  你可以通過以下幾種方式來修改Hibernate的系統配置參數:

  · 將一個Java.util.Properties實例作為參數傳給Configuration類的setProperties()方法。

  · 在Hibernate啟動時用Java –Dproperty=value的方式設置值。

  · 在classpath可以找到的路徑下創建一個名為hibernate.properties的配置文件。

  · 在classpath可以找到的路徑下創建一個名為hibernate.cfg.xml的文件,并在其<property>標簽中定義屬性值。

  以上就是對Hibernate的一個大致介紹,如果你想知道得更多,那本文還是遠遠不夠的,我將陸續推出更多關于Hibernate的資料。但有一點是毫無疑問的:它的確是一個非常優秀的持久層解決方案!

小辭猬 2005-10-31 11:31 發表評論
]]>
Hibernate的原理與配置快速入門(3)http://www.tkk7.com/superwei/articles/17519.html小辭猬小辭猬Mon, 31 Oct 2005 03:31:00 GMThttp://www.tkk7.com/superwei/articles/17519.htmlhttp://www.tkk7.com/superwei/comments/17519.htmlhttp://www.tkk7.com/superwei/articles/17519.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17519.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17519.html一個重要的術語:Type

  Hibernate的設計者們發明了一個術語:Type,它在整個構架中是一個非常基礎、有著強大功能的元素。一個Type對象能將一個Java類型映射到數據庫中一個表的字段中去(實際上,它可以映射到表的多個字段中去)。持久類的所有屬性都對應一個type。這種設計思想使用Hibernate有著高度的靈活性和擴展性。

  Hibernate內置很多type類型,幾乎包括所有的Java基本類型,例如Java.util.Currency、Java.util.calendar、byte[]和Java.io.Serializable。

  不僅如此,Hibernate還支持用戶自定義的type,通過實現接口UserType和接口CompositeUserType,你可以加入自己的type。你可以利用這種特色讓你的項目中使用自定義的諸如Address、Name這樣的type,這樣你就可以獲得更大的便利,讓你的代碼更優雅。自定義type在Hibernate中是一項核心特色,它的設計者鼓勵你多多使用它來創建一個靈活、優雅的項目!

  策略接口

  Hibernate與某些其它開源軟件不同的還有一點――高度的可擴展性,這通過它的內置策略機制來實現。當你感覺到Hibernate的某些功能不足,或者有某些缺陷時,你可以開發一個自己的策略來替換它,而你所要做的僅僅只是繼承它的某個策略接口,然后實現你的新策略就可以了,以下是它的策略接口:

  · 主鍵的生成 (IdentifierGenerator 接口)

  · 本地SQL語言支持 (Dialect 抽象類)

  · 緩沖機制 (Cache 和CacheProvider 接口)

  · JDBC 連接管理 (ConnectionProvider接口)

  · 事務管理 (TransactionFactory, Transaction, 和 TransactionManagerLookup 接口)

  · ORM 策略 (ClassPersister 接口)

  · 屬性訪問策略 (PropertyAccessor 接口)

  · 代理對象的創建 (ProxyFactory接口)

  Hibernate為以上所列的機制分別創建了一個缺省的實現,因此如果你只是要增強它的某個策略的功能的話,只需簡單地繼承這個類就可以了,沒有必要從頭開始寫代碼。

  以上就是Hibernate的一些核心接口,但當我們真正開始用它進行開發時,你的腦海里可能總會有一個疑問:我是通過什么方式,并從哪里取得Session的呢?以下我們就解答這個問題。

  基礎配置

  現在回顧一下我們先前的內容:我們寫出了一個示例程序,并簡要地講解了Hibernate的一些核心類。但要真正使你的項目運行起來,還有一件事必須要做:配置。Hibernate可以配置成可在任何Java環境中運行,一般說來,它通常被用在2-3層的C/S模式的項目中,并被部署在服務端。在這種項目中,Web瀏覽器、或Java GUI程序充當者客戶端。盡管我們的焦點主要是集中在多層web應用,但實際上在一些基于命令行的應用中也可以使用Hibernate。并且,對Hibernate的配置在不同的環境下都會不同,Hibernate運行在兩種環境下:可管理環境和不可管理環境

  · 可管理環境――這種環境可管理如下資源:池資源管理,諸如數據庫連接池和,還有事務管理、安全定義。一些典型的J2EE服務器(JBoss、Weblogic、WebSphere)已經實現了這些。

  · 不可管理環境――只是提供了一些基本的功能,諸如像Jetty或Tomcat這樣的servlet容器環境。一個普通的Java桌面應用或命令行程序也可以認為是處于這種環境下。這種環境不能提供自動事務處理、資源管理或安全管理,這些都必須由應用程序自己來定義。

  Hibernate的設計者們將這兩種環境設計了一個統一的抽象界面,因此對于開發者來說只有一種環境:可管理環境。如果實際項目是建立在諸如Tomcat這類不可管理的環境中時,那Hibernate將會使用它自己的事務處理代碼和JDBC連接池,使其變為一個可管理環境。
對于可管理的環境而言,Hibernate會將自己集成在這種環境中。對于開發者而言,你所要做的工作非常簡單:只需從一個Configuration類中創建一個SessionFactory類就可以了。

小辭猬 2005-10-31 11:31 發表評論
]]>
Hibernate的原理與配置快速入門(2)http://www.tkk7.com/superwei/articles/17518.html小辭猬小辭猬Mon, 31 Oct 2005 03:30:00 GMThttp://www.tkk7.com/superwei/articles/17518.htmlhttp://www.tkk7.com/superwei/comments/17518.htmlhttp://www.tkk7.com/superwei/articles/17518.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17518.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17518.html  理解Hibernate的架構

  當你想用Hibernate開發自己的基于持久層的應用時,第一件事情應當是熟悉它的編程接口。Hibernate的API接口設計得盡量簡潔明了,以方便開發人員。然而實際上由于ORM的復雜性,它的API一般都不可能設計得很簡單。但是別擔心,你沒有必要一下子了解所有的Hibernate的API接口。下面這張圖描述了Hibernate在應用層和持久層中的一些重要的接口類:

  在上圖中,我們將應用層放在了持久層的上部,實際上在傳統的項目中,應用層充當著持久層的一個客戶端角色。但對于一些簡單的項目來說,應用層和持久層并沒有區分得那么清楚,這也沒什么,在這種情況下你可以將應用層和持久層合并成了一層。

  在上圖中,Hibernate的接口大致可以分為以下幾種類型:

  · 一些被用戶的應用程序調用的,用來完成基本的創建、讀取、更新、刪除操作以及查詢操作的接口。這些接口是Hibernate實現用戶程序的商業邏輯的主要接口,它們包括Session、Transaction和Query。

  · Hibernate用來讀取諸如映射表這類配置文件的接口,典型的代表有Configuration類。

  · 回調(Callback)接口。它允許應用程序能對一些事件的發生作出相應的操作,例如Interceptor、Lifecycle和Validatable都是這一類接口。

  · 一些可以用來擴展Hibernate的映射機制的接口,例如UserType、CompositeUserType和IdentifierGenerator。這些接口可由用戶程序來實現(如果有必要)。

  Hibernate使用了J2EE架構中的如下技術:JDBC、JTA、JNDI。其中JDBC是一個支持關系數據庫操作的一個基礎層;它與JNDI和JTA一起結合,使得Hibernate可以方便地集成到J2EE應用服務器中去。

  在這里,我們不會詳細地去討論Hibernate API接口中的所有方法,我們只簡要講一下每個主要接口的功能,如果你想了解得更多的話,你可以在Hibernate的源碼包中的net.sf.hibernate子包中去查看這些接口的源代碼。下面我們依次講一下所有的主要接口:

  核心接口

  以下5個核心接口幾乎在任何實際開發中都會用到。通過這些接口,你不僅可以存儲和獲得持久對象,并且能夠進行事務控制。

  Session接口

  Session接口對于Hibernate 開發人員來說是一個最重要的接口。然而在Hibernate中,實例化的Session是一個輕量級的類,創建和銷毀它都不會占用很多資源。這在實際項目中確實很重要,因為在客戶程序中,可能會不斷地創建以及銷毀Session對象,如果Session的開銷太大,會給系統帶來不良影響。但值得注意的是Session對象是非線程安全的,因此在你的設計中,最好是一個線程只創建一個Session對象。

  在Hibernate的設計者的頭腦中,他們將session看作介于數據連接與事務管理一種中間接口。我們可以將session想象成一個持久對象的緩沖區,Hibernate能檢測到這些持久對象的改變,并及時刷新數據庫。我們有時也稱Session是一個持久層管理器,因為它包含這一些持久層相關的操作,諸如存儲持久對象至數據庫,以及從數據庫從獲得它們。請注意,Hibernate 的session不同于JSP應用中的HttpSession。當我們使用session這個術語時,我們指的是Hibernate中的session,而我們以后會將HttpSesion對象稱為用戶session。

  SessionFactory 接口

  這里用到了一個設計模式――工廠模式,用戶程序從工廠類SessionFactory中取得Session的實例。

  令你感到奇怪的是SessionFactory并不是輕量級的!實際上它的設計者的意圖是讓它能在整個應用中共享。典型地來說,一個項目通常只需要一個SessionFactory就夠了,但是當你的項目要操作多個數據庫時,那你必須為每個數據庫指定一個SessionFactory。
SessionFactory在Hibernate中實際起到了一個緩沖區的作用,它緩沖了Hibernate自動生成的SQL語句和一些其它的映射數據,還緩沖了一些將來有可能重復利用的數據。

  Configuration 接口

  Configuration接口的作用是對Hibernate進行配置,以及對它進行啟動。在Hibernate的啟動過程中,Configuration類的實例首先定位映射文檔的位置,讀取這些配置,然后創建一個SessionFactory對象。

  雖然Configuration接口在整個Hibernate項目中只扮演著一個很小的角色,但它是啟動hibernate時你所遇到的每一個對象。

  Transaction 接口

  Transaction接口是一個可選的API,你可以選擇不使用這個接口,取而代之的是Hibernate的設計者自己寫的底層事務處理代碼。 Transaction接口是對實際事務實現的一個抽象,這些實現包括JDBC的事務、JTA中的UserTransaction、甚至可以是CORBA事務。之所以這樣設計是能讓開發者能夠使用一個統一事務的操作界面,使得自己的項目可以在不同的環境和容器之間方便地移值。

  Query和Criteria接口

  Query接口讓你方便地對數據庫及持久對象進行查詢,它可以有兩種表達方式:HQL語言或本地數據庫的SQL語句。Query經常被用來綁定查詢參數、限制查詢記錄數量,并最終執行查詢操作。

  Criteria接口與Query接口非常類似,它允許你創建并執行面向對象的標準化查詢。

  值得注意的是Query接口也是輕量級的,它不能在Session之外使用。

  Callback 接口

  當一些有用的事件發生時――例如持久對象的載入、存儲、刪除時,Callback接口會通知Hibernate去接收一個通知消息。一般而言,Callback接口在用戶程序中并不是必須的,但你要在你的項目中創建審計日志時,你可能會用到它。



小辭猬 2005-10-31 11:30 發表評論
]]>
Hibernate的原理與配置快速入門(1)http://www.tkk7.com/superwei/articles/17517.html小辭猬小辭猬Mon, 31 Oct 2005 03:29:00 GMThttp://www.tkk7.com/superwei/articles/17517.htmlhttp://www.tkk7.com/superwei/comments/17517.htmlhttp://www.tkk7.com/superwei/articles/17517.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17517.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17517.html
  看完本文后,我相信你對什么是ORM(對像/關系映射)以及它的優點會有一個深刻的認識,我們先通過一個簡單的例子開始來展現它的威力。

  正如一些傳統的經典計算機文章大都會通過一個“hello,world”的例子開始講解一樣,我們也不例外,我們也將從一個相對簡單的例子來闡述Hibernate的開發方法,但如果要真正闡述Hibernate的一些重要思想,僅僅靠在屏幕上打印一些字符是遠遠不夠的,在我們的示例程序中,我們將創建一些對象,并將其保存在數據庫中,然后對它們進行更新和查詢。

“Hello World” “Hello world”示例程序讓您對Hibernate有一個簡單的認識
理解Hibernate的架構 介紹Hibernate接口的主要功能。
核心接口 Hibernate有5個核心接口,通過這幾個接口開發人員可以存儲和獲得持久對象,并且能夠進行事務控制
一個重要的術語:Type Type是Hibernate發明者發明的一個術語,它在整個構架中是一個非常基礎、有著強大功能的元素,一個Type對象能將一個Java類型映射到數據庫中一個表的字段中去。
策略接口 Hibernate與某些其它開源軟件不同的還有一點――高度的可擴展性,這通過它的內置策略機制來實現。
基礎配置 Hibernate可以配置成可在任何Java環境中運行,一般說來,它通常被用在2-3層的C/S模式的項目中,并被部署在服務端。
創建一個SessionFactory對象 要創建一個SessionFactory對象,必須在Hibernate初始化時創建一個Configuration類的實例,并將已寫好的映射文件交由它處理。

  “Hello World”

  Hibernate應用程序定義了一些持久類,并且定義了這些類與數據庫表格的映射關系。在我們這個“Hello world”示例程序中包含了一個類和一個映射文件。讓我們看看這個簡單的持久類包含有一些什么?映射文件是怎樣定義的?另外,我們該怎樣用Hibernate來操作這個持久類。

  我們這個簡單示例程序的目的是將一些持久類存儲在數據庫中,然后從數據庫取出來,并將其信息正文顯示給用戶。其中Message正是一個簡單的持久類:,它包含我們要顯示的信息,其源代碼如下:

  列表1 Message.Java 一個簡單的持久類

package hello;
public class Message {
 private Long id;
 private String text;
 private Message nextMessage;
 private Message() {}
 public Message(String text) {
  this.text = text;
 }
 public Long getId() {
  return id;
 }
 private void setId(Long id) {
  this.id = id;
 }
 public String getText() {
  return text;
 }
 public void setText(String text) {
  this.text = text;
 }
 public Message getNextMessage() {
  return nextMessage;
 }
 public void setNextMessage(Message nextMessage) {
  this.nextMessage = nextMessage;
 }
}


  Message類有三個屬性:Message的id 、消息正文、以及一個指向下一條消息的指針。其中id屬性讓我們的應用程序能夠唯一的識別這條消息,通常它等同于數據庫中的主鍵,如果多個Message類的實例對象擁有相同的id,那它們代表數據庫某個表的同一個記錄。在這里我們選擇了長整型作為我們的id值,但這不是必需的。Hibernate允許我們使用任意的類型來作為對象的id值,在后面我們會對此作詳細描述。

  你可能注意到Message類的代碼類似于JavaBean的代碼風格,并且它有一個沒有參數的構造函數,在我們以后的代碼中我將繼續使用這種風格來編寫持久類的代碼。

  Hibernate會自動管理Message類的實例,并通過內部機制使其持久化,但實際上Message對象并沒有實現任何關于Hibernate的類或接口,因此我們也可以將它作為一個普通的Java類來使用:

Message message = new Message("Hello World");
System.out.println( message.getText() );


  以上這段代碼正是我們所期望的結果:它打印“hello world”到屏幕上。但這并不是我們的最終目標;實際上Hibernate與諸如EJB容器這樣的環境在持久層實現的方式上有很大的不同。我們的持久類(Message類)可以用在與容器無關的環境中,不像EJB必須要有EJB容器才能執行。為了能更清楚地表現這點,以下代碼將我們的一個新消息保存到數據庫中去:

Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message("Hello World");
session.save(message);
tx.commit();
session.close();


  以上這段代碼調用了Hibernate的Session和Transaction接口(關于getSessionFactory()方法我們將會馬上提到)。它相當于我們執行了以下SQL語句:

insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (1, 'Hello World', null)


  在以上的SQL語句中,MESSAGE_ID字段到底被初始化成了什么值呢?由于我們并沒有在先前的代碼中為message對象的id屬性賦與初始值,那它是否為null呢?實際上Hibernate對id屬性作了特殊處理:由于它是一個對象的唯一標識,因此當我們進行save()調用時,Hibernate會為它自動賦予一個唯一的值(我們將在后面內容中講述它是如何生成這個值的)。

  我們假設你已經在數據庫中創建了一個名為MESSAGE的表,那么既然前面這段代碼讓我們將Message對象存入了數據庫中,那么現在我們就要將它們一一取出來。下面這段代碼將按照字母順序,將數據庫中的所有Message對象取出來,并將它們的消息正文打印到屏幕上:

Session newSession = getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List messages =newSession.find("from Message as m order by m.text asc");
System.out.println( messages.size() + " message(s) found:" );
for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
 Message message = (Message) iter.next();
 System.out.println( message.getText() );
}
newTransaction.commit();
newSession.close();


  在以上這段代碼中,你可能被find()方法的這個參數困擾著:"from Message as m order by m.text asc",其實它是Hibernate自己定義的查詢語言,全稱叫Hibernate Query Language(HQL)。通俗地講HQL與SQL的關系差不多就是方言與普通話之間的關系,咋一看,你會覺得它有點類似于SQL語句。其實在find()調用時,Hibernate會將這段HQL語言翻譯成如下的SQL語句:

select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
order by m.MESSAGE_TEXT asc


  以下就是運行結果:

1 message(s) found:
Hello World


  如果你以前沒有ORM(對象-關系映射)的開發經驗,那你可能想在代碼的某個地方去尋找這段SQL語句,但在Hibernate中你可能會失望:它根本不存在!所有就SQL語句都是Hibernate動態生成的。

  也許你會覺得還缺點什么,對!僅憑以上代碼Hibernate是無法將我們的Message類持久化的。我們還需要一些更多的信息,這就是映射定義表!這個表在Hibernate中是以XML格式來體現的,它定義了Message類的屬性是怎樣與數據庫中的MESSAGES表的字段進行一一對應的,列表2是這個示例程序的映射配置文件清單:

  列表2:示例程序的對象-關系映射表

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="hello.Message" table="MESSAGES">
 <id name="id" column="MESSAGE_ID">
  <generator class="increment"/>
 </id>
 <property name="text" column="MESSAGE_TEXT"/>
 <many-to-one name="nextMessage" cascade="all" column="NEXT_MESSAGE_ID"/>
</class>
</hibernate-mapping>


  以上這個文檔告訴Hibernate怎樣將Message類映射到MESSAGES表中,其中Message類的id屬性與表的MESSAGE_ID字段對應,text屬性與表的MESSAGE_TEXT字段對應,nextMessage屬性是一個多對一的關系,它與表中的NEXT_MESSAGE_ID相對應。

  相對于有些開源項目來說,Hibernate的配置文件其實是很容易理解的。你可以輕松地修改與維護它。只要你定義好了持久類與數據庫中表字段的對應關系就行了,Hibernate會自動幫你生成SQL語句來對Message對象進行插入、更新、刪除、查找工作,你可以不寫一句SQL語句,甚至不需要懂得SQL語言!

  現在讓我們做一個新的試驗,我們先取出第一個Message對象,然后修改它的消息正文,最后我們再生成一個新的Message對象,并將它作為第一個Message對象的下一條消息,其代碼如下:

  列表3 更新一條消息

Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
// 1 is the generated id of the first message
Message message =(Message) session.load( Message.class, new Long(1) );
message.setText("Greetings Earthling");
Message nextMessage = new Message("Take me to your leader (please)");
message.setNextMessage( nextMessage );
tx.commit();
session.close();


  以上這段代碼在調用時,Hibernate內部自動生成如下的SQL語句:

select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
where m.MESSAGE_ID = 1

insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (2, 'Take me to your leader (please)', null)

update MESSAGES
set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2
where MESSAGE_ID = 1


  當第一個Message對象的text屬性和nextMessage被程序修改時,請注意Hibernate是如何檢測到這種變化,并如何在數據庫中自動對它更新的。這實際上是Hibernate的一個很有價值的特色,我們把它稱為“自動臟數據檢測”,Hibernate的這個特色使得當我們修改一個持久對象的屬性后,不必顯式地通知Hibernate去將它在數據庫中進行更新。同樣的,當第一個Message對象調用setNextMessage()方法將第二個Message對象作為它的下一條消息的引用時,第二條消息會無需調用save()方法,便可以自動地保存在數據庫中。這種特色被稱為“級聯保存”,它也免去了我們顯式地對第二個Message對象調用save()方法之苦。

  如果我們再運行先前的那段將數據庫中所有的Message對象都打印出來的代碼,那它的運行結果如下:

2 message(s) found:
Greetings Earthling
Take me to your leader (please)


  “Hello world”示例程序現在介紹完畢。我們總算對Hibernate有了一個簡單的認識,下面我們將回過頭來,對Hibernate的主要API調用作一下簡要的介紹:



小辭猬 2005-10-31 11:29 發表評論
]]>
十分鐘在jb(JBuilder)里面運行hibernate的簡單例子http://www.tkk7.com/superwei/articles/17514.html小辭猬小辭猬Mon, 31 Oct 2005 03:27:00 GMThttp://www.tkk7.com/superwei/articles/17514.htmlhttp://www.tkk7.com/superwei/comments/17514.htmlhttp://www.tkk7.com/superwei/articles/17514.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17514.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17514.html如果你有用過其他持久架構 轉到hibernate其實很簡單。一些原理方面就不講了,

robbin講的肯定比我好的多,自己去精華版看看。

我所給的只是我當初剛開始接觸hibernate時候很想要的一個簡單例子和設置方法。

一直沒有找到,所以現在放到這里給大家看看,(只給想要入門的一個直觀的感應,呵呵)

首先當然要新建一個項目

然后在Project Properties->Paths->Required Libraries->add->new 這里定義hibernate的類庫 把hibernate的lib下面的所有jar包進去 當然還有hibernate2.jar也要

然后一路ok下去就可以了。

再來就是hibernate.properties

從hibernate的src下面找到

把它拷到你項目的src目錄下

(什么,你的項目沒有src目錄,新建一個隨便的類就有src目錄了)

這樣一個JB下面的hibernate的開發環境就好了

然后在hibernate.properties里面設置你的數據庫連接

默認是HypersonicSQL

嗯 接下來的是你最想要做的事情了 其實很簡單

新建一個類Message.java

代碼如下

package hello;

import java.io.Serializable;

/**
 * @author getdown
 * @version 1.0
 */

public class Message implements Serializable {
  private Long id;
  private String text;
  //定義一個簡單鏈表 指向另外的一個Message
  private Message nextMessage;
  public Message() {}

  public Message(Long id) {
    this.id = id;
  }

  public Message(String text) {
    this.text = text;
  }

  public Message(Long id, String text) {
    this.id = id;
    this.text = text;
  }

  public Long getId() {
    return id;
  }

  private void setId(Long id) {
    this.id = id;
  }

  public String getText() {
    return text;
  }

  public void setText(String text) {
    this.text = text;
  }

  public Message getNextMessage() {
    return nextMessage;
  }

  public void setNextMessage(Message nextMessage) {
    this.nextMessage = nextMessage;
  }

}

接下來是這個類對應的hibernate的配置文件 Message.hbm.xml

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
    <!--定義類和表的對應-->
    <class
        name="hello.Message"
        table="Messages"
    >
    <!--定義ID字段和生成ID的策略 這里采用identity-->
    <id    name="id"
        column="MESSAGE_ID"
    >
    <generator class="identity"/>
    </id>
        <!--定義里面的text字段-->
    <property
        name="text"
                type="string">
                <!--定義text字段在數據庫里面生成的方法-->
        <column
            name="TEXT"
            length="100"
                        not-null="true"
                />
    </property>
       <!--定義對象關聯之間的對應關系和關聯的字段-->
    <many-to-one
        name="nextMessage"
        cascade="all"
        column="NEXT_MESSAGE_ID"
    />
    </class>
</hibernate-mapping>

然后就是測試類

package hello;

import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.tool.hbm2ddl.SchemaExport;
import net.sf.hibernate.Session;
import net.sf.hibernate.Query;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.type.LongType;
import net.sf.hibernate.Transaction;



/**
 * @author getdown
 * @version 1.0
 */

public class Hello {
  public Hello() {
  }

  public static void main(String[] args) throws Exception {
    Configuration cfg = new Configuration().addClass(Message.class);

    /** 顧名思義 構建表。。。第一次運行的時候運行下面語句可以在數據庫生成表
     * 之后可以把下面這句去掉
     * */
//    new SchemaExport(cfg).create(true, true);

    //先生成sessionFactory
    SessionFactory sessions = cfg.buildSessionFactory();
    //再從sessionFactory得到一個session
    Session session = sessions.openSession();
    //啟動事務
   Transaction tx = session.beginTransaction();

    //開始對數據庫的操作
    /*----對數據庫的創建操作--------*/
    Message message = new Message("helloWorld");
    //創建一條記錄

    session.save(message);
    //存入記錄
   session.flush();
    //提交事務
    tx.commit();


    /*---對數據庫的查詢操作---------------*/
//    Message message = new Message();
//    Query q = session.createQuery("from Message as message where message.id=1");
//    message = (Message) q.list().get(0);
//    message.getNextMessage().setText("helloNext");
//    session.flush();
//    session.close();
//    Long id = new Long(1);
//    Message message = (Message) session.find("from Message as message where 
message.id=?", id, Hibernate.LONG).get(0); // System.out.println(message.getText()); // /*-------事務的處理----------------*/ // try { // Message message = new Message("hello"); // session.save(message); // session.flush(); // message = new Message("hello"); // session.save(message); // session.flush(); // tx.commit(); // } // catch (HibernateException ex) { // tx.rollback(); // } /*-------添加1000條記錄時間--------------*/ // long start = System.currentTimeMillis(); // for(int i = 0; i < 1000; i ++) { // Message message = new Message("hello"); // session.save(message); // session.flush(); // } // tx.commit(); // long end = System.currentTimeMillis(); // System.out.println("添加1000條記錄時間---" + (end-start)/1000 + "s"); session.close(); } }

ok了 運行一下Hello看看出來什么吧

怎么樣 比起CMP的持久 hibernate的持久是不是顯得很輕量級。。

還可以試試看hibernate的性能 把Hello.java的最后一段注釋去掉運行看看

當然hibernate最重要的還是它的原理,還有很多很好的,很有趣的功能和O/RM設計思想等著你自己發掘。

多看看它自己的文檔,可以學到很多東西,它的文檔真的非常好。



小辭猬 2005-10-31 11:27 發表評論
]]>
對象(object)與引用(reference) http://www.tkk7.com/superwei/articles/17511.html小辭猬小辭猬Mon, 31 Oct 2005 03:11:00 GMThttp://www.tkk7.com/superwei/articles/17511.htmlhttp://www.tkk7.com/superwei/comments/17511.htmlhttp://www.tkk7.com/superwei/articles/17511.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17511.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17511.html一,對象(object)與引用(reference)
有許多書籍,對于對象與引用之間的關系一直語焉不詳,甚至有的干脆是錯誤的說法,我們必須對這個問題
有個清晰的了解.
我們知道:
A a = new A();
產生一個A類型的對象,a是這個對象的的一個引用,即a指向heap中真正的對象,而a和其他基本數據類型
一起存放在stack中.也就是object通過reference操控,在底層的話,a更象一個指針.
對于有些書本所說,a就是對象,初學者的話也沒什么大問題,因為對a的操作,就是對a指向的對象的操作.
問題是,當a的指向發生改變時,a就是對象的說法就不能適應程序設計的需要.
讓我們來看一個簡單的程序:

class A
{
private int i=0;
public void setI(int x)
{
i=x;
}
public int getI(){
return i;
}
}

public class MyRef1 {


public static void main(String[] args) {
A a=new A();
A b=new A();
a.setI(10);
b.setI(15);
System.out.println("a的i="+a.getI());
System.out.println("b的i="+b.getI());
a=b;
a.setI(20);
System.out.println("a的i="+a.getI());
System.out.println("b的i="+b.getI());

}

}
我想,大家對于程序的輸出應該認為是:
a的i=10
b的i=15
a的i=20
b的i=15
第一,第二行應該沒什么異義,第三行是對a設置后i的值,問題是,第四行是不會輸出i=15的,正確結果是:
i=20
因此,a,b都是對對象的引用,當我們將b的引用賦予a時,a已經重新指向了b,對指向發生改變后的a的操作,
就是對b的操作.
當然,那些堅持"a,b就是對象"說法的人,還是可以解釋這個問題:對啊,a對象"變成"了b對象,沒有什么,很
正常啊.
那么,我們再來看:

我們知道,java通過final來定義常量:
final int i=10;
當我們對一個常量重新賦值時,會發生編譯錯誤:
i=5;//編譯不通過
我們也可以通過final來定義常量對象:
final A a = new A();
這樣的話,我們將不能對a重新賦值.


如果a本身是個對象,那么,這個對象就不能發生改變,其實,a只不過是一個引用,它只能指向原來指向的對象,
并不是說它所指的對象的狀態不能改變,因此,我們可以通過不改變a原來的指向的情況下對對象狀態進行改
變,看程序:

class A
{
private int i=0;
public void setI(int x)
{
i=x;
}
public int getI(){
return i;
}
}

public class MyRef1 {



public static void main(String[] args) {


final A a = new A();
System.out.println(a.getI());
a.setI(8);
System.out.println(a.getI());


}

}

如果a本身是個對象,那么,根本就不可能
a.setI(8);
而實際a是一個引用,程序可以編譯并運行:
顯示:8

總之,java通過renfence來操控object,是深入學習java知識的基礎,例如下面一點:


二,java參數是值(value)傳遞還是引用(reference)傳遞
我們先看程序:
public class MyRef2 {

static int x=10;
static int y=20;
public static void fangfa(int i)
{
i++;
x=i;
}

public static void main(String[] args) {
System.out.println("x="+x);
System.out.println("y="+y);
MyRef2.fangfa(y);
System.out.println("x="+x);
System.out.println("y="+y);


}

}
顯然,將顯示:
x=10
y=20
x=21
y=20
y的值并沒有發生改變,MyRef2.fangfa(y)使用的僅僅是y的值,里面的i++也不會作用到y本身.
顯然,java的參數是值傳遞,但是,為什么會有引用傳遞的說法呢?
看下面這個程序:
class A
{
private int i=0;
public void setI(int x)
{
i=x;
}
public int getI(){
return i;
}
}

public class MyRef1 {

public static void setA1(A newA,int t)
{
newA.setI(t);

}

public static void main(String[] args) {
A a=new A();
System.out.println(a.getI());
MyRef1.setA1(a, 30);
System.out.println(a.getI());
}

}
按照值傳遞的說法,MyRef1.setA1(a, 30);將使用a所指的對象的一個復件,最終對這個對象沒有作用
而事實是,方法對這個對象起了作用,程序將顯示0,30.那么,java參數是值傳遞是不是錯誤了呢?
老爹告訴你:no!
我們要記住,a只不過是對象的reference,而reference的復件與原來的reference指向的是同一個對象
我們對復件的操作,與對a的操作一樣,最終還是對指向對象的操作,因此,java的參數,只有值傳遞.


小辭猬 2005-10-31 11:11 發表評論
]]>
簡單的struts應用開發(5)http://www.tkk7.com/superwei/articles/17504.html小辭猬小辭猬Mon, 31 Oct 2005 02:33:00 GMThttp://www.tkk7.com/superwei/articles/17504.htmlhttp://www.tkk7.com/superwei/comments/17504.htmlhttp://www.tkk7.com/superwei/articles/17504.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17504.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17504.html第六步:建立JSP視圖頁面 (主要有兩個jsp文件. 添加頁面. adduser.jsp 查看頁面 viewuser.jsp)

adduser.jsp

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ page contentType="text/html; charset=gb2312" %>
<html:html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>
adduser
</title>
</head>
<body>
<h1> </h1>
<p>
<html:form action="/user1Action.do" method="POST">
<html:hidden property="action"/>
<br>
部門:
<html:select property="dep">
<html:options collection="dep" property="id" labelProperty="name1"/>
</html:select>
<br>
ID:
<logic:equal name="userActionForm" property="action" scope="request" value="add">
<html:text property="user_id"/>
</logic:equal>
<logic:equal name="userActionForm" property="action" scope="request" value="edit">
<html:text property="user_id" readonly="true"/>
</logic:equal>
<br>
名字:<html:text property="user_name"/>
<br>
電話:<html:text property="tel"/>
<br>
<html:submit property="submit" value="Submit"/><br>
<html:reset value ="Reset"/>
</html:form>
</body>
</html:html>

viewuser.jsp

<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ page contentType="text/html; charset=GBK" %>
<html:html>
<head>
<title>
viewuser
</title>
</head>
<body>
<div align="center"><a href="userAction.do?action=add">add </a></div>
<table width="60%" border="1" align="center">
<tr bgcolor="#CCCCCC">
<td>ID</td>
<td>user_name</td>
<td>dep</td>
<td>tel</td>
<td>modify</td>
<td>del</td>
</tr>
<logic:iterate name="rs" id="user" scope="request" type="java.util.HashMap">
<tr>
<td><bean:write name="user" property="user_id"/> </td>
<td><bean:write name="user" property="user_name"/> </td>
<td><bean:write name="user" property="dep_name"/> </td>
<td><bean:write name="user" property="tel"/> </td>
<td><a href="userAction.do?action=edit&key=<bean:write name="user" property="user_id"/>">modify</a></td>
<td><a href="userAction.do?action=del&key=<bean:write name="user" property="user_id"/>">del</a></td>
</tr>
</logic:iterate>
</table>
</body>
</html:html>

建產一個轉向頁面 (index.jsp)
<%@ page contentType="text/html; charset=gb2312" %>
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body>
<% response.sendRedirect("userAction.do?action=view"); %>
</body>
</html>

遞七步:建立struts配置文件 (WEB-INF/config-struts.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="userActionForm" type="mystruts.userActionForm" />
</form-beans>
<action-mappings>
<action type="mystruts.userAction" scope="request" path="/userAction">
<forward name="view" path="/viewuser.jsp" />
<forward name="add" path="/adduser.jsp" />
<forward name="delview" path="/userAction.do?action=view" />
</action>
<action name="userActionForm" type="mystruts.user1Action" scope="request" path="/user1Action">
<forward name="view" path="/userAction.do?action=view" />
</action>
</action-mappings>
</struts-config>

運行程序:
啟動tomcat
啟動IE 在地址欄中輸入 http://localhost:8080/mystruts

OK.....



小辭猬 2005-10-31 10:33 發表評論
]]>
簡單的struts應用開發(4)http://www.tkk7.com/superwei/articles/17503.html小辭猬小辭猬Mon, 31 Oct 2005 02:32:00 GMThttp://www.tkk7.com/superwei/articles/17503.htmlhttp://www.tkk7.com/superwei/comments/17503.htmlhttp://www.tkk7.com/superwei/articles/17503.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17503.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17503.html第五步:建立Action (userAction.java)

這里我們將建產兩個Action .

userAction.java 將完成以下工作.
1.添加(前期數據準備. 主是提取部門資料.并傳遞給adduser.jsp)
2.修改(前期數據準備)
3.刪除
4.查看所有用戶資料.

user1Action.java 將完成以下工作
1.添加用戶(對myuser表操作)
2.修改用戶(對myuser表操作)

package mystruts;

import org.apache.struts.action.*;
import javax.servlet.http.*;
import mystruts.*;
import java.util.*;
import java.sql.*;
import ConnectionPool.*;

public class userAction extends Action {
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception
{
userdao dao=new userdao();
HttpServletRequest request=httpServletRequest;
String action;
if(request.getParameter("action").equals("") || request.getParameter("action")==null)
{
action="add";
}
else
{
action=request.getParameter("action");
}
if(action.equals("add"))
{
request.setAttribute("dep",this.getDep());
return (actionMapping.findForward("add"));
}
if(action.equals("edit"))
{
String key=request.getParameter("key");
request.setAttribute("dep",this.getDep());
request.setAttribute("userActionForm",dao.getUser(key));
return (actionMapping.findForward("add"));
}
if(action.equals("del"))
{
String key=request.getParameter("key");
dao.delUser(key);
return (actionMapping.findForward("delview"));
}
if(action.equals("view"))
{
request.setAttribute("rs",dao.getAlluser());
return (actionMapping.findForward("view"));
}

return null;
}
//---------------------------------------------
public Collection getDep()
{
getDbConnection db=new getDbConnection();
Connection con=db.getCon();
ResultSet rs=null;

PreparedStatement ps = null;

ArrayList rslist = new ArrayList();

String sql="select * from mydep";
try {
ps = con.prepareStatement(sql);
rs=ps.executeQuery();
while(rs.next())
{
HashMap rscol = new HashMap();
rscol.put("id",rs.getString("dep_id"));
rscol.put("name1",rs.getString("dep_name"));
rslist.add(rscol);
}
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
return rslist;
}
}



package mystruts;

import org.apache.struts.action.*;
import javax.servlet.http.*;

public class user1Action extends Action {
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception
{
userActionForm uaf = (userActionForm) actionForm;
if(uaf.getAction().equals("add"))
{
new userdao().userInsert(uaf);
return (actionMapping.findForward("view"));
}
if(uaf.getAction().equals("edit"))
{
new userdao().userUpdate(uaf);
return (actionMapping.findForward("view"));
}
return null;
}
}

小辭猬 2005-10-31 10:32 發表評論
]]>
簡單的struts應用開發(3)http://www.tkk7.com/superwei/articles/17502.html小辭猬小辭猬Mon, 31 Oct 2005 02:31:00 GMThttp://www.tkk7.com/superwei/articles/17502.htmlhttp://www.tkk7.com/superwei/comments/17502.htmlhttp://www.tkk7.com/superwei/articles/17502.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17502.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17502.html
package mystruts;

import java.sql.*;
import ConnectionPool.*;
import java.util.*;

public class userdao {
getDbConnection db=null;
Connection con=null;

public userdao() {
}
//-------------------------------------------------------------------
public void userInsert(userActionForm uaf1)
{
db=new getDbConnection();
con=db.getCon();
userActionForm uaf=uaf1;
PreparedStatement ps = null;
String sql="insert into myuser (user_id,user_name,dep,tel) values(?,?,?,?)";
try {

ps = con.prepareStatement(sql);
ps.setString(1,uaf.getUser_id());
ps.setString(2,uaf.getUser_name());
ps.setString(3,uaf.getDep());
ps.setString(4,uaf.getTel());
ps.executeUpdate();
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
}
//---------------------------------------------
public void userUpdate(userActionForm uaf1)
{
db=new getDbConnection();
con=db.getCon();
userActionForm uaf=uaf1;
PreparedStatement ps = null;
String sql="update myuser set user_name=?,dep=?,tel=? where user_id=?";
try {

ps = con.prepareStatement(sql);
ps.setString(1,uaf.getUser_name());
ps.setString(2,uaf.getDep());
ps.setString(3,uaf.getTel());
ps.setString(4,uaf.getUser_id());
ps.executeUpdate();
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
}
//---------------------------------------------
public userActionForm getUser(String key)
{
db=new getDbConnection();
con=db.getCon();
ResultSet rs=null;
userActionForm uaf=new userActionForm();
PreparedStatement ps = null;
String sql="select * from myuser where user_id=?";
try {
ps = con.prepareStatement(sql);
ps.setString(1,key.trim());
rs=ps.executeQuery();
if(rs.next())
{
uaf.setUser_id(rs.getString("user_id"));
uaf.setUser_name(rs.getString("user_name"));
uaf.setDep(rs.getString("dep"));
uaf.setTel(rs.getString("tel"));
uaf.setAction("edit");
}
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
System.out.println("mod"+key);
return uaf;
}
//----------------------------------------
public void delUser(String key)
{
db=new getDbConnection();
con=db.getCon();
PreparedStatement ps = null;
String sql="delete from myuser where user_id=?";
try {
ps = con.prepareStatement(sql);
ps.setString(1,key.trim());
ps.executeUpdate();
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
System.out.println("del"+key);
}
//----------------------------------
public Collection getAlluser()
{
db=new getDbConnection();
con=db.getCon();
ResultSet rs=null;
userActionForm uaf=new userActionForm();
PreparedStatement ps = null;

ArrayList rslist = new ArrayList();

String sql="select * from myuser u,mydep d where u.dep=d.dep_id";
try {
ps = con.prepareStatement(sql);
rs=ps.executeQuery();
while(rs.next())
{
HashMap rscol = new HashMap();
rscol.put("user_id",rs.getString("user_id"));
rscol.put("user_name",rs.getString("user_name"));
rscol.put("dep",rs.getString("dep"));
rscol.put("dep_name",rs.getString("dep_name"));
rscol.put("tel",rs.getString("tel"));
rslist.add(rscol);
}
}
catch (SQLException e)
{
System.out.println("sql error");
}
finally
{
try{
con.close();
db.d_close();
}
catch(Exception e) {}
}
return rslist;
}
//----------------------------------
}

小辭猬 2005-10-31 10:31 發表評論
]]>
簡單的struts應用開發(2)http://www.tkk7.com/superwei/articles/17501.html小辭猬小辭猬Mon, 31 Oct 2005 02:30:00 GMThttp://www.tkk7.com/superwei/articles/17501.htmlhttp://www.tkk7.com/superwei/comments/17501.htmlhttp://www.tkk7.com/superwei/articles/17501.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17501.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17501.html
1.首先創建數據聯接bean, 并打包到 ConnectionPool, 它將從我們配置的聯接池中取得可用聯接.

// Java Document
package ConnectionPool;
import javax.naming.*;
import javax.sql.*;
import java.sql.*;
import java.io.*;
import java.util.*;

public class getDbConnection {

Connection conn;
Statement stmt;
ResultSet rs=null;

String foo = "Not Connected";
int bar = -1;

public getDbConnection() {
try{
Context ctx = new InitialContext();
if(ctx == null )
throw new Exception("Boom - No Context");

DataSource ds =
(DataSource)ctx.lookup(
"java:comp/env/jdbc/TestDB");

if (ds != null) {
conn = ds.getConnection();

}
}
catch(Exception e) {
e.printStackTrace();
}
}

public Connection getCon()
{
return conn;
}


public void d_close() throws SQLException
{
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
rs = null;
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
stmt = null;
}
if (conn != null) {
try { conn.close(); } catch (SQLException e) { ; }
conn = null;
}

}

protected void finalize() throws Throwable
{
try { d_close(); } catch (SQLException e) { ; }
}

}

2.創建數據庫.

數據庫名: mystruts

部門表: mydep

_______________________________________
dep_id dep_name
_______________________________________
1 dep1
2 dep2
3 dep3
4 dep4
_______________________________________

用戶表: myuser
______________________________________________
user_id user_name dep tel
______________________________________________
1 jack 1 0769-2454042
2 max 2 0769-2454043
______________________________________________

(注: 以上字段為了測試方便. 全部使用字符型)


第三步: 創建ActionForm (userActionForm.java)

package mystruts; //請打包到mystruts下.

import org.apache.struts.action.*;
import javax.servlet.http.*;

public class userActionForm extends ActionForm {
private String action="add";
private String dep;
private String tel;
private String user_id;
private String user_name;
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getDep() {
return dep;
}
public void setDep(String dep) {
this.dep = dep;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public ActionErrors validate(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {

return null;
}
public void reset(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {
}
}

小辭猬 2005-10-31 10:30 發表評論
]]>
簡單的struts應用開發(1)http://www.tkk7.com/superwei/articles/17499.html小辭猬小辭猬Mon, 31 Oct 2005 02:23:00 GMThttp://www.tkk7.com/superwei/articles/17499.htmlhttp://www.tkk7.com/superwei/comments/17499.htmlhttp://www.tkk7.com/superwei/articles/17499.html#Feedback0http://www.tkk7.com/superwei/comments/commentRss/17499.htmlhttp://www.tkk7.com/superwei/services/trackbacks/17499.htmlmystruts
|-WEB-INF
| |- lib
| | |- struts.jar
| |- classes
| | |- ConnectionPool
| | | |- getDbConnection.class
| | |-mystruts
| | |- user1Action.class
| | |- userAction.class
| | |- userActionForm.class
| | |- userdao.class
| |-struts-bean.tld
| |-struts-config.xml
| |-struts-html.tld
| |-struts-logic.tld
| |-struts-template.tld
|-adduser.jsp
|-index.jsp
|-viewuser.jsp

第一步: 開發環境配置

(如果你還沒有相關軟件. 請到http://www.apache.org 下載)

tomcat5.0 配置 (建立一個 mystruts 應用, 并拷貝相關文件)

請在你的tomcat安裝目錄中找到\conf\Catalina\localhost 子目錄. 新建 mystruts.xml 文件
文件內容如下. 在這個文件中. 我們將配置一個聯接池.請把相關的驅動.數據庫用戶,密碼改成你自己的本機配置.
并把JDBC驅動拷貝一份到 Tomcat 5.0\common\lib 目錄下. 請把 struts.jar \mystruts\WEB-INF\lib 目錄下.



auth="Container"
type="javax.sql.DataSource"/>



factory
org.apache.commons.dbcp.BasicDataSourceFactory



maxActive
10



maxIdle
5



maxWait
10000



username
sa


password
test



driverClassName
net.sourceforge.jtds.jdbc.Driver



url
jdbc:jtds:sqlserver://192.168.10.223:1433/mystruts




WEB-INF/web.xml (加入struts標記庫的支持)





action
org.apache.struts.action.ActionServlet

debug
2


config
/WEB-INF/struts-config.xml

2


action
*.do


/WEB-INF/struts-bean.tld
/WEB-INF/struts-bean.tld


/WEB-INF/struts-html.tld
/WEB-INF/struts-html.tld


/WEB-INF/struts-logic.tld
/WEB-INF/struts-logic.tld


/WEB-INF/struts-template.tld
/WEB-INF/struts-template.tld



小辭猬 2005-10-31 10:23 發表評論
]]>
主站蜘蛛池模板: 中文字幕亚洲电影| 久久精品国产亚洲αv忘忧草 | 亚洲久悠悠色悠在线播放| 中文字幕亚洲一区二区三区| 黄色网站软件app在线观看免费 | 永久免费av无码网站韩国毛片| 亚洲国产精品精华液| 久久精品亚洲男人的天堂| 69视频免费在线观看| 国产午夜亚洲精品不卡免下载| 国产亚洲人成网站在线观看不卡| 97免费人妻无码视频| 国产精品免费一区二区三区| 亚洲国产成人91精品| 4338×亚洲全国最大色成网站| 精品女同一区二区三区免费站 | 特级毛片爽www免费版| 激情内射亚洲一区二区三区| 国产中文字幕免费| 在线日本高清免费不卡| 免费在线人人电影网| 亚洲国产美女在线观看| 亚洲色婷婷六月亚洲婷婷6月| 西西大胆无码视频免费| 不卡视频免费在线观看| 亚洲人成网站在线在线观看| 亚洲va中文字幕无码久久| 亚洲成A人片在线观看无码3D| 一级毛片视频免费观看| 77777亚洲午夜久久多喷| 亚洲爆乳无码专区| 亚洲片一区二区三区| 免费人成视频在线| 91禁漫免费进入| 永久免费av无码网站yy| 黄色一级视频免费| 亚洲AV永久无码精品一福利| 亚洲一区在线视频| 亚洲男人的天堂在线| 亚洲AV无码专区亚洲AV伊甸园| 亚洲人妻av伦理|