Java DB是基于Java编程语言和SQL的关系数据库管理系统。 这是Apache软件基金会的开源Derby项目的Oracle版本。 Java SE 7 SDK中包含Java DB。

用户定义类型(UDT)是Java类,其实例(对象)存储在数据库表列中。 UDT定义为列数据类型,UDT实例存储为列值。 可以在Java DB数据库中创建和使用UDT。

以下是该帖子的内容:

  1. 用户定义类型(UDT)
  2. 创建和使用UDT
  3. 设计UDT –考虑更新UDT对现有数据的影响
  4. 范例程式码
  5. 注释与参考

1.用户定义类型(UDT)

UDT在数据库中定义数据类型。 UDT是具有公共访问修饰符的Java类。 此类实现java.io.Serializable接口。 该类必须在引用该类的数据库应用程序(或工具)的类路径上可见。

UDT类用于定义表或视图列的数据类型-用户定义的数据类型。 UDT数据是UDT类的实例(Java对象)。 并存储为列数据。 UDT也可以在存储过程和函数(在Java DB中,它们是基于Java的)中称为数据类型。

  • UDT可以具有子类型。 并且可以将子类型数据填充为主类型,即,可以将UDT类的子类实例填充为UDT值。 例如:(a)Java类Type1和在数据库中定义为dbtype1的UDT,以及(b)Java类Subtype1Type1的子类,并且(c) dbtype1表列也可以用的实例填充Subtype1 (除了Type1的实例之外)。
  • 无法对UDT进行索引,排序或比较; 并且不能与在SQL表达式中分组或聚合的运算符一起使用(例如=,LIKE,DISTINCT,GROUP…)。

2.创建和使用UDT

  • 2.1。 创建UDT
  • 2.2。使用UDT

2.1。创建一个UDT

创建一个Java类并在数据库中定义UDT。创建一个Java类,例如TestType1.java (请参见代码: 4.1 TestType1.java ),以用作数据库中的UDT。 编译源代码。

SQL CREATE TYPE语句在数据库中创建UDT。 语法为:

CREATE TYPE udtTypeName
EXTERNAL NAME javaClassName
LANGUAGE JAVA

该命令以默认或指定的架构创建UDT,其中:

  • udtTypeName是数据库中UDT的名称标识符。
  • javaClassName是Java类的标准名称。

例如,使用ij工具在Java DB数据库中创建UDT( ij是Java DB附带的命令行工具。ij是用于在Java DB数据库上运行交互式查询的JDBC工具。):

ij> CONNECT 'jdbc:derby:testDB';
ij> CREATE TYPE type1 EXTERNAL NAME 'TestType1' LANGUAGE JAVA;

在上面的示例中, testDB是现有数据库。 在testDB数据库中创建了名称为type1的UDT。

注意

Java类文件必须位于要从ij工具引用的类路径中。

2.1.1。验证,删除和更新UDT

可以使用以下SQL命令验证创建的UDT:

ij> SELECT alias, javaclassname FROM SYS.SYSALIASES WHERE aliastype='A';

要从数据库中删除UDT,请使用DROP TYPE SQL命令。 以下是一个示例:

ij> DROP TYPE udtTypeName RESTRICT;

在上面的示例中, udtTypeName是数据库中定义的UDT名称。

如果数据库对象正在使用(或引用)UDT,则不能删除UDT。 例如,(a)如果表列的类型为UDT,除非删除相应的表列,否则不能删除该UDT,或者(b)如果数据库函数引用的是UDT的类(实例),则不能删除UDT。除非已修改函数,否则不要引用该UDT类。

要使用更新后的Java代码更新UDT,请(重新)编译UDT类。 这会影响UDT类型的对象。 这也可能会影响存储在UDT对象中的数据,具体取决于在应用程序中定义和使用UDT的方式。 请参阅主题: 3.设计UDT –考虑更新UDT对现有数据的影响

2.2。使用UDT

使用UDT创建数据库对象并处理UDT数据(插入,更新,删除和查询)。 UDT数据可以与SQL交互使用,也可以与Java程序中的JDBC API一起在数据库中使用。

2.2.1。 互动式SQL

下面介绍创建UDT类型的数据库表列,插入数据和查询插入的数据。

  • (i)以UDT作为列类型创建数据库表。

    例如:

    CREATE TABLE test_table1 (id INT,type1col type1, // column with UDT
    )
  • (ii)将数据插入表中。

    使用定制的数据库函数将数据插入到用UDT定义的表列中。有关创建定制函数以将UDT数据插入到表列中的详细信息,请参见4.2。 Example_Fn1 –函数

    示例函数Example_Fn1具有签名Example_Fn1(字符串输入),并返回TestType1的实例(其中TestType1是表示UDT的Java类)。

    ij> INSERT INTO test_table1(id, type1col) VALUES(1, Example_Fn1("udt value 1"));

    上面的SQL命令在表中插入一行,其中带有TestType1 Java对象的UDT列值。 函数Example_Fn1调用带有String输入参数的TestType1类的构造函数来构建对象。 并且该对象存储在表列中。

  • (iii)查询插入的数据。

    可以使用自定义函数从UDT列获取数据。 在以下示例中,UDT类TestType1的重写的Object类的toString()方法返回存储实例的字符串值。

    ij> SELECT * FROM test_table1;
    ID         | TYPE1COL
    -------------------------
    1          | udt value 1

