欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語言bigint go語言適合做什么

【深度知識(shí)】以太坊數(shù)據(jù)序列化RLP編碼/解碼原理

RLP(Recursive Length Prefix),中文翻譯過來叫遞歸長(zhǎng)度前綴編碼,它是以太坊序列化所采用的編碼方式。RLP主要用于以太坊中數(shù)據(jù)的網(wǎng)絡(luò)傳輸和持久化存儲(chǔ)。

創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營(yíng)銷推廣、網(wǎng)站重做改版、大觀網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、html5商城建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為大觀等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

對(duì)象序列化方法有很多種,常見的像JSON編碼,但是JSON有個(gè)明顯的缺點(diǎn):編碼結(jié)果比較大。例如有如下的結(jié)構(gòu):

變量s序列化的結(jié)果是{"name":"icattlecoder","sex":"male"},字符串長(zhǎng)度35,實(shí)際有效數(shù)據(jù)是icattlecoder 和male,共計(jì)16個(gè)字節(jié),我們可以看到JSON的序列化時(shí)引入了太多的冗余信息。假設(shè)以太坊采用JSON來序列化,那么本來50GB的區(qū)塊鏈可能現(xiàn)在就要100GB,當(dāng)然實(shí)際沒這么簡(jiǎn)單。

所以,以太坊需要設(shè)計(jì)一種結(jié)果更小的編碼方法。

RLP編碼的定義只處理兩類數(shù)據(jù):一類是字符串(例如字節(jié)數(shù)組),一類是列表。字符串指的是一串二進(jìn)制數(shù)據(jù),列表是一個(gè)嵌套遞歸的結(jié)構(gòu),里面可以包含字符串和列表,例如["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]就是一個(gè)復(fù)雜的列表。其他類型的數(shù)據(jù)需要轉(zhuǎn)成以上的兩類,轉(zhuǎn)換的規(guī)則不是RLP編碼定義的睜和,可以根據(jù)自己的規(guī)則轉(zhuǎn)換,例如struct可以轉(zhuǎn)成列表,int可以轉(zhuǎn)成二進(jìn)制(屬于字符串一類),以太坊中整數(shù)都以大端形式存儲(chǔ)。

從RLP編碼的名字可以看出它的特點(diǎn):一個(gè)是遞歸,被編碼的數(shù)據(jù)是遞歸的結(jié)構(gòu),編碼算法也是遞歸高早畝進(jìn)行處理的;二是長(zhǎng)度前綴,也就是RLP編碼都帶有一個(gè)前綴,這個(gè)前綴是跟被編碼數(shù)據(jù)的長(zhǎng)度相關(guān)的,從下面的編碼規(guī)則中可以看出這一點(diǎn)。

對(duì)于值在[0, 127]之間的單個(gè)字節(jié),其編碼是其本身。

例1:a的編碼是97。

如果byte數(shù)組長(zhǎng)度l = 55,編碼的結(jié)果是數(shù)組本身,再加上128+l作為前綴。

例2:空字符串編碼是128,即128 = 128 + 0。

例3:abc編碼結(jié)果是131 97 98 99,其中131=128+len("abc"),97 98 99依次是a b c。

如果數(shù)組長(zhǎng)度大于55, 編碼結(jié)果第一個(gè)是183加數(shù)組長(zhǎng)度的編碼的長(zhǎng)度,然后是數(shù)組長(zhǎng)度的本身的編碼,最后是byte數(shù)組的編碼。

請(qǐng)把上面的規(guī)則多讀幾篇,特別是數(shù)組長(zhǎng)度的編碼的長(zhǎng)度。

例4:編碼下面這段字符串:

The length of this sentence is more than 55 bytes, I know it because I pre-designed it

這段字符串共86個(gè)字節(jié),而86的編碼只需要一個(gè)字節(jié),那就是它自己,因此,編碼的結(jié)果如下:

184 86 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前三個(gè)字節(jié)的計(jì)算方式如下:

184 = 183 + 1,因?yàn)閿?shù)組長(zhǎng)度86編碼后僅占用一個(gè)字節(jié)。

86即數(shù)組長(zhǎng)度86

84是T的編碼

例5:編碼一個(gè)重復(fù)1024次"a"的字符串,其結(jié)果為:185 4 0 97 97 97 97 97 97 ...。

1024按 big endian編碼為0 0 4 0,省略掉前面的零,長(zhǎng)度為2,因此185 = 183 + 2。

規(guī)則1~3定義了byte數(shù)組的編碼方案,下面介紹列表的編碼規(guī)則。在此之前,我們先定義列表長(zhǎng)度是指子列表編碼后的長(zhǎng)度之和。

