udt java_Java DB中的Java用户定义类型(UDT)
udt java
Java DB是基于Java編程語言和SQL的關(guān)系數(shù)據(jù)庫管理系統(tǒng)。 這是Apache軟件基金會的開源Derby項(xiàng)目的Oracle版本。 Java SE 7 SDK中包含Java DB。
用戶定義類型(UDT)是Java類,其實(shí)例(對象)存儲在數(shù)據(jù)庫表列中。 UDT定義為列數(shù)據(jù)類型,UDT實(shí)例存儲為列值。 可以在Java DB數(shù)據(jù)庫中創(chuàng)建并使用UDT。
以下是該帖子的內(nèi)容:
1.用戶定義類型(UDT)
UDT在數(shù)據(jù)庫中定義數(shù)據(jù)類型。 UDT是具有公共訪問修飾符的Java類。 此類實(shí)現(xiàn)java.io.Serializable接口。 該類必須在引用該類的數(shù)據(jù)庫應(yīng)用程序(或工具)的類路徑上可見。
UDT類用于定義表或視圖列的數(shù)據(jù)類型-用戶定義的數(shù)據(jù)類型。 UDT數(shù)據(jù)是UDT類的實(shí)例(Java對象)。 并存儲為列數(shù)據(jù)。 UDT也可以在存儲過程和函數(shù)(在Java DB中,它們是基于Java的)中稱為數(shù)據(jù)類型。
- UDT可以具有子類型。 并且可以將子類型數(shù)據(jù)填充為主類型,即,可以將UDT類的子類實(shí)例填充為UDT值。 例如:(a)Java類Type1和在數(shù)據(jù)庫中定義為dbtype1的UDT,以及(b)Java類Subtype1是Type1的子類,并且(c) dbtype1表列也可以用的實(shí)例填充Subtype1 (除了Type1的實(shí)例之外)。
- 無法對UDT進(jìn)行索引,排序或比較; 并且不能與在SQL表達(dá)式中分組或聚合的運(yùn)算符一起使用(例如=,LIKE,DISTINCT,GROUP…)。
2.創(chuàng)建和使用UDT
- 2.1。 創(chuàng)建UDT
- 2.2。使用UDT
2.1。創(chuàng)建一個(gè)UDT
創(chuàng)建一個(gè)Java類并在數(shù)據(jù)庫中定義UDT。創(chuàng)建一個(gè)Java類,例如TestType1.java (請參見代碼: 4.1 TestType1.java ),以用作數(shù)據(jù)庫中的UDT。 編譯源代碼。
SQL CREATE TYPE語句在數(shù)據(jù)庫中創(chuàng)建UDT。 語法為:
CREATE TYPE udtTypeName EXTERNAL NAME javaClassName LANGUAGE JAVA該命令以默認(rèn)或指定的架構(gòu)創(chuàng)建UDT,其中:
- udtTypeName是數(shù)據(jù)庫中UDT的名稱標(biāo)識符。
- javaClassName是Java類的標(biāo)準(zhǔn)名稱。
例如,使用ij工具在Java DB數(shù)據(jù)庫中創(chuàng)建UDT( ij是Java DB附帶的命令行工具。ij是用于在Java DB數(shù)據(jù)庫上運(yùn)行交互式查詢的JDBC工具。):
ij> CONNECT 'jdbc:derby:testDB'; ij> CREATE TYPE type1 EXTERNAL NAME 'TestType1' LANGUAGE JAVA;在上面的示例中, testDB是現(xiàn)有數(shù)據(jù)庫。 在testDB數(shù)據(jù)庫中創(chuàng)建了名稱為type1的UDT。
注意
Java類文件必須位于要從ij工具引用的類路徑中。
2.1.1。驗(yàn)證,刪除和更新UDT
可以使用以下SQL命令驗(yàn)證創(chuàng)建的UDT:
ij> SELECT alias, javaclassname FROM SYS.SYSALIASES WHERE aliastype='A';要從數(shù)據(jù)庫中刪除UDT,請使用DROP TYPE SQL命令。 以下是一個(gè)示例:
ij> DROP TYPE udtTypeName RESTRICT;在上面的示例中, udtTypeName是數(shù)據(jù)庫中定義的UDT名稱。
如果數(shù)據(jù)庫對象正在使用(或引用)UDT,則不能刪除UDT。 例如,(a)如果表列的類型為UDT,除非刪除相應(yīng)的表列,否則不能刪除該UDT,或者(b)如果數(shù)據(jù)庫函數(shù)引用的是UDT的類(實(shí)例),則不能刪除UDT。除非已修改函數(shù),否則不要引用該UDT類。
要使用更新后的Java代碼更新UDT,請(重新)編譯UDT類。 這會影響UDT類型的對象。 這也可能會影響存儲在UDT對象中的數(shù)據(jù),具體取決于在應(yīng)用程序中定義和使用UDT的方式。 請參閱主題: 3.設(shè)計(jì)UDT –考慮更新UDT對現(xiàn)有數(shù)據(jù)的影響 。
2.2。使用UDT
使用UDT創(chuàng)建數(shù)據(jù)庫對象并處理UDT數(shù)據(jù)(插入,更新,刪除和查詢)。 UDT數(shù)據(jù)可以與SQL交互使用,也可以在Java程序中與JDBC API一起在數(shù)據(jù)庫中使用。
2.2.1。 互動式SQL
下面介紹創(chuàng)建UDT類型的數(shù)據(jù)庫表列,插入數(shù)據(jù)和查詢插入的數(shù)據(jù)。
- (i)使用UDT作為列類型創(chuàng)建數(shù)據(jù)庫表。
例如:
CREATE TABLE test_table1 (id INT,type1col type1, // column with UDT ) - (ii)將數(shù)據(jù)插入表中。
使用定制的數(shù)據(jù)庫函數(shù)將數(shù)據(jù)插入到用UDT定義的表列中。有關(guān)創(chuàng)建定制函數(shù)以將UDT數(shù)據(jù)插入到表列中的詳細(xì)信息,請參閱4.2。 Example_Fn1 –函數(shù) 。
示例函數(shù)Example_Fn1具有簽名Example_Fn1(字符串輸入),并返回TestType1的實(shí)例(其中TestType1是表示UDT的Java類)。
ij> INSERT INTO test_table1(id, type1col) VALUES(1, Example_Fn1("udt value 1"));上面SQL命令在表中插入一行,其中帶有TestType1 Java對象的UDT列值。 函數(shù)Example_Fn1使用String輸入?yún)?shù)調(diào)用TestType1類的構(gòu)造函數(shù)來構(gòu)建對象; 并且該對象存儲在表列中。
- (iii)查詢插入的數(shù)據(jù)。
可以使用自定義函數(shù)從UDT列獲取數(shù)據(jù)。 在以下示例中,UDT類TestType1的重寫的Object類的toString()方法返回存儲的實(shí)例的字符串值。
ij> SELECT * FROM test_table1; ID | TYPE1COL ------------------------- 1 | udt value 1
2.2.2。 使用JDBC API
在java.sql包中定義的PreparedStatement和ResultSet接口分別用于插入和獲取數(shù)據(jù)庫UDT數(shù)據(jù)。
- PreparedStatement的setObject()方法用于將UDT數(shù)據(jù)作為對象存儲在UDT表列中。 方法setObject(int parameterIndex,Object obj)使用給定的對象設(shè)置指定參數(shù)的值。
- ResultSet的getObject()方法用于從UDT表列中檢索存儲的UDT數(shù)據(jù)。 方法getObject(int columnIndex)獲取此ResultSet對象的當(dāng)前行中指定列的值。 返回的數(shù)據(jù)是一個(gè)對象。
以下Java代碼段顯示了用法:
// insert data into a table int idValue = 2; TestType1 obj = new TestType1("udt value 2"); PreparedStatement ps = conn.prepareStatement("INSERT INTO test_table1 VALUES (?, ?)"; ps.setInt(1, idValue); // where 1 is the parameter index ps.setObject(2, obj); // UDT data ps.executeUpdate(); ... // retrieve data from a table PreparedStatement ps = conn.prepareStatement("SELECT * FROM test_table1"); ResultSet rs = ps.executeQuery(); while (rs.next()) { int idValue = rs.getInt(1);TestType1 testType1 = (TestType1) rs.getObject(2); // where 2 is the column index in ResultSet object... }注意
UDT用于存儲數(shù)據(jù)。 該UDT(和數(shù)據(jù))可能會在應(yīng)用程序的整個(gè)生命周期中發(fā)生變化(即演變)。 設(shè)計(jì)UDT時(shí)必須考慮到這一點(diǎn)。
另外,請注意,UDT類始終實(shí)現(xiàn)Serializable接口。 必須考慮數(shù)據(jù)序列化和各種版本的UDT數(shù)據(jù)對象的影響。 在簡單的情況下,僅編譯更改的UDT類代碼就足夠了。
有兩種設(shè)計(jì)和使用UDT的方法。
- UDT類實(shí)現(xiàn)了可序列化,并且隨著UDT數(shù)據(jù)的發(fā)展,應(yīng)用程序(帶有UDT)使用數(shù)據(jù)轉(zhuǎn)換應(yīng)用程序。
- UDT類實(shí)現(xiàn)Externalizable (而不是Serializable ),并在UDT類中使用數(shù)據(jù)轉(zhuǎn)換功能。 一個(gè)帶有UDT類代碼的示例如下所示。
關(guān)于可外部化
UDT類必須實(shí)現(xiàn)Serializable接口。 和java.io.Externalizable擴(kuò)展Serializable 。
實(shí)現(xiàn)此接口后,只有可外部化實(shí)例的類的身份(而不是狀態(tài))才寫入序列化流中。 該類負(fù)責(zé)保存和恢復(fù)其實(shí)例的內(nèi)容(狀態(tài))。
必須實(shí)現(xiàn)兩種方法:
- readExternal(ObjectInput in):對象實(shí)現(xiàn)readExternal()方法以恢復(fù)其內(nèi)容。
- writeExternal(ObjectOutput out):對象實(shí)現(xiàn)writeExternal()方法以保存其內(nèi)容。
3.1 UDT類實(shí)現(xiàn)Serializable
UDT類實(shí)現(xiàn)了Serializable,并且隨著UDT數(shù)據(jù)的發(fā)展,應(yīng)用程序(使用UDT)使用數(shù)據(jù)轉(zhuǎn)換應(yīng)用程序-以下是概述步驟:
- UDT實(shí)現(xiàn)Serializable 。
- 創(chuàng)建并使用帶有初始版本的UDT。
- 在使用下一個(gè)版本更新UDT之前,請保存(存儲)先前版本的數(shù)據(jù)。
- 創(chuàng)建下一個(gè)版本的UDT(更新較早的版本)。
- 將初始版本數(shù)據(jù)轉(zhuǎn)換為當(dāng)前更新的版本數(shù)據(jù)。
請注意,在這種情況下,所有以前的版本數(shù)據(jù)一次都轉(zhuǎn)換為當(dāng)前(新)版本。
3.2 UDT類實(shí)現(xiàn)可外部化
UDT類實(shí)現(xiàn)Externalizable (而不是Serializable )并在其中使用數(shù)據(jù)轉(zhuǎn)換功能-以下是概述步驟:
- UDT實(shí)現(xiàn)Externalizable 。
- 創(chuàng)建并使用帶有初始版本的UDT。
- 在使用下一個(gè)版本更新UDT之前,無需執(zhí)行任何操作。
- 使用內(nèi)置的數(shù)據(jù)轉(zhuǎn)換功能,創(chuàng)建下一個(gè)版本的UDT(更新較早的版本)。
在這種情況下,每當(dāng)查詢或更新數(shù)據(jù)時(shí),以前的版本數(shù)據(jù)就會轉(zhuǎn)換為當(dāng)前(新)版本。 版本信息包含在UDT類中。
以下是有關(guān)UDT類的詳細(xì)信息和代碼的示例。
注意
本主題中的示例未顯示用于插入和查詢UDT數(shù)據(jù)SQL命令和函數(shù)的詳細(xì)信息或代碼。 這些可能類似于本文前面顯示的示例。
4.示例代碼
- 4.1。 TestType1.java
- 4.2。 Example_Fn1 –函數(shù)
- 4.3.Testtype2.java(版本1)
- 4.4.Testtype2.java(版本2)
4.1.TestType1.java
public class TestType1implements java.io.Serializable {private String value = "DEFAULT";public TestType1() {}public TestType1(String s) {value = s;}@Overridepublic String toString() {return value;} } // class4.2.Example_Fn1 –功能
這是將數(shù)據(jù)插入U(xiǎn)DT列的功能,如2.2中的示例所示。 使用UDT 。
- (i)使用具有函數(shù)功能的公共靜態(tài)方法創(chuàng)建Java類。
- (ii)使用CREATE FUNCTION命令在數(shù)據(jù)庫中創(chuàng)建函數(shù)。
以下是該函數(shù)和CREATE FUNCTION命令的Java類。 使用ij工具以交互方式編譯Java類并運(yùn)行CREATE FUNCTION命令。
public class FunctionClass {public static TestType1 FnMethod1(String s) {return new TestType1(s);} }CREATE FUNCTION Example_Fn1(VARCHAR(25)) RETURNS type1 LANGUAGE JAVA PARAMETER STYLE JAVA NO SQL EXTERNAL NAME 'FunctionClass.FnMethod1';注意
ij使用SQL命令SHOW FUNCTIONS和DROP FUNCTION來驗(yàn)證創(chuàng)建的函數(shù)并將其從數(shù)據(jù)庫中刪除。
4.3.Testtype2.java(版本1)
import java.io.*; public class Testtype2implements Externalizable {private static final long serialVersionUID = 1L;private static final int FIRST_VERSION = 1; // initial version idprivate String value = "DEFAULT";public Testtype2() {}public Testtype2(String s) {value = s;}@Overridepublic void writeExternal(ObjectOutput out)throws IOException {// first write the version id out.writeInt(FIRST_VERSION);// next write the state out.writeObject(value);}@Overridepublic void readExternal(ObjectInput in)throws IOException, ClassNotFoundException {// read the version id int version = in.readInt();if (version < FIRST_VERSION) { throw new IOException("Corrupt data stream (no such version).");}if (version > FIRST_VERSION) {throw new IOException("Can't deserialize from the future versions.");}// read object (state)value = (String) in.readObject() + "_V" + version;} // readExternal()@Overridepublic String toString() {return value;} } // version 1 class4.4.Testtype2.java(版本2)
import java.io.*; public class Testtype2implements Externalizable {private static final long serialVersionUID = 1L;private static final int FIRST_VERSION = 1; // initial version idprivate static final int NEW_VERSION = 2;private String value = "DEFAULT";private double newData;public Testtype2() {}public Testtype2(String s, double i) {value = s; newData = i;}@Overridepublic void writeExternal(ObjectOutput out)throws IOException {// first write the version id out.writeInt(NEW_VERSION);// next write the state out.writeObject(value); out.writeDouble(newData);}@Overridepublic void readExternal(ObjectInput in)throws IOException, ClassNotFoundException {if (version < FIRST_VERSION) { throw new IOException("Corrupt data stream (no such version).");}if (version > NEW_VERSION) {throw new IOException("Can't deserialize from the future versions.");}// read objectvalue = (String) in.readObject() + "_V" + version;// read new version's data if (version == NEW_VERSION) { newData = in.readDouble();}else { // if FIRST_VERSION// newData is its default value, 0}} // readExternal()@Overridepublic String toString() {return value + ":" + newData;} } // version 2 class注意
5.注釋和參考
- Java Swing文本編輯器應(yīng)用程序中的示例用法:GUI文本編輯器創(chuàng)建一個(gè)文本文檔作為java.swing.text.PlainDocument類的實(shí)例。 使用內(nèi)容創(chuàng)建的UDT Java類–例如PlainDocument實(shí)例,文檔名稱,創(chuàng)建日期等,并在應(yīng)用程序中用于存儲數(shù)據(jù)。
- Oracle 10g數(shù)據(jù)庫支持創(chuàng)建和使用基于Java的UDT。 這些被稱為SQLJ類型。 表示UDT的Java類實(shí)現(xiàn)java.sql.SQLData或oracle.sql.ORAData接口,而不是java.io.Serializable 。 這些UDT是使用CREATE TYPE SQL語句創(chuàng)建的,并存儲到服務(wù)器,并可以通過SQL訪問。
- 鏈接到Apache Derby>文檔(10.8手冊): http : //db.apache.org/derby/manuals/index.html
翻譯自: https://www.javacodegeeks.com/2013/10/java-user-defined-types-udt-in-java-db.html
udt java
總結(jié)
以上是生活随笔為你收集整理的udt java_Java DB中的Java用户定义类型(UDT)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑连接手机热点怎么连华为电脑连接手机热
- 下一篇: Java 9中的无限集