因为工作需要,经常访问Access数据库,封装了一个类。
阅读之前最好了解JDBC基本的连接步骤,可参考:
http://www.yiibai.com/jdbc/jdbc_quick_guide.html
1.假设数据库只需访问一次,可使用静态方法,省去调用时需要实例化。
1.1 首先是类成员,将JDBC驱动、文件路径前缀部分、用户名、密码赋值给成员变量。
private static String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
private static String db_url= "jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=";
private static String user = "admin";
private static String password = "654321";
1.2 调用静态方法返回ArrayList<HashMap<Object, Object>>封装的结果集。
/**
* @param mdbFilePath *.mdb文件绝对路径
* @param sql sql查询语句
*/
public static ArrayList<HashMap<Object, Object>> getResultMap(String mdbFilePath,String sql){
ArrayList<HashMap<Object, Object>> result = new ArrayList<HashMap<Object, Object>>();
Connection conn = getConnection(mdbFilePath); //获取连接
Statement stmt = null;
try{
stmt = conn.createStatement();
ResultSet res = stmt.executeQuery(sql);
result = convertResultSetToArrayList(res); //转换结果集为映射列表
}catch(Exception e){
e.printStackTrace();
}finally{
close(stmt, conn);
}
return result;
}
1.3 获取连接,静态方法。
/**
* @param mdbFilePath *.mdb文件的绝对路径
* @return Connection
*/
private static Connection getConnection(String mdbFilePath){
Connection conn = null;
try{
Class.forName(driver); //初始化驱动
String url = db_url + mdbFilePath;
conn = DriverManager.getConnection(url,user,password);
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
1.4 转换结果集为映射列表,静态方法。
/**
* @param rs 结果集
* @return 映射列表ArrayList<HashMap<Object, Object>>
* @throws Exception
*/
private static ArrayList<HashMap<Object, Object>> convertResultSetToArrayList(ResultSet rs) throws Exception {
ResultSetMetaData rsmd = rs.getMetaData();
ArrayList<HashMap<Object, Object>> mapList = new ArrayList<HashMap<Object, Object>>();
while (rs.next()) {
HashMap<Object, Object> map = new HashMap<Object, Object>();
for (int i = 0; i < rsmd.getColumnCount(); i++) {
map.put(rsmd.getColumnName(i + 1), rs.getString(rsmd.getColumnName(i + 1)));
}
mapList.add(map);
}
return mapList;
}
1.5 关闭资源,静态方法。
private static void close(Statement stmt, Connection conn){
try{
if(stmt != null){
stmt.close();
}
if(conn != null){
conn.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
1.6 类名定义为MdbConnector,用法如下:
String path = "D:\\Language.mdb";
String sql = "SELECT * FROM table1 ";
ArrayList<HashMap<Object, Object>> mapList = MdbConnector.getResultMap(path,sql);
2.假设数据库需要多次访问,可以实例化对象并持有连接,减少重复连接的开销。
2.1 新增两个成员变量:
private Connection conn;
private Statement stmt;
2.2 带参构造方法,使对象持有Connection和Statement:
/**
* @param mdbFilePath *.mdb文件的绝对路径
*/
public MdbConnector(String mdbFilePath){
conn = getConnection(mdbFilePath);
try {
stmt = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
2.3 重载getResultMap方法,使用对象持有的Statement执行SQL语句:
/**
* 从数据库获取查询结果映射列表
* @param sql sql查询语句
* @return 查询结果映射列表
*/
public ArrayList<HashMap<Object, Object>> getResultMap(String sql){
ArrayList<HashMap<Object, Object>> result = new ArrayList<HashMap<Object, Object>>();
try{
ResultSet res = stmt.executeQuery(sql);
result = convertResultSetToArrayList(res);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
2.4 重载close方法:
public void close(){
close(stmt,conn);
}
2.5 用法如下,注意不再需要连接时手动调用close()关闭资源:
String path = "D:\\Language.mdb";
MdbConnector mcont = new MdbConnector(path);
for(int i = 0;i < 100;i++){
String sql = "SELECT name FROM slist WHERE id = '" + i +'";
ArrayList<HashMap<Object, Object>> mapList = mcont.getResultMap(sql);
…… //业务逻辑
}
mcont.close();
3.导入包
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
或者也可以:
import java.util.*;
import java.sql.*;
额外说一下:
第一种方法节约了导入不需要的类的时间,但是不明显。
第二种方法如果声明new Date(),会产生歧义,因为两个包都有Date类。
当然这次的类用哪种方法都可以。
结尾
我知道的不足之处:
1.ArrayList和HashMap线程不安全;
2.重复访问数据库一定次数后,PreparedStatement比Statement速度更快。
3.据说是jdbc-odbc的缺陷,无法将PreparedStatement的?占位符替换为参数,原因似乎是varchar和char的区别,我没找到解决方法。如果有大神知道方法,请赐教!
网友评论