如果列表戚森長(zhǎng)度小于55,編碼結(jié)果第一位是192加列表長(zhǎng)度的編碼的長(zhǎng)度,然后依次連接各子列表的編碼。

注意規(guī)則4本身是遞歸定義的。

例6:["abc", "def"]的編碼結(jié)果是200 131 97 98 99 131 100 101 102。

其中abc的編碼為131 97 98 99,def的編碼為131 100 101 102。兩個(gè)子字符串的編碼后總長(zhǎng)度是8,因此編碼結(jié)果第一位計(jì)算得出:192 + 8 = 200。

如果列表長(zhǎng)度超過55,編碼結(jié)果第一位是247加列表長(zhǎng)度的編碼長(zhǎng)度,然后是列表長(zhǎng)度本身的編碼,最后依次連接各子列表的編碼。

規(guī)則5本身也是遞歸定義的,和規(guī)則3相似。

例7:

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

的編碼結(jié)果是:

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

其中前兩個(gè)字節(jié)的計(jì)算方式如下:

248 = 247 +1

88 = 86 + 2,在規(guī)則3的示例中,長(zhǎng)度為86,而在此例中,由于有兩個(gè)子字符串,每個(gè)子字符串本身的長(zhǎng)度的編碼各占1字節(jié),因此總共占2字節(jié)。

第3個(gè)字節(jié)179依據(jù)規(guī)則2得出179 = 128 + 51

第55個(gè)字節(jié)163同樣依據(jù)規(guī)則2得出163 = 128 + 35

例8:最后我們?cè)賮砜磦€(gè)稍復(fù)雜點(diǎn)的例子以加深理解遞歸長(zhǎng)度前綴,

