📄 jdbc2.0.frame9.html
字号:
stream.writeString(first);
stream.writeString(last);
}
}
public class Person implements SQLData {
Fullname name;
float height;
float weight;
Ref home;
private String sql_type;
public String getSQLTypeName() { return sql_type; }
public void readSQL (SQLInput stream, String type)
throws SQLException {
sql_type = type;
name = (Fullname)stream.readObject();
height = stream.readFloat();
weight = stream.readFloat();
home = stream.readRef();
}
public void writeSQL (SQLOutput stream)
throws SQLException {
stream.writeObject(name);
stream.writeFloat(height);
stream.writeFloat(weight);
stream.writeRef(home);
}
}
</pre>
</blockquote>
<p><a name="299077"></a></p>
<p><a name="299078"></a> 以下方法使用这些类来具体实现 HOMES 和 PEOPLE
表(稍前定义的)中的数据: </p>
<p><a name="299079"></a> </p>
<blockquote>
<pre>import java.sql.*;
.
.
.
public void demo (Connection con) throws SQLException {
// 设置连接的映射
try {
java.util.Map map = con.getTypeMap();
map.put("S.RESIDENCE", Class.forName("Residence"));
map.put("S.FULLNAME", Class.forName("Fullname"));
map.put("S.PERSON", Class.forName("Person"));
}
catch (ClassNotFoundException ex) {}
PreparedStatement pstmt;
ResultSet rs;
pstmt = con.prepareStatement("SELECT OCCUPANT FROM HOMES");
rs = pstmt.executeQuery();
rs.next();
Ref ref = rs.getRef(1);
pstmt = con.prepareStatement(
"SELECT FULLNAME FROM PEOPLE WHERE OID = ?");
pstmt.setRef(1, ref);
rs = pstmt.executeQuery();
rs.next();
Fullname who = (Fullname)rs.getObject(1);
// 打印输出 "Daffy Duck"
System.out.println(who.first + " " + who.last);
}
</pre>
</blockquote>
<p><a name="299109"></a></p>
<h4>9.4.2 在 Java 中镜像 SQL 继承</h4>
<p>可以定义 SQL 结构化类型来构成继承层次。例如,不妨考虑继承自
PERSON 的 SQL 类型 STUDENT: </p>
<p><a name="299111"></a> </p>
<blockquote>
<pre>CREATE TYPE PERSON AS OBJECT (NAME VARCHAR(20), BIRTH DATE);
CREATE TYPE STUDENT AS OBJECT EXTENDS PERSON (GPA NUMERIC(4,2));
</pre>
</blockquote>
<p><a name="299115"></a></p>
<p><a name="299116"></a>以下的 Java 类型可以表示这些 SQL 类型的数据。类 <code>Student</code>
扩展了 <code>Person</code>,同时镜像 SQL 类型层次结构。子类的 <code>SQLData.readSQL()</code>
和 <code>SQLData.writeSQL() </code>方法将每一个调用和其父类中相应方法级联在一起,其目的是在读写子类属性之前先读/写父类属性。</p>
<p><a name="299117"></a> </p>
<blockquote>
<pre> import java.sql.*;
...
public class Person implements SQLData {
public String name;
public Date birth;
private String sql_type;
public String getSQLTypeName() { return sql_type; }
public void readSQL (SQLInput data, String type)
throws SQLException {
sql_type = type;
name = data.readString();
birth = data.readDate();
}
public void writeSQL (SQLOutput data)
throws SQLException {
data.writeString(name);
data.writeDate(birth);
}
}
public class Student extends Person {
public float GPA;
private String sql_type;
public String getSQLTypeName() { return sql_type; }
public void readSQL (SQLInput data, String type)
throws SQLException {
sql_type = type;
super.readSQL(data, type);
GPA = data.readFloat();
}
public void writeSQL (SQLOutput data)
throws SQLException {
super.writeSQL(data);
data.writeFloat(GPA);
}
}
</pre>
</blockquote>
<p><a name="299160"></a></p>
<p>Java 类层次结构并不需要镜像 SQL
继承层次。例如,可以在没有父类的情况下声明以上的 <code>Student</code>
类。这种情况下,<code>Student </code>所含的域可能不仅保存有 STUDENT
自身所声明的属性,而且保存了 SQL 类型 STUDENT 的继承属性。</p>
<p><a name="299161"></a> </p>
<h4>9.4.3 将 SQL distinct 类型映射到 Java 的示例</h4>
<p>SQL distinct 类型 (MONEY) 及表示该类型的 Java 类 Money: </p>
<blockquote>
<pre>
-- SQL 定义
CREATE TYPE MONEY AS NUMERIC(10,2);
// Java 定义
public class Money implements SQLData {
public java.math.BigDecimal value;
private String sql_type;
public String getSQLTypeName() { return sql_type; }
public void readSQL (SQLInput stream, String type)
throws SQLException {
sql_type = type;
value = stream.readBigDecimal();
}
public void writeSQL (SQLOutput stream) throws SQLException {
stream.writeBigDecimal(value);
}
}
</pre>
</blockquote>
<p><a name="298941"></a></p>
<p><a name="298933"></a> </p>
<h3>9.5 方法的通用性</h3>
<p>用户在自定义 Java 类来表示 SQL 结构化类型和 distinct
类型方面具有相当大的灵活性。他们控制内嵌 SQL 属性类型到 Java
域类型的映射方式。而且还控制 SQL 名称(类型和属性的名称)到
Java
名称(类和域名称)的映射方式。用户不仅能增加实现特定于域功能的域和方法(增加到代表
SQL 类型的 Java 类中),而且还可以生成 JavaBeans 作为代表 SQL
类型的类。</p>
<p><a name="298935"></a>用户甚至可以将单个 SQL 类型映射到不同的 Java
类上,这取决于不定的条件。为此,用户必须自定义 <code>SQLData.readSQL()
</code>的实现来在不同的条件下构造和返回不同类的对象。</p>
<p><a name="298936"></a>同样,用户可以将单个 SQL 值映射到多个 Java
对象上,而这又是通过自定义 <code>SQLData.readSQL()</code>
的实现来构造多个对象并将 SQL
属性分配到这些对象的域中来完成的。</p>
<p><a name="298937"></a><code>SQLData.readSQL()</code>
方法的自定义可以递增地组装类型-映射对象,诸如此类。我们相信这些灵活性可以使
JDBC 的用户能为不同的应用程序映射相应的 SQL 类型。</p>
<p><a name="298924"></a> </p>
<h3>9.6 NULL 数据</h3>
<p>JDBC 应用程序使用 JDBC 现有的 <code>getObject()</code> 和 <code>setObject()</code>
机制来检索和存储 <code>SQLData</code> 值。我们注意到:当 <code>PreparedStatement.setObject()
</code>方法的第二个参数 <code>x</code> 具有 Java 值 <code>null</code> 时,JDBC
执行 SQL 语句的方式就仿佛 SQL 字符 NULL 已经取代语句中的该参数: </p>
<p><a name="290184"></a> </p>
<blockquote>
<pre> void setObject (int i, Object x) throws SQLException;
</pre>
</blockquote>
<p><a name="290187"></a></p>
<p><a name="290189"></a>当参数 <code>x</code>
值为空时,并不强制要求相应的参数表达式是 SQL 可以接受的 Java
类型(如果其值为非空,则该 Java 类型可以成功地传给 SQL 语句)。Java
null 不带任何类型信息。例如,可以将类 <code>AntiMatter</code> 的空 Java
变量作为参数传给 SQL 语句(该语句要求 SQL 类型 <code>MATTER</code>
的值)而不会导致错误,即使相应的类型-映射对象不允许将 <code>MATTER</code>
转换成 <code>AntiMatter</code>。</p>
<p><a name="290529"></a> </p>
<h3>9.7 总结</h3>
<p>第 <a href="jdbc2.0.frame8.html#297135">8</a> 章和第 <a
href="jdbc2.0.frame9.html#298134">9</a> 章介绍了支持新型 SQL 类型的 JDBC
扩展。扩展具有以下功能:
<ul>
<p><a name="290536"></a></p>
<li>所有的新 SQL 类型都是用统一和可扩展的接口来处理的,可以在 JDBC
中逐步实现。 <br>
<br>
<a name="290541"></a> </li>
<li>JDBC 中最少程度地增加了机制。JDBC
实现只不过是将控制转移到用来代表 SQL 类型的类的 <code>SQLData.readSQL()</code>
和 <code>SQLData.writeSQL() </code>方法。<br>
<br>
<a name="299282"></a> </li>
<li>扩展是以现有接口 <code>java.io.Serializable</code>、<code>java.io.DataInput</code>、<code>java.io.DataOutput</code>、<code>java.sql.ResultSet</code>
和 <code>java.sql.PreparedStatement </code>为基础的。<br>
<br>
<a name="292550"></a> </li>
<li>数据库工具的编程人员通过自定义代表 SQL 数据的 Java
类获得增加数值的更大灵活性。<br>
<br>
</li>
</ul>
<p><a name="290553"></a></p>
<p><br>
</p>
<hr>
<font size="-1"><a href="jdbc2.0.frame.html">
<p>目录</a> | <a href="jdbc2.0.frame8.html">上一页</a> | <a
href="jdbc2.0.frame10.html">下一页</a> </font></p>
<hr>
<address>
<a href="mailto:jdbc@eng.sun.com">jdbc@eng.sun.com</a> 或 <a
href="mailto:jdbc-business@eng.sun.com">jdbc-business@eng.sun.com</a>
</address>
<a href="../../../relnotes/SMICopyright.html"><font size="-1"><i>
<p>版权所有 © 1996, 1997 Sun Microsystems, Inc. 保留所有权利</i></font>。</a><!-- HTML generated by Suzette Pelouch on June 09, 1998 -->
</p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -