日期:2014-05-16  浏览次数:20446 次

实战 Java 存储过程的编写及在 DB2 上的部署【来源于网络】

????? 在一个设计良好的数据库应用中,存储过程(Stored Procedure)几乎是必不可少的。存储过程可以有效的节约查询的网络开销,并且降低应用部署的难度。Java 存储过程是 DB2 存储过程的一个重要分类,既拥有 Java 语言的灵活性又拥有一般存储过程的优点,同时可以让大量的 Java 开发人员只需经过简单的学习,就可以编写服务器端的存储过程应用。
????? DB2 对 Java 存储过程一直有着良好的支持,DB2 各个版本均自带有 JDK 并且已经配置妥当,用户无需复杂的操作即可直接开始部署 Java 存储过程。并且 DB2 已经提供了整套存储过程部署的工具以方便数据库管理人员。
??? 在 DB2 中 Java 存储过程是一个相对独立的模块,它运行于 JVM 之上而不是直接运行于数据库之中,与用 SQL 写成的存储过程相比,Java 存储过程的编写方法更类似于传统的 Java 应用。下图简单的表示了 DB2 中的执行 Java 存储过程的体系结构:


图 1. DB2 中的执行 Java 存储过程的体系结构
DB2 中的执行 Java 存储过程的体系结构

????? 当然,与一般的 Java 程序相比,Java 存储过程在其设计、编写过程中,还是有许多不同之处。本文之后的章节以一个 Java 程序员的角度,从一个简单的例子出发,逐步介绍了如何编写一个 Java 存储过程,并在 DB2 中进行部署及调用该存储过程。

Java 存储过程的编写

在本章节中,我们将通过把一个程序修改为 DB2 中的一个存储过程,来介绍一般存储过程的编写方式。首先我们设计一个简单的数据库查询程序:


清单 1 一个简单的数据库调用函数

					
	 public ResultSet hello(int intp) throws ClassNotFoundException, 
			 SQLException { 
		 Class.forName("com.ibm.db2.jcc.DB2Driver"); 
		 Connection conn = DriverManager.getConnection( 
				"jdbc:db2://localhost:50000/test", "user", "password"); 
		 String sql = "SELECT * from t1 where c1 = ?"; 
		 PreparedStatement ps = conn.prepareStatement(sql); 
		 ps.setInt(1, intp); 
		 ResultSet rs = ps.executeQuery(sql); 
		 return rs; 
	 } 
    

?

下面一步步将其改写为一个 DB2 标准的 Java 存储过程:

步骤 1:将函数修改为 public static 函数

就像普通 Java 程序中的 main 函数一样,作为入口点的存储过程函数,必须是 public 和 static 的。当数据库用户调用这个存储过程时,数据库会把用户传入的参数进行适当的处理,并传给这个 Java 方法。Java 方法执行完毕之后,将结果返回给数据库。

步骤 2:修改函数返回值的方式

我们知道,数据库中的存储过程没有函数返回值的概念的所有的返回值都是通过参数来传递的。在 Java 中并没有 C 语言中的指针的概念,因此想要把返回值放在参数中,就必须要使用数组。从数组中提取返回值的操作由 DB2 完成,我们只需要把需要返回的参数声明为一个数组。具体方法可以参考下面的例子。
经过前两步的修改,我们的程序变为:


清单 2 初步修改的函数

					
	 public static void hello(int inp, ResultSet[] rs) 
			 throws ClassNotFoundException, SQLException { 
		 Class.forName("com.ibm.db2.jcc.DB2Driver"); 
		 Connection conn = DriverManager.getConnection( 
				"jdbc:db2://localhost:50000/test", "user", "password"); 
		 String sql = "SELECT * from t1 where c1 = ?"; 
		 PreparedStatement ps = conn.prepareStatement(sql); 
		 ps.setInt(1, intp); 
		 rs[0] = ps.executeQuery(sql); 
	 } 
    

?

步骤 3:修改函数中的 connection

这一步是可选的,要依据数据库的需要的具体逻辑来定。一般来说,存储过程中的数据库连接不应该硬编码到程序里,而是获得当前默认的数据库连接——也就是该存储过程安装到的那个数据库。经过这一步的修改,我们的程序变为:


清单 3 可用作存储过程的函数

					
	 public static void hello(int inp, ResultSet[] rs) 
			 throws ClassNotFoundException, SQLException { 
		 Class.forName("com.ibm.db2.jcc.DB2Driver");