["abc",["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]]

編碼結(jié)果是:

248 94 131 97 98 99 248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

列表第一項(xiàng)字符串a(chǎn)bc根據(jù)規(guī)則2,編碼結(jié)果為131 97 98 99,長(zhǎng)度為4。

列表第二項(xiàng)也是一個(gè)列表項(xiàng):

["The length of this sentence is more than 55 bytes, ", "I know it because I pre-designed it"]

根據(jù)規(guī)則5,結(jié)果為

248 88 179 84 104 101 32 108 101 110 103 116 104 32 111 102 32 116 104 105 115 32 115 101 110 116 101 110 99 101 32 105 115 32 109 111 114 101 32 116 104 97 110 32 53 53 32 98 121 116 101 115 44 32 163 73 32 107 110 111 119 32 105 116 32 98 101 99 97 117 115 101 32 73 32 112 114 101 45 100 101 115 105 103 110 101 100 32 105 116

長(zhǎng)度為90,因此,整個(gè)列表的編碼結(jié)果第二位是90 + 4 = 94, 占用1個(gè)字節(jié),第一位247 + 1 = 248

以上5條就是RPL的全部編碼規(guī)則。

各語言在具體實(shí)現(xiàn)RLP編碼時(shí),首先需要將對(duì)像映射成byte數(shù)組或列表兩種形式。以go語言編碼struct為例,會(huì)將其映射為列表,例如Student這個(gè)對(duì)象處理成列表["icattlecoder","male"]

如果編碼map類型,可以采用以下列表形式:

[["",""],["",""],["",""]]

解碼時(shí),首先根據(jù)編碼結(jié)果第一個(gè)字節(jié)f的大小,執(zhí)行以下的規(guī)則判斷:

1. 如果f∈ [0,128), 那么它是一個(gè)字節(jié)本身。

2. 如果f∈[128,184),那么它是一個(gè)長(zhǎng)度不超過55的byte數(shù)組,數(shù)組的長(zhǎng)度為 l=f-128

3. 如果f∈[184,192),那么它是一個(gè)長(zhǎng)度超過55的數(shù)組,長(zhǎng)度本身的編碼長(zhǎng)度ll=f-183,然后從第二個(gè)字節(jié)開始讀取長(zhǎng)度為ll的bytes,按照BigEndian編碼成整數(shù)l,l即為數(shù)組的長(zhǎng)度。

4. 如果f∈(192,247],那么它是一個(gè)編碼后總長(zhǎng)度不超過55的列表,列表長(zhǎng)度為l=f-192。遞歸使用規(guī)則1~4進(jìn)行解碼。

5. 如果f∈(247,256],那么它是編碼后長(zhǎng)度大于55的列表,其長(zhǎng)度本身的編碼長(zhǎng)度ll=f-247,然后從第二個(gè)字節(jié)讀取長(zhǎng)度為ll的bytes,按BigEndian編碼成整數(shù)l,l即為子列表長(zhǎng)度。然后遞歸根據(jù)解碼規(guī)則進(jìn)行解碼。

以上解釋了什么叫遞歸長(zhǎng)度前綴編碼,這個(gè)名字本身很好的解釋了編碼規(guī)則。

(1) 以太坊源碼學(xué)習(xí)—RLP編碼( )

(2)簡(jiǎn)單分析RLP編碼原理

( )

什么是數(shù)據(jù)庫?

什么是數(shù)據(jù)庫?

數(shù)據(jù)庫是以某種文件結(jié)構(gòu)存儲(chǔ)的一系列信息表,這種文件結(jié)構(gòu)使您能夠訪問這些表、選擇表中的列、對(duì)表進(jìn)行排序以及根據(jù)各種標(biāo)準(zhǔn)選擇行。數(shù)據(jù)庫通常有多個(gè) 索引與這些表中的許多列相關(guān)聯(lián),所以我們能盡可能快地訪問這些表。

以員工記錄為例,您可以設(shè)想一個(gè)含有員工姓名、地址、工資、扣稅以及津貼等內(nèi)容的表。讓我們考慮一下這些內(nèi)容可能如何組織在一起。您可以設(shè)想一個(gè)表包含員工姓名、地址和Tel 號(hào)碼。您希望保存的其它信息可能包括工資、工資范圍、上次加薪時(shí)間、下次加薪時(shí)間、員工業(yè)績(jī)?cè)u(píng)定等內(nèi)容。

這些內(nèi)容是否應(yīng)保存在一個(gè)表格中?幾乎可以肯定不應(yīng)該如此。不同類別的員工的工資范圍可能沒有區(qū)別;這樣,您可以僅將員工類型儲(chǔ)存在員工記錄表中,而將工資范圍儲(chǔ)存在另一個(gè)表中,通過類型編號(hào)與這個(gè)表關(guān)聯(lián)。考慮以下情況:

Key Lastname SalaryType SalaryType Min Max

1 Adams 2 1 30000 45000

2 Johnson 1 2 45000 60000

3 Smyth 3 3 60000 75000

4 Tully 1

5 Wolff 2

SalaryType 列中的數(shù)據(jù)引用第二個(gè)表。我們可以想象出許多種這樣的表,如用于存儲(chǔ)居住城市和每個(gè)城市的稅值陵衫、健康計(jì)劃扣除金額等的表。每個(gè)表都有一個(gè)主鍵列(如上面兩個(gè)表中最左邊的列)和若干數(shù)據(jù)列。在數(shù)據(jù)庫中建立表格既是一門藝術(shù),也是一門科學(xué)。這些表的結(jié)構(gòu)由它們的范式指出。我們通常說表屬于1NF、2NF 或 3NF。

第一范式:表中的每個(gè)表元應(yīng)該只有一個(gè)值(永遠(yuǎn)不可伏數(shù)能是一個(gè)數(shù)組)。(1NF)

第二范式:滿足 1NF,并且每一個(gè)非主鍵列完全依賴于主鍵列。這表示主鍵和該行中的剩余表元之間是 1 對(duì) 1 的關(guān)系。(2NF)

第三范式:滿足 2NF,并且所有非主鍵列是互相獨(dú)立的。任何一個(gè)數(shù)據(jù)列中包含的值都不能從其他列的數(shù)據(jù)計(jì)算得到。(3NF)

現(xiàn)在,幾乎所有的數(shù)據(jù)庫都是基于“第三范式 (3NF)”創(chuàng)建的。這意味著通常都有相當(dāng)多的表,每個(gè)表中的信息列都相對(duì)較少。

從數(shù)據(jù)庫中獲取數(shù)據(jù)

假設(shè)我們希望生成一個(gè)包含員工及其工資范圍的表,在我們?cè)O(shè)計(jì)的一個(gè)練習(xí)中將使用這個(gè)表。這個(gè)表格不是直接存在在數(shù)據(jù)庫中,但可以通過向數(shù)據(jù)庫發(fā)出一個(gè)查詢來構(gòu)建它。我們希望得到如下所示的一個(gè)表:

Name Min Max

Tully $30,000.00 $45,000.00

Johnson $30,000.00 $45,000.00

Wolff $45,000.00 $60,000.00

Adams $45,000.00 $60,000.00

Smyth $60,000.00 $75,000.00

我們發(fā)現(xiàn),獲得這些表的查詢形式如下所示

SELECT DISTINCTROW Employees.Name, SalaryRanges.Min,

