关键字:
KingbaseES、JDBC、人大金仓
JDBC介绍
Java数据库连接即JDBC是一种Java标准,提供了从Java连接到关系型数据库的接口。JDBC标准是通过标准java.sql接口定义和实现的,数据库厂商能够通过实现和扩展JDBC标准,实现自身的JDBC驱动程序。
Kingbase JDBC介绍
KingbaseES JDBC提供了Java的JDBC驱动程序kingbase8jdbc,它支持SUN JDBC 3.0和部分4.0API的标准。通过JDBC接口对象,应用程序可以完成与数据库的连接、执行SQL语句、从数据库中获取结果、状态及错误信息、终止事务和连接等操作。
JDBC API 是Java平台的一个部分,它由两个包组成:java.sql和javax.sql。在java.sql和javax.sql中包含了多个类和多个标准接口。Kingbase JDBC主要实现了只写标准接口,还实现了特定的数据源接口。
目前,KingbaseES JDBC实现的标准接口有:
java.sql.Driver java.sql.Connection java.sql.Statement java.sql.PreparedStatement java.sql.CallableStatement java.sql.DatabaseMetaData java.sql.ParameterMetaData java.sql.ResultSet java.sql.ResultMetaData java.sql.Savepoint java.sql.Clob java.sql.Blob java.sql.SQLXML java.sql.Array java.sql.RowId java.sql.Struct javax.sql.DataSource javax.sql.CommonDataSource javax.sql.ConnectionEventListener javax.sql.ConnectionPoolDataSource javax.sql.PooledConnection javax.sql.XAConnection javax.sql.XADataSource |
JDBC的操作过程
在客户端使用KingbaseES JDBC来访问和操作KingbaseES数据库中的数据通常包括以下过程:
●建立与数据库的连接
●创建语句对象
●执行查询并返回结果集对象
●处理结果集对象
●关闭结果集和语句对象
●关闭与数据库的连接
JDBC建立和关闭连接
KingbaseES JDBC中提供了两种建立数据库的连接的方法:通过 DriverManager 和 DataSource。
●使用DriverManger连接数据库
●JDBC连接属性
●使用DataSource连接数据库
1.如果应用程序需要通过KingbaseES JDBC来访问和操纵KingbaseES数据库中的数据,则应在程序开始时先装载KingbaseES的JDBC,可以使用下面的语句进行装载:
Class.forName("com.kingbase8.Driver"); 或 DriverManager.registerDriver(new com.kingbase8.Driver()); |
也可以直接通过以下调用来建立连接:
Connection con = DriverManager.getConnection(TestUtil.getURL(), TestUtil.getUser(), TestUtil.getPassword()); |
2.与数据库建立连接的标准方法是调用DriverManger.getConnection方法,它由以下三种调用格式:
●getConnection(url, user, password)
●getConnection(url, java.util.Properties)
●getConnection(url)
3.在KingbaseES JDBC中,数据库是用URL表示的,目前KingbaseES JDBC支持以下几种地址格式:
jdbc:kingbase8:database jdbc:kingbase8://host/database jdbc:kingbase8://host:port/database jdbc:kingbase8://host:port/database?para1=val1¶2=val2… |
5.常用的建立数据库连接所需的所有步骤的示例:
Connection con; /* 加载驱动程序 */ Class.forName("com.kingbase8.Driver"); String url = "jdbc:kingbase8://localhost:54321/testdb"; con = DriverManager.getConnection(url,"userID","passwd"); |
DataSource 接口是在 JDBC 3.0 的规范中定义的另外一种获取数据源连接的方法。使用 DataSource 进行数据库连接可以提高应用程序的可移植性,因为应用程序使用一个逻辑名称建立与数据库的连接,该逻辑名通过使用 JNDI(Java Naming and Directory Interface) 命名服务映射到真正的 DataSource 对象,该 DataSource 对象表示了一个真正的数据库连接。如果数据源的信息发生变化,只需修改该 DataSource 对象的属性,而不需要修改应用程序。
KingbaseES JDBC 在 KBSimpleDataSource 类中实现了 DataSource 接口,在 Jdbc3PoolingDataSource 类中实现了具有连接池功能的 DataSource 接口。下面分别介绍它们的使用方式。
4.2.1 使用 DataSource 连接数据库(不使用JNDI)
通过DataSource来建立连接的过程主要分为以下几个步骤:
1.创建KBSimpleDataSource
创建一个 KingbaseES 的 DataSource,要执行以下语句:
KBSimpleDataSource ds = new KBSimpleDataSource(); |
2.初始化连接属性
标准的 DataSource 属性包括:databaseName,password, portNumber,serverName,user。用户通过以下方法来对这些属性进行设置:
setDatabaseName(String dbname); setPassword(String pwd); setPortNumber(int pn); setServerName(String sn); setUser(String user); |
4.2.2 使用 DataSource 连接数据库(使用JNDI)
KingbaseES JDBC 驱动程序提供通过 JNDI 查找方式来获取数据源的方法,其步骤如下:
1.建立数据源
KBSimpleDataSource ds = new KBSimpleDataSource(); ds.setDatabaseName("test") ; ds.setUser("system") ; ds.setPassword("manager") ; ds.setPortNumber(54321) ; /* 通过JNDI绑定数据源 */ Context ctx = null; try { Hashtable env = new Hashtable (5); env.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); /* "file:/job/jndi"中,要在本程序运行的盘上建立目录job和其子目录jndi */ env.put (Context.PROVIDER_URL, "file:/job/jndi"); ctx = new InitialContext(env); } catch (NamingException ne) { ne.printStackTrace(); } /* 绑定JNDI和数据源 */ ctx.rebind("DataSource", ds); |
2. 通过 JNDI 查找来获取数据源
/* 开始使用数据源 */ Context ctx2 = null; try { Hashtable env = new Hashtable (5); env.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); env.put (Context.PROVIDER_URL, "file:/job/jndi"); ctx2 = new InitialContext(env); } catch (NamingException ne) { ne.printStackTrace(); } /* 通过 JNDI 查找到数据源 */ DataSource ds2 = (DataSource)ctx2.lookup("DataSource"); |
3.使用数据源做SQL语句处理
Connection conn = ds2.getConnection(); Statement stmt = conn.createStatement() ; String sql = "select * from tu9"; ResultSet rs = stmt.executeQuery( sql ) ; while ( rs.next() ) { System.out.print(rs.getString("name") + rs.getString("nick")) ; } System.out.println(); rs.close() ; stmt.close() ; conn.close(); |
关闭与数据库的连接,只需要对连接对象conn调用close()方法:
conn.close(); |
JDBC创建语句对象
连接一旦建立,就可向数据库传送 SQL 语句,而且对可被发送的 SQL 语句类型不加任何限制,它允许使用特定的数据库语句。KingbaseES JDBC 提供了三个类,用于向数据库发送 SQL 语句,Connection 接口中的三个方法可用于创建这些类的实例:
●Statement 对象:由方法 createStatement 所创建,用于发送简单的 SQL 语句。
●PreparedStatement 对象:由方法 prepareStatement 所创建,用于发送带有一个或多个输入参数(IN 参数)的 SQL 语句。
●CallableStatement 对象:由方法 prepareCall 所创建,用于执行 SQL 存储过程。
Statement 对象由方法 createStatement 所创建,Statement 对象用于发送简单的 SQL 语句,来进行查询或对数据库进行更新,Statement 对象提供三种方法执行 SQL 语句:
●execute 方法用于执行返回多个结果集或更新多个元组的 SQL 语句;
●executeQuery 方法用于执行返回单个结果集的 SQL 语句;
●executeUpdate 方法用于执行含有 INSERT、UPDATE 或 DELETE 语句或者不返回任何内容的 SQL 语句,如 DDL 语句。
●Statement对象的使用:
Connection conn = DriverManager.getConnection(url, "system", "manager"); Statement stmt=conn.createStatement(); stmt.executeUpdate("update table1 set col1=1"); |
数据库服务器在处理 SQL 语句时都是首先生成该语句的执行计划,然后执行。对于有些应用需要反复处理拥有相同执行计划的语句,就会浪费处理资源,这时就可以使用 PreparedStatement 对象,这样,数据库服务器可以提前取得 SQL 语句,并为它创建查询计划,以后该语句就可以多次执行。
- 生成一个 PreparedStatement 对象,对语句进行预编译。
- 设置参数。
- 执行语句,获取结果。
- PreparedStatement 对象的使用
Connection conn = DriverManager.getConnection(url, "system", "manager"); PreparedStatement pstmt = conn.prepareStatement( "UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?"); int i; for (i = 0; i < employee.length; i++) { pstmt.setBigDecimal(1, employee[i].salary); pstmt.setInt(2, employee[i].id); pstmt.executeUpdate(); } |
CallableStatement 对象从 PreparedStatement 中继承了用于处理 IN 参数的方法,而且还增加了用于处理 OUT 参数和 INOUT 参数的方法。处理一个存储过程的 SQL 语句通常包括以下过程:
●生成一个 CallableStatement 对象,对语句进行预编译。
●提取参数信息。
●设置参数。
●注册输出参数。
●执行语句。
●获取输出参数的返回值
●CallableStatement类的使用
Connection conn = DriverManager.getConnection(url, "system", "manager"); Statement statement = conn.createStatement(); /* 存储过程语句,该语句需在oracle兼容模式下执行 */ String sql = "create or replace procedure procName (inout id int," + " in name char(20), out salary float) as " + "begin " + "select number into id from callable " + "where number = id and xm = name;" + "select gz into salary from callable " + "where number = id and xm = name;" + "end;"; /* 执行语句,创建 CallableStatement 对象 */ statement.execute(sql); CallableStatement cstmt = conn.prepareCall("{call procName(?,?,?)}"); /* 参数1为INOUT类型,参数2为IN类型,参数3为OUT类型 */ /* 注册输出参数 */ cstmt.registerOutParameter(1,Types.INTEGER); cstmt.registerOutParameter(3,Types.REAL); |
JDBC查询结果集处理
建立服务器连接后,我们可以在该连接上执行查询语句,并返回结果集对象,具体方法如下:
●创建一个语句对象
Statement stmt=conn.createStatement(); |
●执行一条SQL查询语句,并返回结果集
ResultSet rs=stmt.executeQuery("select * from table1"); 或者 stmt.execute("select * from table1"); ResultSet rs=stmt.getResultSet(); |
●结果集的读取
在 ResultSet 第一次创建时,指针定位在第一行的前面,通过 ResultSet 中提供的各个定位函数使 ResultSet 指针指向实际要访问的数据行,然后使用 getXXX 方法读取结果集中当前行或列的值。
next()方法
Statement stmt=conn.createStatement(); ResultSet rs=stmt.executeQuery("select * from table1"); while (rs.next()) System.out.println(rs.getInt (1)); |
●对结果集的更新
Statement stmt=conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); ResultSet rs=stmt.executeQuery("select * from table1"); rs.next(); System.out.println("updata before: " + rs.getInt(1)); rs.updateInt(1,21);/* 修改当前行第一列的值为21。 */ rs.updateRow();/* 作用于数据源 */ System.out.println("updata after: " + rs.getInt(1)); |
关闭结果集与数据库的连接
Connection conn = DriverManager.getConnection(url, "system", "manager"); Statement stmt=conn.createStatement(); ResultSet rs=stmt.executeQuery("select * from table1"); Stmt.close(); Conn.cloase(); |
参考文档
《KingbaseES 客户端编程接口》