因为项目的原因,需要和Access数据库打交道,先不说这语法和MySQL的略有不同,先是这第一步连接数据库这一步就尝试了很多种方法,花了不少的时间。
首先尝试的是用Access_JDBC30.jar这个第三方包(具体可以参考这篇博客),这个是可以读取数据的,但是存在一个问题,就是未注册版只能读取前1000行,这是一个致命的问题,虽说是网上有破解版,但万一出现什么问题呢,这是最基础的部分,后期出了问题可就麻烦了,遂弃之。
因为数据库服务器和项目服务器不是同一个,所以需要通过远程连接的方式去访问access数据库,然后继续网上搜索,发现了《java连接access数据库的三种方式以及远程连接》这篇博客的第三种方法:Rmi远程连接,尝试后发现很好用,遂分享一下操作方法以及写的一个Demo。
首先说一下服务器端的配置,我用了一个安装了Windows XP的虚拟机来模拟远程数据库服务器,因为这个Rmi驱动时基于Java平台的,所以需要安装一个Java运行环境,这里要注意安装jre8以下的版本,因为8及以上的版本取消了jdbc-odbc桥,但是我们这里还是需要配置odbc数据源的。
操作系统 | Windows XP Professional SP3 |
软件 | ①jre-7u79-windows-i586.exe ②RmiJdbc.jar |
具体步骤请参考上文提到的博客,这里补充一个小功能,就是开机自动加载驱动并且无窗口显示。当时我在客户机器上按照步骤启动rmi,成功连接并读取数据后,就断开了远程桌面连接,一段时间后发现又连接不上了,远程过去看了看,原来是管理员把rmi的运行窗口给关闭了,所以就连不上了。所以就有了下面的解决方案:
- 在RmiJdbc.jar的同一目录下新建一个bat批处理文件,例如run.bat,写入 java -jar RmiJdbc.jar
- 还是在同一目录,新建一个vbs脚本文件,例如access.vbs,写入 Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c run.bat",vbhide ,要注意的是,里面的.bat文件名要和第一步新建的文件名一致。- 在vbs文件右键,选择发送到桌面快捷方式,然后回到桌面,将此快捷方式复制或移动到 C:\Documents and Settings\Administrator\「开始」菜单\程序\启动 这个文件夹里面,也就是开始菜单里面的启动文件夹,具体的位置以及进入方式视操作系统的不同而不同,请百度。
这样的话,每次重启或者开机的时候就会自动开启rmi了。
下面是一个工具Demo:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
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.List;
import java.util.Map;
import com.alibaba.fastjson.JSON;
public class AccessHelper {
String url;
String username;
String password;
public static void main(String[] args) throws InstantiationException, IllegalAccessException, SQLException {
// TODO 自动生成的方法存根
AccessHelper ack = new AccessHelper("jdbc:rmi://192.168.xx.xx/jdbc:odbc:dbName", "administrator", "password");
String sql = "Select top 10 * From USER";
System.out.println(JSON.toJSON(ack.query(sql)));
}
public AccessHelper(String url, String username, String password) {
// TODO 自动生成的构造函数存根
this.url = url;
this.username = username;
this.password = password;
}
public List<Map<String, Object>> query(String sql)
throws InstantiationException, IllegalAccessException, SQLException {
List<Map<String, Object>> res = new ArrayList<>();
try {
Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
System.out.println("Driver Loading Completed");
Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
ResultSetMetaData md = rs.getMetaData();// 获取键名
int columnCount = md.getColumnCount();// 获取行的数量
while (rs.next()) {
Map<String, Object> info = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
String Key = md.getColumnName(i);
Object value = rs.getObject(i);
info.put(Key, value);
}
res.add(info);
}
rs.close();
stmt.close();
conn.close();
} catch (ClassNotFoundException e) {
System.out.print(e);
}
return res;
}
public int update(String sql) throws InstantiationException, IllegalAccessException, SQLException {
int total = 0;
try {
Class.forName("org.objectweb.rmijdbc.Driver").newInstance();
System.out.println("Driver Loading Completed");
Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
int l = stmt.executeUpdate(sql);
System.out.println("Update item counts:" + l);
total = l;
stmt.close();
conn.close();
} catch (ClassNotFoundException e) {
System.out.print(e);
}
return total;
}
}