SalaryRanges.Max FROM Employees INNER JOIN SalaryRanges ON Employees.SalaryKey = SalaryRanges.SalaryKey

ORDER BY SalaryRanges.Min;

這種語言稱為結(jié)構(gòu)化查詢語言,即 SQL,而且它是幾乎目前所有數(shù)據(jù)庫都可以使用的一種語言。SQL-92 標(biāo)準(zhǔn)被認(rèn)為是一種基礎(chǔ)標(biāo)準(zhǔn),而且已更新多次。

數(shù)據(jù)庫的種類

PC 上的數(shù)據(jù)庫,如 dBase、Borland Paradox、Microsoft Access 和 FoxBase。

數(shù)據(jù)庫服務(wù)器:IBM DB/2、Microsoft SQL Server、 Oracle、Sybase、SQLBase 和 XDB。

所有這些數(shù)據(jù)庫產(chǎn)品都支持多種相對(duì)類似的 SQL 方言,因此,所有數(shù)據(jù)庫最初看起來好象可以互換。每種數(shù)據(jù)庫都有不同的性能特征,而且每一種都有不同的用戶界面和編程接口。

ODBC

如果我們能夠以某種方式編寫不依賴于特定廠商的數(shù)據(jù)庫缺汪首的代碼,并且能夠不改變自己的調(diào)用程序即可從這些數(shù)據(jù)庫中得到相同的結(jié)果,那將是一件很好的事。如果我們可以僅為所有這些數(shù)據(jù)庫編寫一些封裝,使它們具有相似的編程接口,這種對(duì)數(shù)據(jù)庫編程獨(dú)立于供應(yīng)商的特性將很容易實(shí)現(xiàn)。

什么是 JDBC?

JDBC 是對(duì) ODBC API 進(jìn)行的一種面向?qū)ο蟮姆庋b和重新設(shè)計(jì),它易于學(xué)習(xí)和使用,并且它真正能夠使您編寫不依賴廠商的代碼,用以查詢和操縱數(shù)據(jù)庫。盡管它與所有 Java API 一樣,都是面向?qū)ο蟮模⒉皇呛芨呒?jí)別的對(duì)象集.

除 Microsoft 之外,多數(shù)廠商都采用了 JDBC,并為其數(shù)據(jù)庫提供了 JDBC 驅(qū)動(dòng)程序;這使您可輕松地真正編寫幾乎完全不依賴數(shù)據(jù)庫的代碼。另外,JavaSoft 和 Intersolv 已開發(fā)了一種稱為 JDBC-ODBC Bridge 的產(chǎn)品,可使您連接還沒有直接的 JDBC 驅(qū)動(dòng)程序的數(shù)據(jù)庫。支持 JDBC 的所有數(shù)據(jù)庫必須至少可以支持 SQL-92 標(biāo)準(zhǔn)。這在很大程度上實(shí)現(xiàn)了跨數(shù)據(jù)庫和平臺(tái)的可移植性。

安裝和使用 JDBC

JDBC 的類都被歸到 java.sql 包中,在安裝 Java JDK 1.4時(shí)會(huì)自動(dòng)安裝。然而,如果您想使用 JDBC-ODBC 橋。JDBC-ODBC 驅(qū)動(dòng)程序可從 Sun 的 Java 網(wǎng)站 () 輕松地找到并下載。在您擴(kuò)充并安裝了這個(gè)驅(qū)動(dòng)程序后,必須執(zhí)行下列步驟:

將 \jdbc-odbc\classes; 路徑添加到您的 PATH 環(huán)境變量中。

將 \jdbc-odbc\classes; 路徑添加到您的 CLASSPATH 環(huán)境變量中。

JDBC 驅(qū)動(dòng)程序的類型

Java 程序連接數(shù)據(jù)庫的方法實(shí)際上有四種:

1. JDBC-ODBC 橋和 ODBC 驅(qū)動(dòng)程序 -- 在這種方式下,這是一個(gè)本地解決方案,因?yàn)?ODBC 驅(qū)動(dòng)程序和橋代碼必須出現(xiàn)在用戶的每臺(tái)機(jī)器中。從根本上說這是一個(gè)臨時(shí)解決方案。

2. 本機(jī)代碼和 Java 驅(qū)動(dòng)程序 -- 它用另一個(gè)本地解決方案(該平臺(tái)上的 Java 可調(diào)用的本機(jī)代碼)取代 ODBC 和 JDBC-ODBC 橋。

