JDBC 是执行SQL 语句的JAVA API,由一系列使用Java 编写的类和接口组成。JDBC为工具和数据库开发人员提供标准API并使使用纯JAVA API 编写数据库应用成为可能。JDBC 是个低级的接口,意味着它只是用来直接调用SQL 命令。另外,JDBC 也作为诸如JMS和EJB等高级界面和接口的基础。
金蝶Apusic应用服务器支持JDBC4.0版本,JDBC4.0是本文档书写时JDBC API最新发布版。 有关JDBC3.0的特性,参见JDBC4.0特性。
JAVA 数据库连接(JDBC)提供对后台数据库的访问,JAVA 应用通过使用JDBC驱动程序(数据库供应商指定的数据库接口)取得对JDBC 的使用。尽管任何JAVA 应用都可以装载JDBC 驱动程序、连接数据库、执行数据库操作,Apusic应用服务器还提供一个高效的JDBC 数据库连接池。JDBC 数据库连接池是一个通过金蝶Apusic应用服务器管理的JDBC连接的命名组。金蝶Apusic应用服务器启动时打开JDBC 数据库连接并把他们加入到JDBC数据库连接池中。当应用请求一个连接时,应用从池中取得连接,使用后将连接返回到池中以备被其他应用使用。通常,建立数据库连接是个耗费时间和资源的操作。因此,通过限制连接操作次数的连接池,能提高服务器的效率。要在JNDI命名树中登记一个连接池,只需为它定义一个DataSource对象。Java 客户端应用通过对DataSource名字执行JNDI查找,即可从连接池中获取连接。服务器端Java类使用标准JDBC 接口,它是一个一般化的JDBC驱动程序接口。即使在数据层改变了数据库的类型,也不用更改应用的代码,使应用具有更强的可移植特性。
金蝶Apusic应用服务器提供已准备好的对DBMS 的连接池。连接池启动时连接即建立,消除了应用运行时建立连接的拥挤状态。可以从如HTTPServlet、EJB 等服务器端应用使用连接池和通过Apusic 的RMI 服务使用独立Java 客户端应用程序访问连接池。连接池需要一个两层的JDBC驱动程序生成Apusic 到DBMS 的连接。
对于从服务器端应用如HTTP Servlet 等使用数据库连接池可使用JNDI 和DataSource对象,下例将在一个Servlet中使用数据源来演示从服务器端应用数据库连接池。
import javax.servlet.*; import javax.servlet.http.*; import javax.sql.*; import java.sql.*; import javax.naming.*; public class ConnectionPoolServlet extends javax.servlet.http.HttpServlet{ public void service(HttpServletRequest req, HttpServletResponse res)throws IOException{ try{ //取得InitialContext 对象 Context ctx=new InitialContext(); //通过JNDI 取得数据源 DataSource datasource=(DataSource) ctx.lookup("jdbc/oracle"); //通过数据源取得数据库连接 Connection conn=datasource.getConnection(); ... } } ...
金蝶Apusic应用服务器增加了JDBC 连接的远程访问接口,用户可以在Java客户端程序中通过RMI 调用JDBC连接池中的连接。
第一,如要实现在Java 客户端程序中通过RMI 调用JDBC连接池中的连接,必须在datasources.xml中,为相应的数据库连接设定其通过远程连接需要的户认证标记。方法如下,首先设定将使用此连接的Apusic组或用户,如:your_group<组名>或your_user<用户名>;然后在datasources.xml中添加<remote-acl>标记及其元素。范例如下:
<remote-acl> <user>username</user> </remote-acl> 或 <remote-acl> <group>groupname</group> </remote-acl>
第二,在客户端Java 程序中,将相关的验证信息加入到环境参数中,即Apusic用户名及密码。范例如下:
import javax.sql.*; import java.sql.*; import javax.naming.*; import javax.rmi.*; public class RMIJdbc public static void main(String[] args){ Hashtable env=new Hashtable(); Context initCtx=null; DataSource datasource=null; try{ env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.naming.jndi.CNContextFactory"); env.put(Context.PROVIDER_URL,"iiop://APUSIC_ADDRESS:6888"); //插入相关验证信息 env.put(Context.SECURITY_CREDENTIALS,"your_username" ) ; env.put(Context.SECURITY_PRINCIPAL,"your_password"); initCtx=new InitialContext(env); //通过RMI 取得数据库连接 datasource=(DataSource)initCtx.lookup("jdbc/sample") Connection conn=datasource.getConnection(); }catch(Exception e){ e.printStackTrace(); } ... }
最后,编译客户端代码并执行。如不能连接,请检查是否可以通过servlet 或EJB 进行连接, 可参考上节"2.1服务器端应用"中相关内容。
下面的例子是JAVA应用程序直接访问数据源的例子。数据库是Oracle,表是scott下的customer。
第一步:建立数据源。
在Apusic管理工具中,打开“驾驶舱”-->“数据源”-->“新增数据源”,在“添加数据源”界面下连接池中填写如下信息:
如果需要提供可供远程访问的数据源,请参考第 33.2.1 节 “编辑datasources.xml文件”配置
第二步:JAVA应用程序代码:
/** * Title: JDBCTest * Description: JDBC Test * Copyright: Copyright (c) 2003 * Company: Apusic * @author Michael * @version 1.0 */ import java.util.*; import javax.ejb.*; import java.sql.*; import javax.sql.*; import javax.naming.*; public class JDBClient { private Connection con = null; private PreparedStatement prepStmt = null; /** * dbName 对应第一步在创建数据源时的“基本”表格中“连接池JNDI名” */ private String dbName = "jdbc/sample"; public JDBClient() { } public void run(){ try{ Hashtable env = new Hashtable(); // url 中的localhost可以替换为任意可连通的已安装Apusic应用服务器的主机名或地址 String url = "iiop://localhost:6888"; env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.naming.jndi.CNContextFactory"); env.put(Context.PROVIDER_URL, url); // 下面的用户必须是在Apusic中存在的,并且是在“远程访问控制用户列表”中定义的用户 env.put(Context.SECURITY_PRINCIPAL ,"scott"); env.put(Context.SECURITY_CREDENTIALS ,"tiger"); InitialContext ic = new InitialContext(env); DataSource ds = (DataSource) ic.lookup(dbName); con = ds.getConnection(); // customer 是Oracle自带的scott下的表 String selectStatement = "select * from customer" ; prepStmt = con.prepareStatement(selectStatement); ResultSet rs = prepStmt.executeQuery(); System.out.println("FIRSTNAME " + "LASTNAME" ); while (rs.next()) { System.out.println(rs.getString("FIRSTNAME") +" "+ rs.getString("LASTNAME")); } }catch(Exception e){ e.printStackTrace() ; } finally { cleanup(con,prepStmt); } } private void cleanup(Connection con, PreparedStatement ps) { try { if (ps != null) ps.close(); } catch (SQLException e) { e.printStackTrace() ; } try { if (con != null) con.close(); } catch (SQLException e) { e.printStackTrace() ; } } public static void main(String[] args) { JDBClient _jdbctest = new JDBClient(); _jdbctest.run(); } }
正确的执行结果为:
FIRSTNAME LASTNAME
sunny sunny Yuan
Judy Judy Li
John John Wan
Peter Peter Miao