本文给出一个通过JDBC连接Oracle数据库的实例,希望对JDBC初学者有所帮助。我没有像很多例子那样一个函数就把整个JDBC的操作全部完成,这样的代码在企业项目开发中一般是不能通过审核的,我现在工作的公司就对代码规范有严格要求。比如,“一个函数,只做一件事”。这意味着你不能把一大堆功能代码放在一个函数里,需要拆分。另外,一个函数的代码行数也有严格要求,一般不能超过80行。所以,那些一个函数几百行的代码绝对通不过审核,除非这个公司根本不在乎编码规范。初学者可能觉得这个好苛刻,其实这非常合理,代码是写给人看的,附带在机器上执行,所以养成一个好的编码规范,方便后期的代码维护,利己又利人,何乐而不为?
本文的价值在于提醒编程者注意代码规范,当然我写的不一定规范,仅仅是参考,我也正在提升自己的编码规范的道路上。另外,在实际的开发中,特别是高访问量、高并发的系统中,不会直接通过JDBC来操作数据库,而会通过数据库连接池来操作数据库,这会大大提升性能。因为数据库连接是一个基于TCP协议的网络连接,需要很多资源,频繁地对数据库进行连接、断开会严重影响系统性能。
下面是我的代码,感谢参考和完善!主要展示Connection、PreparedStatement、ResultSet和ResultSetMetaData的基本用法,另外我之所以不使用Statement,是因为PreparedStatement比Statement有以下优势:
> PreparedStatement预编译SQL语句,性能更好;
> PreparedStatement不需要拼接SQL语句,而拼接SQL语句非常容易出错;
> PreparedStatement可以防止SQL注入,拥有更高的安全性。
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.PreparedStatement;
-
import java.sql.ResultSet;
-
import java.sql.ResultSetMetaData;
-
import java.sql.SQLException;
-
-
public class OracleJDBCDemo {
-
private Connection con = null; // 数据库连接对象
-
private PreparedStatement psmt = null; // 预编译语句对象
-
private ResultSet result = null; // 结果集对象
-
-
/**
-
* 建立数据库连接
-
*
-
* @return
-
* @throws ClassNotFoundException
-
* @throws SQLException
-
*/
-
public Connection setUpConnection() throws ClassNotFoundException, SQLException {
-
Class.forName( "oracle.jdbc.driver.OracleDriver"); // 加载Oracle驱动程序
-
String url = "jdbc:oracle:thin:@" + "host:port:databaseName"; // 连接使用的url
-
String user = "your database userName"; // 数据库用户名
-
String password = "your database password"; // 密码
-
con = DriverManager.getConnection(url, user, password); // 获取连接
-
-
return con;
-
}
-
-
/**
-
* 执行查询
-
*
-
* @return
-
* @throws SQLException
-
*/
-
public ResultSet query() throws SQLException {
-
StringBuilder sql = new StringBuilder( "SELECT * ").
-
append( "FROM BFM_USER").
-
append( " WHERE USER_CODE=?");
-
psmt = con.prepareStatement(sql.toString()); // 预编译SQL
-
psmt.setString( 1, "admin"); // 设置参数
-
result = psmt.executeQuery(); // 执行SQL
-
return result;
-
}
-
-
/**
-
* 分析查询结果集的元数据信息
-
*
-
* @throws SQLException
-
*/
-
public void analyzeResultSet() throws SQLException {
-
ResultSetMetaData rsmd = null;
-
StringBuilder sb = null;
-
rsmd = result.getMetaData(); // 获取查询游标的元数据对象
-
sb = new StringBuilder();
-
System.out.println( "列数目:" + rsmd.getColumnCount());
-
for ( int i = 0; i < rsmd.getColumnCount(); i++) {
-
sb.append( "列名:" + rsmd.getColumnName(i + 1) + " ");
-
sb.append(rsmd.getColumnType(i + 1) + " ");
-
sb.append(rsmd.getColumnLabel(i + 1) + " ");
-
sb.append( "列最大宽度:" + rsmd.getColumnDisplaySize(i + 1) + "个字符 ");
-
sb.append( "数据类型:" + rsmd.getColumnTypeName(i + 1));
-
System.out.println(sb.toString());
-
sb.delete( 0, sb.length());
-
}
-
}
-
-
/**
-
* 打印查询到的结果
-
*
-
* @throws SQLException
-
*/
-
public void printResult() throws SQLException {
-
StringBuilder sb = null;
-
sb = new StringBuilder();
-
while (result.next()) {
-
for ( int i = 0; i < result.getMetaData().getColumnCount(); i++) {
-
sb.append(result.getString(i + 1) + " ");
-
}
-
System.out.println(sb.toString());
-
sb.delete( 0, sb.length());
-
}
-
}
-
-
/**
-
* 关闭数据库连接
-
*
-
* @throws SQLException
-
*/
-
public void closeConnection() throws SQLException {
-
if ( null != result) {
-
result.close();
-
}
-
if ( null != psmt) {
-
psmt.close();
-
}
-
if ( null != con) {
-
con.close();
-
}
-
}
-
-
public static void main(String[] args) {
-
OracleJDBCDemo ojdbc = new OracleJDBCDemo();
-
try {
-
ojdbc.setUpConnection(); // 建立连接
-
ojdbc.query(); // 执行查询
-
ojdbc.printResult(); // 打印查询结果
-
ojdbc.analyzeResultSet(); // 分析查询游标的元数据
-
} catch (ClassNotFoundException | SQLException e) {
-
e.printStackTrace();
-
} finally {
-
try {
-
ojdbc.closeConnection();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
}
> 导入包的时候“按需导入”,不要一个星号就完事了;
> 实际开发中的异常处理是将捕获到的异常信息登记到log日志中,二不是简单的打印异常栈。
补充
加载MySQL驱动的写法:Class.forName("com.mysql.jdbc.Driver");
加载Oracle驱动的写法:Class.forName("oracle.jdbc.driver.OracleDriver");
MySQL的URL的写法:jdbc:mysql://hostname:port/databasename
Oracle的URL的写法:jdbc:oracle:thin:@hostname:port:databasename