3. JDBC 網(wǎng)絡(luò)的純 Java 驅(qū)動(dòng)程序 -- 由 Java 驅(qū)動(dòng)程序翻譯的 JDBC 形成傳送給服務(wù)器的獨(dú)立協(xié)議。然后,服務(wù)器可連接任何數(shù)量的數(shù)據(jù)庫。這種方法使您可能從客戶機(jī) Applet 中調(diào)用服務(wù)器,并將結(jié)果返回到您的 Applet。在這種情況下,中間件軟件提供商可提供服務(wù)器。

4. 本機(jī)協(xié)議 Java 驅(qū)動(dòng)程序 -- Java 驅(qū)動(dòng)程序直接轉(zhuǎn)換為該數(shù)據(jù)庫的協(xié)議并進(jìn)行調(diào)用。這種方法也可以通過網(wǎng)絡(luò)使用,而且可以在 Web 瀏覽器的 Applet 中顯示結(jié)果。在這種情況下,每個(gè)數(shù)據(jù)庫廠商將提供驅(qū)動(dòng)程序。

如果您希望編寫代碼來處理 PC 客戶機(jī)數(shù)據(jù)庫,如 dBase、Foxbase 或 Access,則您可能會(huì)使用第一種方法,并且擁有用戶機(jī)器上的所有代碼。更大的客戶機(jī)-服務(wù)器數(shù)據(jù)庫產(chǎn)品(如 IBM 的 DB2)已提供了第 3 級(jí)別的驅(qū)動(dòng)程序。

兩層模型和三層模型

當(dāng)數(shù)據(jù)庫和查詢它的應(yīng)用程序在同一臺(tái)機(jī)器上,而且沒有服務(wù)器代碼的干預(yù)時(shí),我們將生成的程序稱為兩層模型。一層是應(yīng)用程序,而另一層是數(shù)據(jù)庫。在 JDBC-ODBC 橋系統(tǒng)中通常是這種情況。

當(dāng)一個(gè)應(yīng)用程序或 applet 調(diào)用服務(wù)器,服務(wù)器再去調(diào)用數(shù)據(jù)庫時(shí),我們稱其為三層模型。當(dāng)您調(diào)用稱為“服務(wù)器”的程序時(shí)通常是這種情況。

編寫 JDBC 代碼訪問數(shù)據(jù)庫

用 ODBC 注冊(cè)您的數(shù)據(jù)庫

連接數(shù)據(jù)庫

所有與數(shù)據(jù)庫有關(guān)的對(duì)象和方法都在 java.sql 包中,因此在使用 JDBC 的程序中必須加入 "import java.sql.* "。 JDBC 要連接 ODBC 數(shù)據(jù)庫,您必須首先加載 JDBC-ODBC 橋驅(qū)動(dòng)程序

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

該語句加載驅(qū)動(dòng)程序,并創(chuàng)建該類的一個(gè)實(shí)例。然后,要連接一個(gè)特定的數(shù)據(jù)庫,您必須創(chuàng)建 Connect 類的一個(gè)實(shí)例,并使用 URL 語法連接數(shù)據(jù)庫。

String url = "jdbc:odbc:Northwind";

Connection con = DriverManager.getConnection(url);

請(qǐng)注意,您使用的數(shù)據(jù)庫名是您在 ODBC 設(shè)置面板中輸入的“數(shù)據(jù)源”名稱。

URL 語法可能因數(shù)據(jù)庫類型的不同而變化極大。

jdbc:subprotocol:subname

第一組字符代表連接協(xié)議,并且始終是 jdbc。還可能有一個(gè)子協(xié)議,在此處,子協(xié)議被指定為 odbc。它規(guī)定了一類數(shù)據(jù)庫的連通性機(jī)制。如果您要連接其它機(jī)器上的數(shù)據(jù)庫服務(wù)器,可能也要指定該機(jī)器和一個(gè)子目錄:

jdbc:bark//doggie/elliott

最后,您可能要指定用戶名和口令,作為連接字符串的一部分:

jdbc:bark//doggie/elliot;UID=GoodDog;PWD=woof

訪問MSSQL Server方法:(驅(qū)動(dòng)程序需要:msutil.jar,msbase.jar,mssqlServer.jar)

DBDriver=com.microsoft.jdbc.sqlserver.SQLServerDriver

URL=jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=demo

username=sa

password=

maxcon=10

mincon=1

poolName=SkyDev

利用我們開發(fā)的數(shù)據(jù)庫類,使用方法如下:

DbObject DbO = new DbObject(new SqlServerConnectionFactory("localhost",

1433, "demo", "sa", ""));

Connection con = DbO.getConnection();

//類代碼(不含連接工廠實(shí)現(xiàn))

package skydev.modules.data;

public final class SqlServerConnectionFactory