2.2.2。 使用JDBC API

java.sql包中定义的PreparedStatementResultSet接口分别用于插入和获取数据库UDT数据。

  • PreparedStatementsetObject()方法用于将UDT数据作为对象存储在UDT表列中。 方法setObject(int parameterIndex,Object obj)使用给定的对象设置指定参数的值。
  • ResultSet的getObject()方法用于从UDT表列中检索存储的UDT数据。 方法getObject(int columnIndex)获取此ResultSet对象的当前行中指定列的值。 返回的数据是一个对象。

以下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...
}

注意

  1. 在上面的代码中, conn是数据库Connection对象。
  2. UDT Java类文件必须位于类路径中,才能从JDBC代码进行引用。
  3. 设计UDT –考虑更新UDT对现有数据的影响

UDT用于存储数据。 该UDT(和数据)可能会在应用程序的整个生命周期中发生变化(即演变)。 设计UDT时必须考虑到这一点。

另外,请注意,UDT类始终实现Serializable接口。 必须考虑数据序列化和UDT数据对象的各种版本的影响。 在简单的情况下,仅编译更改的UDT类代码就足够了。

有两种设计和使用UDT的方法。

  • UDT类实现了可序列化,并且随着UDT数据的发展,应用程序(带有UDT)使用数据转换应用程序。
  • UDT类实现Externalizable (而不是Serializable ),并在UDT类中使用数据转换功能。 一个带有UDT类代码的示例如下所示。

关于可外部化

UDT类必须实现Serializable接口。 和java.io.Externalizable扩展Serializable

实现此接口后,只有可外部化实例的类的身份(而不是状态)才写入序列化流中。 该类负责保存和恢复其实例的内容(状态)。

必须实现两种方法:

  • readExternal(ObjectInput in):对象实现readExternal()方法以还原其内容。
  • writeExternal(ObjectOutput out):对象实现writeExternal()方法以保存其内容。

3.1 UDT类实现Serializable

UDT类实现了Serializable,并且随着UDT数据的发展,应用程序(使用UDT)使用数据转换应用程序-以下是概述步骤:

  • UDT实现Serializable
  • 创建并使用带有初始版本的UDT。
  • 在使用下一个版本更新UDT之前,请保存(存储)先前版本的数据。
  • 创建下一个版本的UDT(更新较早的版本)。
  • 将初始版本数据转换为当前更新的版本数据。

请注意,在这种情况下,所有以前的版本数据一次都转换为当前(新)版本。

3.2 UDT类实现可外部化

UDT类实现Externalizable (而不是Serializable )并在其中使用数据转换功能-以下是概述步骤:

  • UDT实现Externalizable
  • 创建并使用带有初始版本的UDT。
  • 在使用下一版本更新UDT之前,无需执行任何操作。
  • 使用内置的数据转换功能,创建下一个版本的UDT(更新较早的版本)。

在这种情况下,每当查询或更新数据时,以前的版本数据就会转换为当前(新)版本。 版本信息包含在UDT类中。

以下是有关UDT类的详细信息和代码的示例。

  1. 创建具有版本1的UDT类: Testtype2.java (请参见代码: 4.3Testtype2.java(版本1)
  2. 编译
  3. 在数据库中创建UDT: type2
  4. 创建带有UDT列的表: test_table3
  5. 将数据插入UDT列
  6. 查询UDT数据
  7. 使用版本2更新UDT类: Testtype2.java (请参见代码: 4.3 Testtype2.java(版本2)
  8. 编译
  9. 将数据(版本2)插入UDT列
  10. 查询UDT数据–版本1和版本2数据

注意

本主题中的示例未显示用于插入和查询UDT数据的SQL命令和函数的详细信息或代码。 这些可能类似于本文前面显示的示例。

4.示例代码

  • 4.1。 TestType1.java
  • 4.2。 Example_Fn1 –函数
  • 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;}
} // class

4.2.Example_Fn1 –功能

此功能是将数据插入UDT列的功能,请参见2.2中的示例 使用UDT

  • (i)使用具有该功能功能的公共静态方法创建一个Java类。
  • (ii)使用CREATE FUNCTION命令在数据库中创建函数。

以下是该函数和CREATE FUNCTION命令的Java类。 使用ij工具以交互方式编译Java类并运行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来验证创建的函数并将其从数据库中删除。

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 class

4.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

注意

  1. externalizablereadExternal()方法必须按与writeExternal()方法写入的相同顺序和相同类型读取值。
  2. 在上面的示例代码中, serialVersionUID变量是可选的。

