【问题标题】:How to connect UCanAccess to an Access database encrypted with a database password?如何将 UCanAccess 连接到使用数据库密码加密的 Access 数据库?
【发布时间】:2015-10-04 11:11:37
【问题描述】:

我已经开发了一个带有 Access 数据库的 Java 应用程序(字典)来存储字典中的单词,我正准备分发它。 我想用密码加密我的数据库,以防止人们访问我的话。 当我设置密码时,Java 代码会显示此异常

net.ucanaccess.jdbc.UcanaccessSQLException: Decoding not supported.  Please choose a CodecProvider which supports reading the current database encoding.
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:247)

这是我在使用密码加密数据库之前的连接代码......

String s1="jdbc:ucanaccess://";
String user="";
String pass="";
String s4="words.accdb";

public void connectToDB(){
        //database connection
        try {
            conn = DriverManager.getConnection(s1+s4,user,pass);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //end of database connection
    }

这是用密码加密后的代码,例如12345...

String s1="jdbc:ucanaccess://";
String user="";
String pass="12345";
String s4="words.accdb";

public void connectToDB(){
        //database connection
        try {
            conn = DriverManager.getConnection(s1+s4,user,pass);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //end of database connection
    }

【问题讨论】:

    标签: java ms-access jdbc ms-access-2010 ucanaccess


    【解决方案1】:

    您与 jdbc 驱动程序 (s1) 的链接似乎无效。

    看看我从this Sitegoogle 时发现的模式

     String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\IJTS EXAMPLES\\Database11.accdb;PWD=1234";
    

    这是来自a Site的示例

    private void initializeConnection()
    {
    
    Connection con ;
    try
    {
    
    // Load Class Definition for Database Driver
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    
    // set this to a MS Access DB you have on your machine
    String curDir = System.getProperty("user.dir");
    String filename = curDir +"/test.mdb";
    
    String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\\test.mdb;READONLY=true";
    
    // Get connection from the DriverManager
    con = DriverManager.getConnection( database,"Admin","test" );
    
    
    } catch (Exception e) {
    
    System.out.println("Database Connection Problem");
    
    }
    
    }
    

    请注意,您必须通过用您的凭据替换部分来更改字符串

    【讨论】:

    • 不,我的链接是有效的,没有密码也可以正常工作 我如何用 ucanaccess 编写数据库连接语句?因为从 jre8 中删除了 jdbc:odbc 桥
    • 如果被删除了,为什么还在使用MSAccess?您能告诉我们您不能使用纯 java 解决方案的原因吗?
    【解决方案2】:

    我假设您已经在 MSAccess 中设置了数据库密码,并对其进行了加密。

    要连接到这种类型的数据库,您需要正确的连接字符串并通过 odbc 连接。

    这是获取 MSAccess 连接字符串的链接 https://www.connectionstrings.com/access/

    关于这个主题的好帖子可以在这里找到How can I add a password to this JDBC:ODBC connection string that is trying to connect to an MS Access database

    我建议您使用不同类型的嵌入式数据库来为 java 完成所有这些工作。使用h2,这是更好的纯java解决方案

    http://www.h2database.com/html/main.html

    代码示例

    public class HelloWorld {
    
        /**
         * Called when ran from command line.
         *
         * @param args ignored
         */
        public static void main(String... args) throws Exception {
            // delete the database named 'test' in the user home directory
            DeleteDbFiles.execute("~", "test", true);
    
            Class.forName("org.h2.Driver");
            Connection conn = DriverManager.getConnection("jdbc:h2:~/test");
            Statement stat = conn.createStatement();    
            stat.execute("create table test(id int primary key, name varchar(255))");
            stat.execute("insert into test values(1, 'Hello')");
            ResultSet rs;
            rs = stat.executeQuery("select * from test");
            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
            stat.close();
            conn.close();
        }    
    }
    

    数据库文件存储在哪里?

    当使用像 jdbc:h2:~/test 这样的数据库 URL 时,数据库存储在用户目录中。对于 Windows,这通常是 C:\Documents and Settings\ 或 C:\Users\。

    如果未设置基本目录(如 jdbc:h2:test),则数据库文件存储在启动应用程序的目录(当前工作目录)中。

    从开始菜单使用 H2 控制台应用程序时,这是 /bin。可以在数据库 URL 中设置基本目录。可以使用固定或相对路径。

    当使用 URL jdbc:h2:file:data/sample 时,数据库存储在目录 data 中(相对于当前工作目录)。如果该目录尚不存在,则会自动创建该目录。

    也可以使用完全限定的目录名称(对于 Windows,使用驱动器名称)。示例:jdbc:h2:file:C:/data/test

    在 URL 中传递用户名和/或密码

    而不是将用户名作为单独的参数传递,如 Connection conn = DriverManager. getConnection("jdbc:h2:~/test", "sa", "123");

    用户名(和/或密码)可以在 URL 本身中提供:Connection conn = DriverManager. getConnection("jdbc:h2:~/test;USER=sa;PASSWORD=123");

    【讨论】:

    • 为什么还需要 MSAccess?使用 H2
    • 我不知道用它:)
    • 我可以帮助你使用它...给我一点时间为你编码
    【解决方案3】:

    UCanaccess 通过依赖注入模式支持加密。

    -您必须将jackcess-encrypt 和所有相关依赖项添加到您的项目中

    -您必须按照 ucanaccess 网站的建议编写一个实现 net.ucanaccess.jdbc.JackcessOpenerInterface 的类

    - 你必须在 jdbc url 中传递上述类的名称: 如果你将实现类命名为com.pippo.Bingo 那么你必须以这种方式构建jdbc url:

    DriverManager.getConnection("jdbc:ucanaccess://c:/db/your_db_name.mdb;jackcessOpener=com.pippo.Bingo", "sa", pwd);
    

    【讨论】:

    • 谢谢亲爱的,我知道你的回答是正确的,但是我应该在实现 JackcessOpenerInterface 接口的类中写什么,或者我什么时候应该调用位于 JackcessOpenerInterface 接口内的 open 方法,请解释更多..... .. 因为太多人有同样的问题
    • 我想帮助你。您只需复制 ucanaccess 网站中显示的实现 JackcessOpenerInterface 的类,更改其名称,在 jdbc url 中传递选择的(完整)名称,例如jdbc:ucanaccess://c:/db/your_db_name.mdb;jackcessOpener=com.plete.Name; UCanAccess 将调用 open 方法。
    • 另请参阅我在 ucanaccess 论坛中的回答(当 sourceforge 新可用时)
    • 现在它显示了这个异常 Exception in thread "main" java.lang.NoClassDefFoundError: org/bouncycastle/crypto/InvalidCipherTextException at com.healthmarketscience.jackcess.CryptCodecProvider.createHandler(CryptCodecProvider.java:114) 来自 open 方法内的返回 return dbd.open();
    • 谢谢我已经建立了解决方案,我们必须添加另一个 jar 文件http://www.bouncycastle.org/latest_releases.html 非常感谢........
    【解决方案4】:

    如何将 UCanAccess 连接到使用数据库密码加密的 Access 数据库的步骤

    第 1 步:
    将这两个包添加到您的项目中(jackcess-encrypt.jar、bcprov-ext-jdk15on-152)

    您可以从以下链接下载这两个包:

    Jackcess Encrypt
    Bouncy Castle

    第 2 步:
    您必须将此类添加到您的项目文件夹中

    import java.io.File;
    import java.io.IOException;
    import net.ucanaccess.jdbc.JackcessOpenerInterface;
    import com.healthmarketscience.jackcess.CryptCodecProvider;
    import com.healthmarketscience.jackcess.Database;
    import com.healthmarketscience.jackcess.DatabaseBuilder;
    
    public class CryptCodecOpener implements JackcessOpenerInterface {
             @Override
        public Database open(File fl,String pwd) throws IOException {
           DatabaseBuilder dbd =new DatabaseBuilder(fl);
           dbd.setAutoSync(false);
           dbd.setCodecProvider(new CryptCodecProvider(pwd));
           dbd.setReadOnly(false);
           return dbd.open();
        }
      //Notice that the parameter setting autosync =true is recommended with UCanAccess for performance reasons. 
      //UCanAccess flushes the updates to disk at transaction end. 
      //For more details about autosync parameter (and related tradeoff), see the Jackcess documentation. 
    }
    

    喜欢这个

    第 3 步:
    使用以下连接代码

    public void connectToDB(){
                try {
                    conn = DriverManager.getConnection("jdbc:ucanaccess://words.accdb;jackcessOpener=CryptCodecOpener", "user", "pass");
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
        }
    


    你也可以看这个视频...https://www.youtube.com/watch?v=TT6MgBBkRSE

    【讨论】:

      猜你喜欢
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      相关资源
      最近更新 更多