extends ConnectionFactory {

private final String dbDriver =

"com.microsoft.jdbc.sqlserver.SQLServerDriver";

private String host;

private int port;

private String databaseName;

public SqlServerConnectionFactory() {

super.setDriverName(dbDriver);

}

/**

*

* @param host 數(shù)據(jù)庫所在的主機(jī)名:如"localhost"

* @param port SQL服務(wù)器運(yùn)行的端口號(hào),如果使用缺省值 1433,傳入一個(gè)負(fù)數(shù)即可

* @param databaseName 數(shù)據(jù)庫名稱

* @param userName 用戶名

* @param password 口令

*/

public SqlServerConnectionFactory(String host,

int port,

String databaseName,

String userName,

String password) {

this.setHost(host);

this.setPort(port);

this.setDatabaseName(databaseName);

this.setUserName(userName);

this.setPassword(password);

init();

}

private void init() {

super.setDriverName(dbDriver);

super.setUrl("jdbc:microsoft:sqlserver://" + host.trim() + ":" +

new Integer(port).toString() + ";DatabaseName=" +

databaseName.trim());

//super.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=demo");

}

……

//------------------------------------------------------------------------------------

訪問MySQL的方法:

DBDriver=com.mysql.jdbc.Driver

URL=jdbc:mysql://localhost/demo

username=

password=

maxcon=5

mincon=1

poolName=zhengmao

訪問數(shù)據(jù)庫

一旦連接到數(shù)據(jù)庫,就可以請(qǐng)求表名以及表列的名稱和內(nèi)容等信息,而且您可以運(yùn)行 SQL 語句來查詢數(shù)據(jù)庫或者添加或修改其內(nèi)容。可用來從數(shù)據(jù)庫中獲取信息的對(duì)象有:

DatabaseMetaData 有關(guān)整個(gè)數(shù)據(jù)庫的信息:表名、表的索引、數(shù)據(jù)庫產(chǎn)品的名稱和版本、數(shù)據(jù)庫支持的操作。

ResultSet 關(guān)于某個(gè)表的信息或一個(gè)查詢的結(jié)果。您必須逐行訪問數(shù)據(jù)行,但是您可以任何順序訪問列。

ResultSetMetaData 有關(guān) ResultSet 中列的名稱和類型的信息。

盡管每個(gè)對(duì)象都有大量的方法讓您獲得數(shù)據(jù)庫元素的極為詳細(xì)的信息,但在每個(gè)對(duì)象中都有幾種主要的方法使您可獲得數(shù)據(jù)的最重要信息。然而,如果您希望看到比此處更多的信息,建議您學(xué)習(xí)文檔以獲得其余方法的說明。

ResultSet

ResultSet 對(duì)象是 JDBC 中最重要的單個(gè)對(duì)象。從本質(zhì)上講,它是對(duì)一個(gè)一般寬度和未知長(zhǎng)度的表的一種抽象。幾乎所有的方法和查詢都將數(shù)據(jù)作為 ResultSet 返回。ResultSet 包含任意數(shù)量的命名列,您可以按名稱訪問這些列。它還包含一個(gè)或多個(gè)行,您可以按順序自上而下逐一訪問。在您使用 ResultSet 之前,必須查詢它包含多少個(gè)列。此信息存儲(chǔ)在 ResultSetMetaData 對(duì)象中。

//從元數(shù)據(jù)中獲得列數(shù)

ResultSetMetaData rsmd;

rsmd = results.getMetaData();

numCols = rsmd.getColumnCount();

當(dāng)您獲得一個(gè) ResultSet 時(shí),它正好指向第一行之前的位置。您可以使用 next() 方法得到其他每一行,當(dāng)沒有更多行時(shí),該方法會(huì)返回 false。由于從數(shù)據(jù)庫中獲取數(shù)據(jù)可能會(huì)導(dǎo)致錯(cuò)誤,您必須始終將結(jié)果集處理語句包括在一個(gè) try 塊中。

您可以多種形式獲取 ResultSet 中的數(shù)據(jù),這取決于每個(gè)列中存儲(chǔ)的數(shù)據(jù)類型。另外,您可以按列序號(hào)或列名獲取列的內(nèi)容。請(qǐng)注意,列序號(hào)從 1 開始,而不是從 0 開始。ResultSet 對(duì)象的一些最常用方法如下所示。

getInt(int); 將序號(hào)為 int 的列的內(nèi)容作為整數(shù)返回。

getInt(String); 將名稱為 String 的列的內(nèi)容作為整數(shù)返回。

getFloat(int); 將序號(hào)為 int 的列的內(nèi)容作為一個(gè) float 型數(shù)返回。

getFloat(String); 將名稱為 String 的列的內(nèi)容作為 float 型數(shù)返回。

getDate(int); 將序號(hào)為 int 的列的內(nèi)容作為日期返回。

getDate(String); 將名稱為 String 的列的內(nèi)容作為日期返回。

next(); 將行指針移到下一行。如果沒有剩余行,則返回 false。

Close(); 關(guān)閉結(jié)果集。

getMetaData(); 返回 ResultSetMetaData 對(duì)象。

ResultSetMetaData

您使用 getMetaData() 方法從 ResultSet 中獲取 ResultSetMetaData 對(duì)象。您可以使用此對(duì)象獲得列的數(shù)目和類型以及每一列的名稱。

getColumnCount(); 返回 ResultSet 中的列數(shù)。

getColumnName(int); 返回列序號(hào)為 int 的列名。

getColumnLabel(int); 返回此列暗含的標(biāo)簽。

isCurrency(int); 如果此列包含帶有貨幣單位的一個(gè)數(shù)字,則返回 true。

isReadOnly(int); 如果此列為只讀,則返回 true。

isAutoIncrement(int); 如果此列自動(dòng)遞增,則返回 true。這類列通常為鍵,而且始終是只讀的。

getColumnType(int); 返回此列的 SQL 數(shù)據(jù)類型。這些數(shù)據(jù)類型包括

BIGINT

BINARY

BIT

CHAR

DATE

DECIMAL

DOUBLE

FLOAT

INTEGER

LONGVARBINARY

LONGVARCHAR

NULL

NUMERIC

OTHER

REAL

SMALLINT

TIME

TIMESTAMP

TINYINT

VARBINARY

VARCHAR

DatabaseMetaData

DatabaseMetaData 對(duì)象可為您提供整個(gè)數(shù)據(jù)庫的信息。您主要用它獲取數(shù)據(jù)庫中表的名稱,以及表中列的名稱。由于不同的數(shù)據(jù)庫支持不同的 SQL 變體,因此,也有多種方法查詢數(shù)據(jù)庫支持哪些 SQL 方法。

getCatalogs() 返回該數(shù)據(jù)庫中的信息目錄列表。使用 JDBC-ODBC Bridge 驅(qū)動(dòng)程序,您可以獲得用 ODBC 注冊(cè)的數(shù)據(jù)庫列表。這很少用于 JDBC-ODBC 數(shù)據(jù)庫。

getTables(catalog, schema,tableNames, columnNames) 返回表名與 tableNames 相符而且列名與 columnNames 相符的所有表的說明。

getColumns(catalog, schema,tableNames, columnNames) 返回表名與 tableNames 相符而且列名與 columnNames 相符的所有表列說明。

getURL(); 獲得您所連接的 URL 名稱。

getDriverName(); 獲得您所連接的數(shù)據(jù)庫驅(qū)動(dòng)程序的名稱。

獲取有關(guān)表的信息

您可以使用 DataBaseMetaData 的 getTables() 方法來獲取數(shù)據(jù)庫中表的信息。這個(gè)方法有如下4個(gè) String 參數(shù):

results =dma.getTables(catalog, schema, tablemask, types[]);

其中參數(shù)的意義是:

Catalog 要在其中查找表名的目錄名。對(duì)于 JDBC-ODBC 數(shù)據(jù)庫以及許多其他數(shù)據(jù)庫而言,可將其設(shè)置為 null。這些數(shù)據(jù)庫的目錄項(xiàng)實(shí)際上是它在文件系統(tǒng)中的絕對(duì)路徑名稱。

Schema 要包括的數(shù)據(jù)庫“方案”。許多數(shù)據(jù)庫不支持方案,而對(duì)另一些數(shù)據(jù)庫而言,它代表數(shù)據(jù)庫所有者的用戶名。一般將它設(shè)置為 null。

Tablemask 一個(gè)掩碼,用來描述您要檢索的表的名稱。如果您希望檢索所有表名,則將其設(shè)為通配符 %。請(qǐng)注意,SQL 中的通配符是 % 符號(hào),而不是一般 PC 用戶的 * 符號(hào)。

types[] 這是描述您要檢索的表的類型的 String 數(shù)組。數(shù)據(jù)庫中通常包括許多用于內(nèi)部處理的表,而對(duì)作為用戶的您沒什么價(jià)值。如果它是空值,則您會(huì)得到所有這些表。如果您將其設(shè)為包含字符串“TABLES”的單元素?cái)?shù)組,您將僅獲得對(duì)用戶有用的表格。

