#
?由于Jboss默認的數據庫為HypersonicDB,很多人,包括我,對它都不是十分了解,只知道它是java寫的,使用起來不是很方便,本人最近在學EJB,所以研究了一下。
?
? 我在網上找了很多資料包括什么《JBOSS 數據源設置大全》啊,一類的文章,都不能成功將默認的數據庫改為Oricle10g(別的數據庫能否成功我沒有試過),也就是我用的數據庫,所以自己查閱了國外的一些BBS,總結了一下經驗,貢獻給chinajavalab。
? 1.刪除Jboss\server\default\deploy下的hsql-ds.xml,從Jboss\docs\examples\jca中復制一個oracle-ds.xml過來,修改里面的屬性;connection-url,driver-class,user-name,pssword,其中jndi-name最好設置成DefaultDS,這樣可以方便后面幾個xml文件的修改
? 2.刪除Jboss\server\default\deploy\jms下的一切有關HSQL的文件,共有兩個,
從Jboss\docs\examples\jms中復制一個oracle-jdbc2-service.xml過來,將<depends>中的name改為DefaultDS,或者你自己設置的jndi-name
? 3.進入Jboss\server\default\conf,如果你將jndi-name設置成DefaultDS的話,就不用設置login-config.xml了,否則要設置,將里面的DefaultDS更換成你的jndi-name,后面的xml文件也要注意jndi-name,后面就不再提示了
? 4.修改jboss-service.xml,將<!--attribute name="Pad">true</attribute--> 的注釋去掉
? 5.修改standardjbosscmp-jdbc.xml,將datasource-mapping設置成Oracle9i,這里不管你用的是9i還是10g都要設置成9i,jboss4中目前還沒有10g的相關內容,我用的是10g,沒有問題的,關鍵是你的dirver包一定要是class12.jar,并將它放進Jboss\server\default\lib中
? 6.修改standardjaws.xml,將type-mapping設置為Oracle9i,增加
<type-mapping-definition> ?
<name>Oracle9i</name>
? ? ?<mapping>
? ? ? ? ? .
? ? ? ? ? .
? ? ?中間的內容到standardjbosscmp-jdbc.xml中的Oracle9i里找,復制過來
? ? ?,只要其中<mapping>的內容,其他不要
? ? ? ? ? .
? ? ? ? ? .
? ? ?</mapping>
</type-mapping-definition>
好了,重新啟動你的jboss,部署一個EJB試一試,如果有異常,表示你還沒有配置正確
Sun發布的JDK/JRE有兩種版本,一種是.rpm.bin格式的,另一種則是.bin格式的,前者我沒有試,但是我想應該是適合于rpm的,可能會安裝到/usr里面去,而且自動化程度可以高一些。后者則完全是綠色軟件,只是做一個解壓的動作。下面我就來講后者的安裝全攻略。
1、首先我們要到Sun的網站上去下載JDK/JRE(點這里進入),最新的正式版本已經是6.0(也就是1.6),當然老的版本Sun也仍然提供下載,點上面的“Previous Releases”就可以找到了。下載.bin文件,下面假設這個文件的名字是jdk1.x.bin。
2、把安裝文件解壓出來。假設我們下載的文件保存在/opt下。
打開終端,運行以下命令:
引用:
cd /opt
chmod a+x jdk1.x.bin
./jdk1.x.bin
你會看到版權提示,不管它,按空格鍵翻頁。然后會提示你是否同意版權協議[yes/no],此時輸入yes,回車,安裝程序就會把文件解壓到當前目錄下的jdk1.x這樣的目錄下面(JRE應該大體相同)。
3、讓JDK/JRE支持中文。由于默認安裝的JDK/JRE不帶中文字體,不支持中文顯示,所以我們要自行修改某些字體相關的配置,讓它們支持中文。
設定字體有兩種方法:
第一種方法是把你的中文字體目錄做個連接到jdk/jre/lib/fonts里面,這種方法很簡便。看命令:
引用:
cd /opt/jdk1.x/jre/lib/fonts
ln -s /usr/share/fonts/truetype/windows fallback (假設我們的中文字體放在/usr/share/fonts/truetype/windows目錄里,這個目錄里我放的是從Windows那邊copy過來的字體)
為什么要做fallback這個連接,我也是從網上看到的,我想應該是Sun做的設定吧,設定JDK/JRE在運行時會到這個目錄里去找那些非西方字體。這種方法對JDK/JRE 1.4/1.5/1.6都適用,但是由于沒有在fontconfig.properties文件里面詳細設定字體,所以這種方法顯示出來的字體很難看。
第二種方法是把配置好的fontconfig.properties做個連接到jdk1.x/jre/lib里面。看命令:
引用:
cd /opt/jdk1.x/jre/lib
ln -s /etc/java/fontconfig.properties (假設我們的fontconfig.properties放在/etc/java目錄里)
這種方法對JDK/JRE 1.4/1.5/1.6都適用,只不過1.4版本的文件名是font.properties而不是fontconfig.properties。當然你也可以直接把fontconfig.properties文件復制到/opt/jdk1.x/jre/lib里面,這樣就不用做連接,但是如果你同時安裝幾個不同版本的JDK,還是做連接比較方便。在下面我會把我配置好的font.properties和fontconfig.properties的內容貼出來,大家稍作修改就可以用了。
3、讓Web瀏覽器支持Java插件(也就是支持Java Applets)。
做一個連接就可以了。看命令:
引用:
cd /usr/lib/firefox/plugins (Ubuntu的firefox插件目錄在這里,其它版本以此參考)
ln -s /opt/jdk1.x/jre/plugin/i386/ns7/libjavaplugin_oji.so
然后運行firefox,在地址欄里打入about:plugins,回車,可以看到firefox的插件列表里已經有了Java插件。
如果你用的是其它的瀏覽器,方法大體也差不多,就是進入瀏覽器的plugins目錄,做一個連接。不過要注意的是,如果你用的瀏覽器是 mozilla 1.4/netscape 7.0以上的版本,用上面的命令沒問題,但是如果你用的瀏覽器是mozilla 1.2/netscape 7.0以下的版本,Sun有提供另一個插件。這樣的話,命令就要改一下了:
引用:
cd /usr/lib/mozilla/plugins
ln -s /opt/jdk1.x/jre/plugin/i386/ns7-gcc29/libjavaplugin_oji.so
4、讓Web瀏覽器支持Java Web Start程序。(可選安裝)
如果你不知道Java Web Start程序是什么,看這里:
http://www.stcore.com/java/2006/06/18/1150640682d28890.html
所謂安裝,其實就是添加一個mimetype(類似于文件關聯),讓瀏覽器知道,遇到Java Web Start程序該用什么程序來處理。
對應mozilla/netscape瀏覽器的方法:
點擊菜單:Edit->Preferences->Navigator->Helper Applications
然后新建一個mimetype:
mimetype是:application/x-java-jnlp-file
extention是:jnlp
關聯程序是:/opt/jdk1.x/jre/bin/javaws
對應firefox瀏覽器的方法:
由于firefox沒有直接添加mimetype的方法,所以要改的話需要安裝一個Mime Type Editor擴展,看這里:
http://forums.mozine.org/index.php?showtopic=5521
5、為firefox瀏覽器加入Java Console菜單項。(可選安裝)
mozilla/netscape裝好java插件之后就有Java Console菜單項,可以方便地調用Java控制臺,這對程序員調試程序有用。但是firefox還沒有這個菜單項,添加的方法就是解壓一個zip文件到firefox/extension目錄。現在我們就來添加,看命令:
引用:
cd /usr/lib/firefox/extensions
unzip /opt/jdk1.x/jre/lib/deploy/ffjcext.zip
重啟firefox,就可以看到工具菜單里多了一個Java Console菜單項。
JDK/JRE 1.5及以下版本并沒有提供這個firefox擴展,如果要安裝的話到這里安裝:
https://addons.mozilla.org/firefox/141/
6、把Java工具加入系統菜單。(可選安裝)
Ubuntu自帶的JDK/JRE會在系統菜單中添加兩個Java工具,就是Java Plugin Control Panel和Java Policy Tool。下面我們也為自己安裝的JDK/JRE添加兩個菜單項。
在Ubuntu的主菜單上點擊右鍵->編輯菜單->首選項->新建項目:
第一項:
圖標是:/opt/jdk1.x/jre/plugin/desktop/sun_java.png
名稱是:Java Plugin Control Panel (這個隨便寫)
命令是:/opt/jdk1.x/jre/bin/ControlPanel
第二項:
圖標是:/opt/jdk1.x/jre/plugin/desktop/sun_java.png
名稱是:Java Policy Tool (這個隨便寫)
命令是:/opt/jdk1.x/jre/bin/policytool
7、添加JAVA_HOME/JRE_HOME環境變量。(Java開發人員必備)
這里以最常用的bash命令解釋器為例,編輯用戶目錄下的.bashrc或.profile文件。如果你想在所有用戶的shell下都生效,就編輯/etc/profile文件。同樣都是加入以下內容:
引用:
export JAVA_HOME=/opt/jdk1.x
export JRE_HOME=/opt/jdk1.x/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
至此,Sun JDK/JRE在Linux上的安裝過程結束。
DAO 類是線程安全的,它的所有操作都通過調用 DbExecutor 對象來執行。每次操作,DAO 都會從 DbExecutorFactory 中獲得一個 DbExecutor 對象。DAO 要做的就是保證做完操作之后都要執行 DbExecutor 對象的 close 方法。
DbExecutor 是一個接口,它的大部分方法和 DAO 差不多。它包含一個數據庫連接,當連接關閉時,DbExecutor 對象的生命周期也就結束了。OraDbExecutor 是 DbExecutor 的一個實現。
OraDbExecutor.java - 構造函數
- public OraDbExecutor(String dsName, Connection conn) {
- this.dsName = dsName;
- this.connection = conn;
- }
當創建 DbExecutor 實例時,DbExecutorFactory 先從 ConnectionFactoryBuilder 獲得一個 ConnectionFactory 對象,然后從ConnectionFactory 獲取一個數據庫連接,用來創建 DbExecutor。當然,連接每個數據庫的 ConnectionFactory 對象只有一個。
ConnectionFactoryBuilder.java - build()
- publicsynchronized ConnectionFactory build(String dsName) throws ConfigErrorException {
- if (factoryCache.get(dsName) == null) {
- DataSourceCollection sources = Configurator.getDataSources();
- DataSource ds = sources.getDataSource(dsName);
- if (ds == null) {
- thrownew ConfigErrorException("沒有找到數據源 " + dsName);
- }
- factoryCache.put(dsName, buildFactory(ds));
- }
- return (ConnectionFactory) factoryCache.get(dsName);
- }
創建了一個 DAO 類用來做所有的事情,包括查詢。查詢方法如下:
java 代碼 - public?List?query(Class?clazz,?String?sql,?List?params)?throws?DAOException;??
第一個參數是用來接受封裝的類。 有時候僅查詢一個字段,根本不用封裝:
java 代碼 - public?List?query(String?sql,?List?params)?throws?DAOException;?
如果封裝,就要考慮查詢結果字段到對象屬性的映射關系。根據公司的數據庫設計規范, 單詞之間用下劃線連起來。所以簡單的替換一下就可以了。比如 USER_NAME 字段就映 射到 userName 屬性。
如果查詢結果中的字段有多,那這個字段的值就只好丟棄;如果類的屬性有多,也不會給 它賦值。
分頁查詢。有時候會用到分頁查詢,所以添加了一個方法:
java 代碼 - public?Page?queryPage(Class?clazz,?String?sql,?List?params,?int?pageIndex,?int?pageSize)??
- ????????????throws?DAOException;??
Page 對象除了包含查詢結果外還有 totalNum 屬性,表示查詢總結果數。
表格封裝的查詢。有時候查詢語句是動態生成的,沒法確定查詢結果的字段個數,用類來 封裝顯然不合適。于是定義了一個通用的表格結構用來封裝,并添加了 queryTable() 方法: java 代碼 ? - public?DataTable?queryTable(String?sql)?throws?DAOException;???
- public?DataTable?queryTable(String?sql,?List?params,?int?pageIndex,?int?pageSize)?????
- ???????????????? throws?DAOException;???
DataTable 對象包含的其實就是一堆 HashMap。不過它同 Page 一樣有一個查詢總結果數, 而且添加了一些方法方便提取數據。這種查詢的使用方式如下:
java 代碼 ? - DAO?dao?=?DAO.getDAO(SOURCE_NAME);??
- DataTable?table?=?dao.queryTable("select?*?from?tt_test");??
- assertEquals(6,?table.getColumns());??
- Map?row?=?table.query("name",?"張三豐");???
- assertNotNull(row);??
靜態字段作為映射關系配置。有些字典表或配置表,一開始就被全部讀入并緩存起來。為 了少寫代碼,DAO 提供將靜態字段 TN 作為表名來查詢的方式。如果類中存在 String 類型的 靜態字段 TN,則可以使用這個方法:
java 代碼 ? - public?List?query(Class?clazz)?throws?DAOException;?
|
沒有哪個 DAO 能夠包攬所有的數據庫管理。每種 DAO 都有各自的定位。我們公司的項目有這樣一些特點:
- 所用數據庫都是 Oracle;
- 使用一些已有的數據庫表;
- 查詢語句要經過優化,DBA 要對其字斟句酌;
- 同時連接多個數據庫。
我們的項目大都會用到一些其他系統現有的表。有的表包含四五十個字段,而對于某些業務邏輯來講只需要查詢一兩個字段的值。DBA 強烈反對“select * ”,對關聯查詢、嵌套查詢的性能要求也很嚴格。所以像 Hibernate 這樣自動生成 SQL 語句的 DAO 自然不敢用。我們需要自己設計一個 DAO。
本著夠用就行的原則,我們設計的 DAO (下面簡稱 DAO)先定下一個很低的目標:實現數據庫連接管理,SQL 語句由使用者提供,將查詢結果進行簡單的封裝。
數據庫連接管理的具體設計是:
1、使用 XML 配置文件配置數據庫連接;
2、支持 JDBC 和 JNDI(主要針對 WebLogic 的連接池) 兩種方式創建數據庫連接;
3、對同時連接多個數據庫進行管理;
4、使用者不需關心數據庫連接的創建和關閉。
對 XML 配置文件的設計:
??? DAO 配置文件用來配置數據庫連接。鑒于當前的目標,DAO 沒有映射關系配置。
??? 配置文件將數據庫抽象為“數據源”(DataSource),DAO 管理的是數據源。一個項目中可以存在多個數據源。數據源包含一個或多個連接配置,但運行時只會啟用其中的一個,這樣是為了方便修改配置,像 Rails 的 數據庫配置文件中同時配置了開發環境、測試環境和產品環境三中數據庫連接,一樣的道理。
??? 連接配置有 JNDI 和 JDBC 兩種類型,分別需要不同的參數。JNDI 配置需要 JNDI 服務器、InitialContextFactory 類和 JNDI 名稱三個參數,而JDBC 配置需要 Driver、url、用戶名和密碼四個參數。密碼暫時不考慮加密,采用明文的方式。下面是一個配置文件的例子:
xml 代碼
?
- <?xml?version="1.0"?encoding="GB2312"??>??
- <!DOCTYPE?dao-config?PUBLIC??
- ????????"-//Chinacreator,?Ltd.//Data?Access?Object?Library?1.2//CN"?"dao-config.dtd">??
- ??
- <dao-config>??
- ??
- ????<datasource?name="local_mysql"?connection="default">??
- ????????<description>數據源1</description>??
- ????????<connection?name="default"?type="jdbc">??
- ????????????<property?name="driver"?value="com.mysql.jdbc.Driver"/>??
- ????????????<property?name="url"?value="jdbc:mysql://localhost/test"/>??
- ????????????<property?name="username"?value="user"/>??
- ????????????<property?name="password"?value="user"/>??
- ????????</connection>??
- ????</datasource>??
- ??
- ????<datasource?name="demo"?connection="jdbc_connection">??
- ????????<description>數據源2</description>??
- ??
- ????????<connection?name="jndi_connection"?type="jndi">??
- ????????????<description>JNDI?方式</description>??
- ????????????<property?name="driver"?value="weblogic.jndi.WLInitialContextFactory"/>??
- ????????????<property?name="server"?value="t3://127.0.0.1:7010"/>??
- ????????????<property?name="jndiname"?value="jndi/name"/>??
- ????????</connection>??
- ??
- ????????<connection?name="jdbc_connection"?type="jdbc">??
- ????????????<description>JDBC?方式</description>??
- ????????????<property?name="driver"?value="oracle.jdbc.driver.OracleDriver"/>??
- ????????????<property?name="url"?value="jdbc:oracle:thin:@127.0.0.1:1521:SidName"/>??
- ????????????<property?name="username"?value="username"/>??
- ????????????<property?name="password"?value="password"/>??
- ????????</connection>??
- ??
- ????????<connection?name="pooled_jdbc"?type="jdbc">??
- ????????????<description>帶連接池的?JDBC?方式</description>??
- ????????????<property?name="driver"?value="oracle.jdbc.driver.OracleDriver"/>??
- ????????????<property?name="url"?value="jdbc:oracle:thin:@172.16.168.85:1521:ora9i01"/>??
- ????????????<property?name="username"?value="username"/>??
- ????????????<property?name="password"?value="password"/>??
- ????????????<property?name="usepool"?value="true"/>??
- ????????????<property?name="poolsize"?value="2"/>??
- ????????</connection>??
- ????</datasource>??
- </dao-config>??
??? 那么使用者如何使用 DAO 執行 SQL 呢?下面是一個最簡單的例子:
java 代碼
- DAO?dao?=?DAO.getDAO("demo");?
- List?list?=?dao.query("select?areaname?from?tb_pub_area_code");??
- assertEquals("長沙",?list.get(0));??
??? 在這個例子中,DAO 根據配置文件找到數據源“demo”(17行),再根據數據源的 connection 屬性找到名為
"jdbc_connection" 的連接配置(27行),然后連接到
"jdbc:oracle:thin:@127.0.0.1:1521:SidName" (30行)進行查詢。
下面是當前網頁應用程序應該出現的地方:
?
基于表單的交互
表單是很慢的,非常慢。嘗試編輯位于
del.icio.us
上面的一個書簽?點擊編輯鏈接打開一個編輯書簽的表單頁面,然后編輯你的內容并點擊提交按鈕等待整個提交過程結束,最后返回上一頁并向下滾動到你剛才編輯的書簽那里查看內容是否已經正確更改。那
AJAX
呢?點擊編輯鏈接馬上開始更改標簽內容,點擊提交按鈕開始異步傳輸標簽編輯的內容并立即看到更改后的內容而無需重載整個頁面。
?
深層樹狀導航
總而言之,帶有深層樹狀導航的應用程序通常是一個噩夢。在大多數情況中簡單平直的拓撲結構以及搜索
/
標記可以很好的工作。但是如果一個應用程序真正使用深層樹狀導航,使用
JavaScript
來管理拓撲
ui(user interface
用戶接口
)
,則使用
Ajax
懶加載深層數據可以降低服務器的負載。舉例來說,為了閱讀一個只有一行的結果來加載整個一個新頁面是非常耗時的。
?
實時用戶對用戶通訊
在一個允許用戶創建實時討論的信息公告系統中,
迫使用戶一次又一次的更新完頁面看到答復是非常愚蠢的。回復應該是實時的,用戶不應被迫總是去癡迷于刷新操作。即使是
gmail
這個已經對以前像
hotmail/yahoo mail
的收件箱刷新,刷新收件箱標記的操作有所改進,也并沒有充分的使用
Ajax
的功能來提示有新郵件到達。
?
投票、是否選擇、等級評價
如果
Ajax
提交過程沒有一個協調的
UI
提示是非常糟糕的,通過使用
Ajax
來提交一個調查或是否選擇可以減少提交過程等待的痛苦。通過減少點擊的等待時間,
Ajax
應用程序變得越來越有交互性
-
如果要用
40
秒來提交一個投票,除非非常在意的話大多數人會選擇放棄。如果只花
1
秒呢,非常大比例的人會樂于參加投票的。(我在
Netflix versus
有
2008
張電影投票在
IMDb.com
有
210
張電影投票)
?
過濾和復雜數據操作
應用一個過濾、按日期排序、按日期和姓名排序、打開或關閉過濾器等等。任何一種高交換型操作應該交給
JavaScript
來處理而不是通過向服務器來提交一系列的請求。在查找或者操作大量數據的時候帶來的視圖上的改變最多不會超過
30
秒,
Ajax
真的使這些操作加速了。
?
普通錄入時的提示/
自動補齊
一些軟件
/JavaScript
是擅長于幫助用戶完成鍵入相同的文字或可以預測的文字的工作的。在
del.icio.us
和
Gmail
中該功能是非常有益的,可以用來快速增加標記
/email
等。
?
對于一個頻繁使用的應用程序諸如網頁郵件客戶端或博客閱讀器來說,用戶有充足的時間來學習如何使用新的UI概念但是他們卻無法接受一個非常緩慢的反應速度。這種應用為Ajax變的更加普及起到了一個完美的杠桿作用。隨著用戶使用頻率的增加,更多的Ajax部件應該加強用戶的使用體驗。
但是對于網頁應用程序來說,把每件事甚至任何事都用JavaScript來實現也是沒有意義的。Ajax只是針對一些特定的環境才能帶來顯著的幫助。在Ajax出現之前網頁應用程序已經可以工作的很好了并且目前在網頁開發中Ajax還存在著許多的缺陷和缺點。就算不從服務器端取得一個異步的信息數據流一個平直的html網頁日志也可以工作的很好。對于文檔或文檔之間的跳轉來說,老舊的純HTML仍然是最好的選擇。簡單或很少使用的應用程序就算不用JavaScript同樣可以很好的工作。
?
下面是一些不應該用到Ajax
的地方:
?
簡單的表單
就算表單是
Ajax
技術的最大受益人,一個簡單內容的表單,或提交訂貨單,或一次性的很少用到的表單都不應該使用以
Ajax
驅動的表單提交機制。總的來說,如果一個表單不是很長用,或已經工作的很好,那么就算使用
Ajax
也沒有什么幫助。
?
搜索
實時搜索帶來的痛苦要遠大于他帶來的幫助。這就是為什么
Google Suggest
還處于
beta
測試而并沒有放在主頁上的原因。在
Start.com Live.com
上搜索的時候你是不能使用返回按鈕來查看上一次搜索或返回上一頁的。或許還沒有人來完成這項工作,但是完成這個工作應該是很困難的至少是不太明知的或者會因此帶來更多的麻煩。(譯注:現在已經有很多開源的框架可以實現歷史記錄功能)
?
基本導航
總的來說,使用
Ajax
為一個基礎的網站
/
程序做導航是一個可怕的念頭。誰會把用來使自己的程序變的更好的時間花在編寫代碼模仿瀏覽器的行為上面?在基礎頁面中導航的操作中
JavaScript
是沒有用的。
?
替換大量的信息
Ajax
可以不用整頁刷新來動態更新頁面中改變的一小部分。但是如果一頁上的大部分內容都需要更新,那為什么不從服務器那里獲得一個新頁面呢?
?
顯示操作
雖然看上去
Ajax
是一個純
UI
技術,其實不是這樣的。他實際上是一個數據同步、操作、傳輸的技術。要想得到一個穩定的干凈的網頁程序,不使用
Ajax/JavaScript來直接完成用戶接口是明智的。JavaScript可以分散分布并簡單的操作XHTML/HTML DOM,根據CSS規則來決定如何讓UI顯示數據。查看
來查看如何使用
CSS
來替代
JavaScript
來控制數據的顯示。
?
無用的網頁小部件
滑塊選擇控件、拖拽控件、彈性控件(此處原文為
bouncies
,不知指為何物?)、鼠標樣式、天氣預報控件,這些小部件應該可以被更直接的控件代替或者為了整潔干脆整個去掉。為了選擇一種顏色,也許滑塊選擇控件可以選擇一個正確的陰影顏色,但是在一個商店中選擇一個價格,使用滑塊選擇控件選到分這個單位對于用戶來說有點過分。
建立表:
CREATE TABLE [TestTable] (
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[FirstName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
[LastName] [nvarchar] (100) COLLATE Chinese_PRC_CI_AS NULL ,
[Country] [nvarchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Note] [nvarchar] (2000) COLLATE Chinese_PRC_CI_AS NULL
) ON [PRIMARY]
GO
插入數據:(2萬條,用更多的數據測試會明顯一些)
SET IDENTITY_INSERT TestTable ON
declare @i int
set @i=1
while @i<=20000
begin
insert into TestTable([id], FirstName, LastName, Country,Note) values(@i, 'FirstName_XXX','LastName_XXX','Country_XXX','Note_XXX')
set @i=@i+1
end
SET IDENTITY_INSERT TestTable OFF
-------------------------------------
分頁方案一:(利用Not In和SELECT TOP分頁)
語句形式:
SELECT TOP 10 *
FROM TestTable
WHERE (ID NOT IN
(SELECT TOP 20 id
FROM TestTable
ORDER BY id))
ORDER BY ID
SELECT TOP 頁大小 *
FROM TestTable
WHERE (ID NOT IN
(SELECT TOP 頁大小*頁數 id
FROM 表
ORDER BY id))
ORDER BY ID
-------------------------------------
分頁方案二:(利用ID大于多少和SELECT TOP分頁)
語句形式:
SELECT TOP 10 *
FROM TestTable
WHERE (ID >
(SELECT MAX(id)
FROM (SELECT TOP 20 id
FROM TestTable
ORDER BY id) AS T))
ORDER BY ID
SELECT TOP 頁大小 *
FROM TestTable
WHERE (ID >
(SELECT MAX(id)
FROM (SELECT TOP 頁大小*頁數 id
FROM 表
ORDER BY id) AS T))
ORDER BY ID
-------------------------------------
分頁方案三:(利用SQL的游標存儲過程分頁)
create procedure XiaoZhengGe
@sqlstr nvarchar(4000), --查詢字符串
@currentpage int, --第N頁
@pagesize int --每頁行數
as
set nocount on
declare @P1 int, --P1是游標的id
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
select ceiling(1.0*@rowcount/@pagesize) as 總頁數--,@rowcount as 總行數,@currentpage as 當前頁
set @currentpage=(@currentpage-1)*@pagesize+1
exec sp_cursorfetch @P1,16,@currentpage,@pagesize
exec sp_cursorclose @P1
set nocount off
其它的方案:如果沒有主鍵,可以用臨時表,也可以用方案三做,但是效率會低。
建議優化的時候,加上主鍵和索引,查詢效率會提高。
通過SQL 查詢分析器,顯示比較:我的結論是:
分頁方案二:(利用ID大于多少和SELECT TOP分頁)效率最高,需要拼接SQL語句
分頁方案一:(利用Not In和SELECT TOP分頁) 效率次之,需要拼接SQL語句
分頁方案三:(利用SQL的游標存儲過程分頁) 效率最差,但是最為通用
在實際情況中,要具體分析。
這些天開發一個項目,服務器是tomcat,操作系統是xp,采用的是MVC架構,模式是采用Facade模式,總是出現亂碼,自己也解決了好多 天,同事也幫忙解決,也參考了網上眾多網友的文章和意見,總算是搞定。但是好記性不如爛筆桿,所以特意記下,以防止自己遺忘,同時也給那些遇到同樣問題的 人提供一個好的參考途徑:
(一) JSP頁面上是中文,但是看的是后是亂碼:
解決的辦法就是在JSP頁面的編碼的地方<%@ page language="java" contentType="text/html;charset=GBK" %>,因為Jsp轉成Java文件時的編碼問題,默認的話有的服務器是ISO-8859-1,如果一個JSP中直接輸入了中文,Jsp把它當作 ISO8859-1來處理是肯定有問題的,這一點,我們可以通過查看Jasper所生成的Java中間文件來確認
(二) 當用Request對象獲取客戶提交的漢字代碼的時候,會出現亂碼:
解決的辦法是:要配置一個filter,也就是一個Servelet的過濾器,代碼如下:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
/**
* Example filter that sets the character encoding to be used in parsing the
* incoming request
*/
public class SetCharacterEncodingFilter implements Filter {
/**
* Take this filter out of service.
*/
public void destroy() {
}
/**
* Select and set (if specified) the character encoding to be used to
* interpret request parameters for this request.
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)throws IOException, ServletException {
request.setCharacterEncoding("GBK");
// 傳遞控制到下一個過濾器
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
配置web.xml
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>SetCharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果你的還是出現這種情況的話你就往下看看是不是你出現了第四中情況,你的Form提交的數據是不是用get提交的,一般來說用post提交的話是沒有問題的,如果是的話,你就看看第四中解決的辦法。
還有就是對含有漢字字符的信息進行處理,處理的代碼是:
package dbJavaBean;
public class CodingConvert
{
public CodingConvert()
{
//
}
public String toGb(String uniStr){
String gbStr = "";
if(uniStr == null){
uniStr = "";
}
try{
byte[] tempByte = uniStr.getBytes("ISO8859_1");
gbStr = new String(tempByte,"GB2312");
}
catch(Exception ex){
}
return gbStr;
}
public String toUni(String gbStr){
String uniStr = "";
if(gbStr == null){
gbStr = "";
}
try{
byte[] tempByte = gbStr.getBytes("GB2312");
uniStr = new String(tempByte,"ISO8859_1");
}catch(Exception ex){
}
return uniStr;
}
}
你也可以在直接的轉換,首先你將獲取的字符串用ISO-8859-1進行編碼,然后將這個編碼存放到一個字節數組中,然后將這個數組轉化成字符串對象就可以了,例如:
String str=request.getParameter(“girl”);
Byte B[]=str.getBytes(“ISO-8859-1”);
Str=new String(B);
通過上述轉換的話,提交的任何信息都能正確的顯示。
(三) 在Formget請求在服務端用request. getParameter(“name”)時返回的是亂碼;按tomcat的做法設置Filter也沒有用或者用 request.setCharacterEncoding("GBK");也不管用問題是出在處理參數傳遞的方法上:如果在servlet中用 doGet(HttpServletRequest request, HttpServletResponse response)方法進行處理的話前面即使是寫了:
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
也是不起作用的,返回的中文還是亂碼!!!如果把這個函數改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。
同樣,在用兩個JSP頁面處理表單輸入之所以能顯示中文是因為用的是post方法傳遞的,改成get方法依舊不行。
由此可見在servlet中用doGet()方法或是在JSP中用get方法進行處理要注意。這畢竟涉及到要通過瀏覽器傳遞參數信息,很有可能引起常用字符集的沖突或是不匹配。
解決的辦法是:
1) 打開tomcat的server.xml文件,找到區塊,加入如下一行:
URIEncoding=”GBK”
完整的應如下:
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/>
2)重啟tomcat,一切OK。
需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的這個文件就可以知道原因了。需要注意的是:這 個地方如果你要是用UTF-8的時候在傳遞的過程中在Tomcat中也是要出現亂碼的情況,如果不行的話就換別的字符集。
(四) JSP頁面上有中文,按鈕上面也有中文,但是通過服務器查看頁面的時候出現亂碼:
解決的辦法是:首先在JSP文件中不應該直接包含本地化的消息文本,而是應該通過<bean:message>標簽從Resource Bundle中獲得文本。應該把你的中文文本放到Application.properties文件中,這個文件放在WEB-INF/classes/* 下,例如我在頁面里有姓名,年齡兩個label,我首先就是要建一個Application.properties,里面的內容應該是name=”姓名” age=”年齡”,然后我把這個文件放到WEB-INF/classes/properties/下,接下來根據 Application.properties文件,對他進行編碼轉化,創建一個中文資源文件,假定名字是 Application_cn.properties。在JDK中提供了native2ascii命令,他能夠實現字符編碼的轉換。在DOS環境中找到你 放置Application.properties的這個文件的目錄,在DOS環境中執行一下命令,將生成按GBK編碼的中文資源文件 Application_cn.properties:native2ascii ?Cencoding gbk Application.properties Application_cn.properties執行以上命令以后將生成如下內容的Application_cn.properties文件: name=\u59d3\u540d age=\u5e74\u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"/>。到這一步,基本上完成了一大半,接著你就要在JSP頁面上寫 <%@ page language="java" contentType="text/html;charset=GBK" %>,到名字的那個label是要寫<bean:message key=”name”>,這樣的化在頁面上出現的時候就會出現中文的姓名,年齡這個也是一樣,按鈕上漢字的處理也是同樣的。
(五) 寫入到數據庫是亂碼:
解決的方法:要配置一個filter,也就是一個Servelet的過濾器,代碼如同第二種時候一樣。
如果你是通過JDBC直接鏈接數據庫的時候,配置的代碼如下:jdbc:mysql://localhost:3306/workshopdb? useUnicode=true&characterEncoding=GBK,這樣保證到數據庫中的代碼是不是亂碼。
如果你是通過數據源鏈接的化你不能按照這樣的寫法了,首先你就要寫在配置文件中,在tomcat 5.0.19中配置數據源的地方是在C:\Tomcat 5.0\conf\Catalina\localhost這個下面,我建立的工程是workshop,放置的目錄是webapp下面, workshop.xml的配置文件如下:
<!-- insert this Context element into server.xml -->
<Context path="/workshop" docBase="workshop" debug="0"
reloadable="true" >
<Resource name="jdbc/WorkshopDB"
auth="Container"
type="javax.sql.DataSource" />
<ResourceParams name="jdbc/WorkshopDB">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<parameter>
<name>username</name>
<value>root</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<!-- Class name for mm.mysql JDBC driver -->
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value><![CDATA[jdbc:mysql://localhost:3306/workshopdb
?useUnicode=true&characterEncoding=GBK]]></value>
</parameter>
</ResourceParams>
</Context>
粗體的地方要特別的注意,和JDBC直接鏈接的時候是有區別的,如果你是配置正確的化,當你輸入中文的時候到數據庫中就是中文了,有一點要注意的是你在顯 示數據的頁面也是要用<%@ page language="java" contentType="text/html;charset=GBK" %>這行代碼的。需要注意的是有的前臺的人員在寫代碼的是后用Dreamver寫的,寫了一個Form的時候把他改成了一個jsp,這樣有一個地方 要注意了,那就是在Dreamver中Action的提交方式是request的,你需要把他該過來,因為在jsp的提交的過程中緊緊就是POST和 GET兩種方式,但是這兩種方式提交的代碼在編碼方面還是有很大不同的,這個在后面的地方進行說明。3
以上就是我在開發系統中解決中文的問題,不知道能不能解決大家的問題,時間匆忙,沒有及時完善,文筆也不是很好,有些地方估計是詞不達意。大家可以給我意見,希望能共同進步。
Oracle數據庫有三種標準的備份方法,它們分別是導出/導入(EXP/IMP)、熱備份和冷備份。導出備件是一種邏輯備份,冷備份和熱備份是物理備份。
一、 導出/導入(Export/Import)
利用Export可將數據從數據庫中提取出來,利用Import則可將提取出來的數據送回到Oracle數據庫中去。
1、 簡單導出數據(Export)和導入數據(Import)
Oracle支持三種方式類型的輸出:
(1)、表方式(T方式),將指定表的數據導出。
(2)、用戶方式(U方式),將指定用戶的所有對象及數據導出。
(3)、全庫方式(Full方式),瘵數據庫中的所有對象導出。
數據導入(Import)的過程是數據導出(Export)的逆過程,分別將數據文件導入數據庫和將數據庫數據導出到數據文件。
2、 增量導出/導入
增量導出是一種常用的數據備份方法,它只能對整個數據庫來實施,并且必須作為SYSTEM來導出。在進行此種導出時,系統不要求回答任何問題。導出文件名缺省為export.dmp,如果不希望自己的輸出文件定名為export.dmp,必須在命令行中指出要用的文件名。
增量導出包括三種類型:
(1)、“完全”增量導出(Complete)
即備份三個數據庫,比如:
exp system/manager inctype=complete file=040731.dmp
(2)、“增量型”增量導出
備份上一次備份后改變的數據,比如:
exp system/manager inctype=incremental file=040731.dmp
(3)、“累積型”增量導出
累計型導出方式是導出自上次“完全”導出之后數據庫中變化了的信息。比如:
exp system/manager inctype=cumulative file=040731.dmp
數據庫管理員可以排定一個備份日程表,用數據導出的三個不同方式合理高效的完成。
比如數據庫的被封任務可以做如下安排:
星期一:完全備份(A)
星期二:增量導出(B)
星期三:增量導出(C)
星期四:增量導出(D)
星期五:累計導出(E)
星期六:增量導出(F)
星期日:增量導出(G)
如果在星期日,數據庫遭到意外破壞,數據庫管理員可按一下步驟來回復數據庫:
第一步:用命令CREATE DATABASE重新生成數據庫結構;
第二步:創建一個足夠大的附加回滾。
第三步:完全增量導入A:
imp system/manager inctype=RESTORE FULL=y FILE=A
第四步:累計增量導入E:
imp system/manager inctype=RESTORE FULL=Y FILE=E
第五步:最近增量導入F:
imp system/manager inctype=RESTORE FULL=Y FILE=F
二、 冷備份
冷備份發生在數據庫已經正常關閉的情況下,當正常關閉時會提供給我們一個完整的數據庫。冷備份時將關鍵性文件拷貝到另外的位置的一種說法。對于備份Oracle信息而言,冷備份時最快和最安全的方法。冷備份的優點是:
1、 是非常快速的備份方法(只需拷文件)
2、 容易歸檔(簡單拷貝即可)
3、 容易恢復到某個時間點上(只需將文件再拷貝回去)
4、 能與歸檔方法相結合,做數據庫“最佳狀態”的恢復。
5、 低度維護,高度安全。
但冷備份也有如下不足:
1、 單獨使用時,只能提供到“某一時間點上”的恢復。
2、 再實施備份的全過程中,數據庫必須要作備份而不能作其他工作。也就是說,在冷備份過程中,數據庫必須是關閉狀態。
3、 若磁盤空間有限,只能拷貝到磁帶等其他外部存儲設備上,速度會很慢。
4、 不能按表或按用戶恢復。
如果可能的話(主要看效率),應將信息備份到磁盤上,然后啟動數據庫(使用戶可以工作)并將備份的信息拷貝到磁帶上(拷貝的同時,數據庫也可以工作)。冷備份中必須拷貝的文件包括:
1、 所有數據文件
2、 所有控制文件
3、 所有聯機REDO LOG文件
4、 Init.ora文件(可選)
值得注意的使冷備份必須在數據庫關閉的情況下進行,當數據庫處于打開狀態時,執行數據庫文件系統備份是無效的。
下面是作冷備份的完整例子。
(1) 關閉數據庫
sqlplus /nolog
sql>connect /as sysdba
sql>shutdown normal;
(2) 用拷貝命令備份全部的時間文件、重做日志文件、控制文件、初始化參數文件
sql>cp
(3) 重啟Oracle數據庫
sql>startup
三、 熱備份
熱備份是在數據庫運行的情況下,采用archivelog mode方式備份數據庫的方法。所以,如果你有昨天夜里的一個冷備份而且又有今天的熱備份文件,在發生問題時,就可以利用這些資料恢復更多的信息。熱備份要求數據庫在Archivelog方式下操作,并需要大量的檔案空間。一旦數據庫運行在archivelog狀態下,就可以做備份了。熱備份的命令文件由三部分組成:
1. 數據文件一個表空間一個表空間的備份。
(1) 設置表空間為備份狀態
(2) 備份表空間的數據文件
(3) 回復表空間為正常狀態
2. 備份歸檔log文件
(1) 臨時停止歸檔進程
(2) log下那些在archive rede log目標目錄中的文件
(3) 重新啟動archive進程
(4) 備份歸檔的redo log文件
3. 用alter database bachup controlfile命令來備份控制文件
熱備份的優點是:
1. 可在表空間或數據庫文件級備份,備份的時間短。
2. 備份時數據庫仍可使用。
3. 可達到秒級恢復(恢復到某一時間點上)。
4. 可對幾乎所有數據庫實體做恢復
5. 恢復是快速的,在大多數情況下愛數據庫仍工作時恢復。
熱備份的不足是:
1. 不能出錯,否則后果嚴重
2. 若熱備份不成功,所得結果不可用于時間點的恢復
3. 因難于維護,所以要特別仔細小心,不允許“以失敗告終”。
?代碼清單
import java.io.*;
import java.net.*;
import java.util.*;
/**
* <p>title: 個人開發的api</p>
* <p>description: 將指定的http網絡資源在本地以文件形式存放</p>
* <p>copyright: copyright (c) 2004</p>
* <p>company: newsky</p>
* @author magicliao
* @version 1.0
*/
public class httpget {
public final static boolean debug = true;//調試用
private static int buffer_size = 8096;//緩沖區大小
private vector vdownload = new vector();//url列表
private vector vfilelist = new vector();//下載后的保存文件名列表
/**
* 構造方法
*/
public httpget() {
}
/**
* 清除下載列表
*/
public void resetlist() {
vdownload.clear();
vfilelist.clear();
}
/**
* 增加下載列表項
*
* @param url string
* @param filename string
*/
public void additem(string url, string filename) {
vdownload.add(url);
vfilelist.add(filename);
}
/**
* 根據列表下載資源
*/
public void downloadbylist() {
string url = null;
string filename = null;
//按列表順序保存資源
for (int i = 0; i < vdownload.size(); i++) {
url = (string) vdownload.get(i);
filename = (string) vfilelist.get(i);
try {
savetofile(url, filename);
}
catch (ioexception err) {
if (debug) {
system.out.println("資源[" + url + "]下載失敗!!!");
}
}
}
if (debug) {
system.out.println("下載完成!!!");
}
}
/**
* 將http資源另存為文件
*
* @param desturl string
* @param filename string
* @throws exception
*/
public void savetofile(string desturl, string filename) throws ioexception {
fileoutputstream fos = null;
bufferedinputstream bis = null;
httpurlconnection httpurl = null;
url url = null;
byte[] buf = new byte[buffer_size];
int size = 0;
//建立鏈接
url = new url(desturl);
httpurl = (httpurlconnection) url.openconnection();
//連接指定的資源
httpurl.connect();
//獲取網絡輸入流
bis = new bufferedinputstream(httpurl.getinputstream());
//建立文件
fos = new fileoutputstream(filename);
if (this.debug)
system.out.println("正在獲取鏈接[" + desturl + "]的內容...\n將其保存為文件[" + filename + "]");
//保存文件
while ( (size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
fos.close();
bis.close();
httpurl.disconnect();
}
/**
* 設置代理服務器
*
* @param proxy string
* @param proxyport string
*/
public void setproxyserver(string proxy, string proxyport) {
//設置代理服務器
system.getproperties().put("proxyset", "true");
system.getproperties().put("proxyhost", proxy);
system.getproperties().put("proxyport", proxyport);
}
/**
* 設置認證用戶名與密碼
*
* @param uid string
* @param pwd string
*/
public void setauthenticator(string uid, string pwd) {
authenticator.setdefault(new myauthenticator(uid, pwd));
}
/**
* 主方法(用于測試)
*
* @param argv string[]
*/
public static void main(string argv[]) {
httpget oinstance = new httpget();
try {
//增加下載列表(此處用戶可以寫入自己代碼來增加下載列表)
oinstance.additem("http://www.ebook.com/java/網絡編程001.zip","./網絡編程1.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程002.zip","./網絡編程2.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程003.zip","./網絡編程3.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程004.zip","./網絡編程4.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程005.zip","./網絡編程5.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程006.zip","./網絡編程6.zip");
oinstance.additem("http://www.ebook.com/java/網絡編程007.zip","./網絡編程7.zip");
//開始下載
oinstance.downloadbylist();
}
catch (exception err) {
system.out.println(err.getmessage());
}
}
}