5.注释和参考

  • Java Swing文本编辑器应用程序中的示例用法:GUI文本编辑器创建一个文本文档作为java.swing.text.PlainDocument类的实例。 使用内容创建的UDT Java类–例如PlainDocument实例,文档名称,创建日期等,并在应用程序中用于存储数据。
  • Oracle 10g数据库支持创建和使用基于Java的UDT。 这些被称为SQLJ类型。 表示UDT的Java类实现java.sql.SQLDataoracle.sql.ORAData接口,而不是java.io.Serializable 。 这些UDT是使用CREATE TYPE SQL语句创建的,并存储到服务器,并且可以通过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

Java DB中的Java用户定义类型(UDT)相关推荐

  1. Java DB中的Java存储过程

    1 Java存储过程 这篇文章是关于Java DB中的Java存储过程的. Java DB是基于Java编程语言和SQL的关系数据库管理系统. 这是Apache软件基金会的开源Derby项目的Orac ...

  2. udt java_Java DB中的Java用户定义类型(UDT)

    udt java Java DB是基于Java编程语言和SQL的关系数据库管理系统. 这是Apache软件基金会的开源Derby项目的Oracle版本. Java SE 7 SDK中包含Java DB ...

  3. 关于Java项目中,word和Excel类型文件的预览功能实现

    关于Java项目中,word和Excel类型文件的预览功能实现 背景 Aspose说明 Aspose.Words Aspose.Cells pom依赖引入 引入license.xml(授权文件) 创建 ...

  4. 为什么我会在2012年的新企业Java项目中使用Java EE而不是Spring

    这个问题经常出现. 我的新项目也在2011年11月发布. 在这个新的Enterprise Java项目中,我将使用Java EE(JEE)代替Spring框架. 我知道:关于此主题的文章,博客和论坛讨 ...

  5. vb连接mysql出现的问题_连接数据库问题用户定义类型未定义【vb6】

    连接数据库问题用户定义类型未定义[vb6]0 Dim cnnImage As NewADODB.Connection Dim rsImage As New ADODB.Recordset Dim st ...

  6. 具有用户定义类型的format的示例用法

    具有用户定义类型的format的示例用法 实现功能 C++实现代码 实现功能 具有用户定义类型的format的示例用法 C++实现代码 #include "boost/format.hpp& ...

  7. Java 8中的java.util.Random

    Java 8中java.util.Random类的简洁功能之一是对其进行了改进,现在可以返回随机的数字流 . 例如,要生成一个介于0(含)和1(不含)之间的随机双精度数的无限流: Random ran ...

  8. Java 8 中的 java.util.Optional

    Java 8 中的 java.util.Optional 学习了:https://blog.csdn.net/sun_promise/article/details/51362838 package ...

  9. Access FileDialog 用户定义类型未定义(User-defined type not defined)的解决方法

    Access VBA里的FileDialog函数可以打开文件对话框.有的高版Access(2016及以上)会提示"用户定义类型未定义".解决方案是在VBA编辑器里选择" ...

最新文章

  1. 程序员过关斩将--你的面向接口编程一定对吗?
  2. ASP.NET Core应用程序的参数配置及使用
  3. 测试 MathJax 排版功效
  4. 华为机试——计算字符个数
  5. 【英语学习】【Level 07】U05 Best Destination L4 A perfect destination
  6. IOS开发-TableView表视图LV2
  7. 详解电脑蓝屏怎么回事
  8. DIV块中 元素垂直居中
  9. 数据禾|2001年东四盟地区植被类型分布数据
  10. 计算机考证广东省ps
  11. Google Earth Engine 入门1 GEE账号注册
  12. JavaScript两个实用的图片懒加载优化方法
  13. std::forward理解
  14. 云栖专辑 | 阿里开发者们的20个感悟,一通百通
  15. C——Linux下的串口编程
  16. ESP8266-Arduino编程实例-MS5611气压传感器驱动
  17. 一张微信智能名片能否挽救企业被浪费的80%商机?
  18. Java 图片压缩(Thumbnails)
  19. 迷你服务器开机无显示,迷你版云服务器未启动
  20. 基础乐理 节奏联系题,很重要

热门文章

  1. ios签名软件_苹果企业签名常常掉怎样处理【苹果签名吧】
  2. jdk8 npe_JDK 14中更好的NPE消息
  3. java设计模式 订阅模式_Java中的外观设计模式
  4. 微软 azure_在Microsoft Azure上运行Eclipse MicroProfile
  5. spock 集成测试_使用Spock Mocks进行Grails 3.3集成测试
  6. envoy重试_具有Envoy代理的微服务模式,第二部分:超时和重试
  7. kafka streams_Kafka REST Proxy MapR Streams入门
  8. 冷热复位_冷热rx-java可观察
  9. sap界面功能_功能介面
  10. 在Spring@Component vs @Repository vs @Service