一個(gè)簡(jiǎn)單的 JDBC 程序

我們已經(jīng)學(xué)習(xí)了 JDBC 的所有基本功能,現(xiàn)在我們可以編寫一個(gè)簡(jiǎn)單的程序,該程序打開數(shù)據(jù)庫,打印它的表名以及某一表列的內(nèi)容,然后對(duì)該數(shù)據(jù)庫執(zhí)行查詢。此程序如下所示:

package skydevkit;

import java.sql.*;

public class JdbcOdbc_test {

ResultSet results;

ResultSetMetaData rsmd;

DatabaseMetaData dma;

Connection con;

public JdbcOdbc_test() throws SQLException {

String url = "jdbc:odbc:Northwind";

try {

//加載 JDBC-ODBC 橋驅(qū)動(dòng)程序

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

con = DriverManager.getConnection(url);//連接數(shù)據(jù)庫

dma = con.getMetaData();//獲取數(shù)據(jù)庫的元數(shù)據(jù)

System.out.println("Connected to:" + dma.getURL());

System.out.println("Driver " + dma.getDriverName());

} catch (Exception e) {

System.out.println(e);

}

try {

Statement stmt = con.createStatement();

results = stmt.executeQuery("select * from 客戶;");

ResultSetMetaData resultMetaData = results.getMetaData();

int cols = resultMetaData.getColumnCount();

String resultRow = "";

for (int i = 1; i cols; i++) {

resultRow += resultMetaData.getColumnName(i) + ";";

}

System.out.println(resultRow);

while (results.next()) {

resultRow = "";

for (int i = 1; i cols; i++) {

try {

resultRow += results.getString(i) + ";";

} catch (NullPointerException e) {

System.out.println(e.getMessage());

}

}

System.out.println(resultRow);

}

} catch (Exception e) {

System.out.println("query exception");

} finally {

results.close();

}

}

}

