文章目录
- 一、前言
- 二、概述
- 三、具体实现
- 1、思路
- 2、access数据库连接
- 3、环境搭建(如果jdk版本低于8,可以直接跳过)
- 4、代码
- 四、总结
一、前言
知识是伟大的,奉献知识的人更是伟大的!
java生成Access数据库文件https://community.yellowfinbi.com/knowledge-base/article/moving-the-jdbc-odbc-bridge-from-java-7-to-java-8java连接access数据库的三种方式 从以上博客中深受启发。
二、概述
- 最近应项目要求,需要将项目数据导出成.mdb格式文件,而.mdb格式文件本身是access数据库文件。所以问题变成从 系统数据库(postgreSQL)中读取数据,然后将数据写入到.mdb文件中。
- 环境:
|配置|版本|
| 系统 | win10 |
| access | access 97 |
| jdk | jdk8 |
三、具体实现
1、思路
大致思路如下:
- 导出模板:服务端必须存在一个空白的access数据库mdb格式文件(且该文件必须在本机上可以打开,总结里会提到)
- 服务器将mdb模板复制到本地指定的某个路径下,如C:\data.mdb(作为数据库/源)
- 当前端用户发起请求后,后台从postgre数据库中获取相应的数据保存到内存
- 代码尝试连接该数据库,然后将内存中的数据添加到数据库中
- 读取写完之后的data.mdb文件,返回给前端进行下载
2、access数据库连接
要实现将数据写到mdb文件中,与word、pdf或者txt文件格式不同,mdb本身是数据格式文件,其中包括有access数据库的模式、表格、字段等格式限制,需要根据相对应的字段来填入相应的数据。所以我们应该如使用oracle、mysql或者postgre一样,使用sql语言来进行操作。
- 连接access数据库,网上的内容有很多,但是都比较杂乱,不具有针对性。没有特别细致的介绍,所以笔者打通了其中一种方法,供后来者参考。
- 现在网上存在的三种方法分别如下:
① 电脑配置数据源结合java实现
② 纯java代码实现
③ 使用RmiJdbc.jar(远程连接的方法)
本文主要针对第二种方法进行实现。
3、环境搭建(如果jdk版本低于8,可以直接跳过)
要通过JDBC-ODBC桥接器的方式,连接access数据库只能使用jdk1.8以下的版本,因为JDK1.8已经在JDK包里去除了这个类,所以系统找不到该类,将会出现以下错误。
但是如果要将jdk版本还原到1.7版本,显然是不可能的。
幸运的是,我们找到了解决办法
其中的jdbc.jar包,可以到网上下载,亦或使用Tomcat中lib文件中的jdbc.jar包,其实是一样的。
环境配置好之后,剩下的就是撸代码了!!!!
4、代码
可以将与access数据库的连接封装成一个工具类,方便后期调用。
/**
* @Description:Access数据库连接类
* @author:Yex
* @data: 2019年12月9日 下午2:53:36
*/
class ConnectionAccessDB {
private static Connection connection = null;
private static java.sql.Statement statement;
private static String blankMdbFilePath; //空白mdb文件路径
// 新mdb文件路径
public static String defaultSavedMdbFilePath = "C:\\data.mdb";
// 新mdb文件名
//public static final String defaultSavedMdbFileName = "data.mdb";
// mdb文件后缀
public static final String defaultSavedMdbFileExtension = ".mdb";
// 需要保存到的新的mdb文件路径和名
private static String savedMdbFilePathAndName = defaultSavedMdbFilePath;
public ConnectionAccessDB() {
}
public ConnectionAccessDB(String blankMdbFilePath) {
this.blankMdbFilePath = blankMdbFilePath;
}
public ConnectionAccessDB(String blankMdbFilePath, String defaultSaveMdbFilePath) {
this.blankMdbFilePath = blankMdbFilePath;
this.defaultSavedMdbFilePath = defaultSaveMdbFilePath;
}
/**
* 外部连接数据库
* @throws SQLException
*/
public Connection connected() throws SQLException{
try {
//获取xml配置数据库连接属性
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //+ ";DriverID=22;READONLY=true}"
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + savedMdbFilePathAndName.trim() ;
Properties pro = new Properties();
pro.setProperty("charSet","GB2312");
connection = DriverManager.getConnection(database, pro);
statement = connection.createStatement();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return connection;
}
/**
* @Description: 设置需要拷贝空白mdb所到的文件位置和名称
* @author: Yex
* @date: 2019年12月9日 下午2:49:43
*/
public void setSavedFilePathAndName(String newFilePathAndName) {
this.savedMdbFilePathAndName = newFilePathAndName;
}
/**
* @Description: 删除产生的文件
* @author: Yex
* @date: 2019年12月9日 下午2:50:36
*/
public void deleteOldMdbFile() throws Exception {
File oldTargetFile = new File(savedMdbFilePathAndName);
if (oldTargetFile.exists()) {
oldTargetFile.delete();
}
}
/**
* @Description: 将空白路径 拷贝到 指定的特定路径下,并作为数据源
* @author: Yex
* @date: 2019年12月9日 下午2:52:26
*/
public void copyBlankMdbFile() throws Exception {
FileInputStream is = new FileInputStream(blankMdbFilePath);
OutputStream out = new FileOutputStream(savedMdbFilePathAndName);
byte[] buffer = new byte[1024];
int numRead;
while ((numRead = is.read(buffer)) != -1) {
out.write(buffer, 0, numRead);
}
is.close();
out.close();
}
/**
* @Description: 执行sql语句
* @author: Yex
* @date: 2019年12月9日 下午2:52:50
*/
public void executeSql(String sql) throws Exception {
statement.execute(sql);
}
/**
* @Description: 关闭连接
* @author: Yex
* @date: 2019年12月9日 下午2:53:05
*/
public void closeConnection() throws Exception {
statement.close();
connection.close();
}
/**
* @Description: 数据库-插入语句
* @author: Yex
* @data: 2019年12月10日 下午3:54:35
*/
public void Insert(String tableName,String column, String values) throws SQLException {
String sql = "INSERT INTO " + tableName +
" (" + column + ")" + " values" +
"(" + values + ")";
statement.execute(sql);
}
/**
* @Description: 数据库-删除语句
* @author: Yex
* @data: 2019年12月10日 下午4:02:42
*/
public void Delete(String tableName, String condition) throws SQLException {
String sql = "DELETE FROM " + tableName +
" WHERE" + condition;
statement.execute(sql);
}
}
注意!!!!!!!!!!!!!!!!!
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + savedMdbFilePathAndName.trim() ;
Driver={Microsoft Access Driver (*.mdb, .accdb)}就是你的驱动名称,这个必须和你本地所存在的驱动对应起来,是同一个东西。
其中,.mdb, *.accdb中逗号后面必须带有空格!!!!!!!!!!
DBQ=数据库文件名称。
如果本地不存在上述驱动,那么会报错 *[Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序时。
查看系统数据源: 搜索 “管理工具” -> 进入 ODBC数据源 ->系统DSN -> 添加
理应如图所示,如果弹出的页面中无法找到数据源,请使用 AccessDatabaseEngine试试。
四、总结
由于项目要求,导出的格式必须为access97版本的数据库格式,但是access 97版本的文件只有03年以前的office版本才能打开,其他任何版本的access均会提示“access无法打开应用程序较早版本”,所以导致java代码也无法正常连接access数据库。最后笔者忍痛下载了office 2000。如果对导出的数据库版本没有要求,应该不会存在该问题。