補(bǔ)充高級(jí)內(nèi)容

關(guān)于調(diào)用SQLServer存儲(chǔ)過程的例子:(用到了我們開發(fā)的數(shù)據(jù)庫連接類)

CREATE PROCEDURE [dbo].[sp_getStudentByName](@name char(10))

AS

Select * from Students where [Name]=@name

GO

DbObject DbO = new DbObject(new SqlServerConnectionFactory("localhost",

1433, "demo", "sa", ""));

Connection con = DbO.getConnection();

CallableStatement pstmt = null;

System.out.println("TestDB1()............");

/* try {

pstmt = con.prepareCall("{call sp_getStudentById(?)}");

pstmt.setInt(1, 1);

}*/

try {

pstmt = con.prepareCall("{call sp_getStudentByName(?)}"); //注意參數(shù)如何傳遞

pstmt.setString(1, "Tom");

}

……

使用輸出參數(shù):

CREATE PROCEDURE [dbo].[sp_insertStudent](@name char(10),@age int,@id int OUTPUT) AS

insert into Students([Name],[Age]) values (@name,@age)

select @id=@@IDENTITY

GO

try {

pstmt = con.prepareCall("{call sp_insertStudent(?,?,?)}");

pstmt.setString(1, "zengqingsong");

pstmt.setInt(2, 22);

pstmt.registerOutParameter(3, Types.INTEGER);

pstmt.executeUpdate();

int id = pstmt.getInt(3);

System.out.println(id);

}

使用返回參數(shù)的例子:

CREATE PROCEDURE [dbo].[sp_insertStudent](@name char(10),@age int,@id int OUTPUT) AS

insert into Students([Name],[Age]) values (@name,@age)

select @id=@@IDENTITY –測(cè)試輸出參數(shù)

return 30 –測(cè)試返回30

GO

try {

pstmt = con.prepareCall("{?=call sp_insertStudent(?,?,?)}");

pstmt.setString(2, "zengqingsong");

pstmt.setInt(3, 22);

pstmt.registerOutParameter(4, Types.INTEGER);

pstmt.registerOutParameter(1, Types.INTEGER);

int ret = pstmt.executeUpdate(); //執(zhí)行影響的行數(shù)

int ret2 = pstmt.getInt(1); //返回參數(shù)(輸出參數(shù))

int id = pstmt.getInt(4); //輸出參數(shù)

System.out.println(ret);

System.out.println(ret2);

System.out.println(id);

當(dāng)前標(biāo)題:go語言bigint go語言適合做什么
當(dāng)前地址:http://chinadenli.net/article41/dsphghd.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)關(guān)鍵詞優(yōu)化服務(wù)器托管軟件開發(fā)搜索引擎優(yōu)化面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)