即使关闭连接后,数据仍然存在于h2数据库表中

Posted

技术标签:

【中文标题】即使关闭连接后,数据仍然存在于h2数据库表中【英文标题】:Even after closing the connection, data still exists in h2 database tables 【发布时间】:2017-11-27 10:09:54 【问题描述】:

当我浏览许多 H2 数据库教程时,默认情况下,关闭与数据库的最后一个连接会关闭数据库。对于内存数据库,这意味着内容会丢失。

我已经创建了 Employee1 表,插入了记录并关闭了连接。但是,如果我在某个时间后重新连接同一个数据库,我仍然可以检索 Employee1 数据。为什么数据仍然存在?

package connection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Connector 

static Connection conn = null;
static Statement stmt = null;

public static void main(String[] args) 

    System.out.println("Welcome!");
    Connector connector = new Connector();
    connector.createConnection();
    connector.createTable("Employee2");
    connector.insertRecord("Employee2");
    connector.readRecord("Employee2");
    connector.readRecord("Employee1"); //Employee1 Table which is created in previous execution but still it reads the data
    connector.closeConnection();


public void createConnection() 
    try 
        System.out.println("Creating connection");
        // STEP 1: Register JDBC driver
        Class.forName("org.h2.Driver");
        // STEP 2: Open a connection
        System.out.println("Connecting to database...");
        conn = DriverManager.getConnection("jdbc:h2:mem/db1", "sa", "");
     catch (SQLException se) 
        // Handle errors for JDBC
        se.printStackTrace();
     catch (Exception e) 
        // Handle errors for Class.forName
        e.printStackTrace();
    



public void createTable(String tableName) 
    try 
        // STEP 3: Execute a query
        System.out.println("Creating table in given database with the name of ..." + tableName);
        stmt = conn.createStatement();
        String sql = "CREATE TABLE " + tableName + "(id INTEGER not NULL, " + " first VARCHAR(255), "
                + " last VARCHAR(255), " + " age INTEGER, " + " PRIMARY KEY ( id ))";
        stmt.executeUpdate(sql);
        System.out.println("Created table in given database...");

     catch (SQLException se) 
        // Handle errors for JDBC
        se.printStackTrace();
     catch (Exception e) 
        // Handle errors for Class.forName
        e.printStackTrace();
    


public void insertRecord(String tableName) 
    try 
        // STEP 3: Execute a query
        stmt = conn.createStatement();
        String sql = "INSERT INTO " + tableName + " VALUES (500, 'Zara', 'Ali', 18)";

        stmt.executeUpdate(sql);
        sql = "INSERT INTO " + tableName + " VALUES (501, 'Mahnaz', 'Fatma', 25)";

        stmt.executeUpdate(sql);
        sql = "INSERT INTO " + tableName + " VALUES (502, 'Zaid', 'Khan', 30)";

        stmt.executeUpdate(sql);
        sql = "INSERT INTO " + tableName + " VALUES(503, 'Sumit', 'Mittal', 28)";

        stmt.executeUpdate(sql);
        System.out.println("Inserted records into the table...");
     catch (SQLException se) 
        // Handle errors for JDBC
        se.printStackTrace();
     catch (Exception e) 
        // Handle errors for Class.forName
        e.printStackTrace();
    


public void readRecord(String tableName) 
    try 
        System.out.println("Reading data from "+tableName);
        stmt = conn.createStatement();
        String sql = "SELECT id, first, last, age FROM " + tableName;
        ResultSet rs = stmt.executeQuery(sql);

        // STEP 4: Extract data from result set
        while (rs.next()) 
            // Retrieve by column name
            int id = rs.getInt("id");
            int age = rs.getInt("age");
            String first = rs.getString("first");
            String last = rs.getString("last");

            // Display values
            System.out.print("ID: " + id);
            System.out.print(", Age: " + age);
            System.out.print(", First: " + first);
            System.out.println(", Last: " + last);
        
        // STEP 5: Clean-up environment
        rs.close();
     catch (SQLException se) 
        // Handle errors for JDBC
        se.printStackTrace();
     catch (Exception e) 
        // Handle errors for Class.forName
        e.printStackTrace();
     finally 
        // finally block used to close resources
        try 
            if (stmt != null)
                stmt.close();
         catch (SQLException se2) 
         // nothing we can do
     // end try


public void closeConnection() 
    try 
        if (conn != null) 
            conn.close();
            System.out.println("Connection Closed..");
        
     catch (SQLException se) 
        se.printStackTrace();
     // end finally try


上述程序的输出:

Welcome!
Creating connection
Connecting to database...
Creating table in given database with the name of ...Employee2
Created table in given database...
Inserted records into the table...
Reading data from Employee2
ID: 500, Age: 18, First: Zara, Last: Ali
ID: 501, Age: 25, First: Mahnaz, Last: Fatma
ID: 502, Age: 30, First: Zaid, Last: Khan
ID: 503, Age: 28, First: Sumit, Last: Mittal
Reading data from Employee1
ID: 400, Age: 18, First: freeze, Last: Ali
ID: 401, Age: 25, First: dora, Last: Fatma
ID: 402, Age: 30, First: xer, Last: Khan
ID: 403, Age: 28, First: kilo, Last: Mittal
Connection Closed..

【问题讨论】:

查看是否设置了其中之一:***.com/questions/27057900/… 实际上我的问题是即使关闭连接后,内容并没有丢失它仍然存在。即使我尝试过 conn = DriverManager.getConnection("jdbc:h2:mem/db1;DB_CLOSE_DELAY=0", "sa", "");但它不起作用。 我了解您的问题。我没有解释。 【参考方案1】:

如你所见here

jdbc:h2:mem/db1

使用mem/db1 的相对路径连接到本地数据库文件,因此数据仍然存在,因为它以文件的形式保存。

对于内存数据库,连接字符串应该是:

jdbc:h2:mem:db1

注意/: 之间的区别

【讨论】:

非常感谢。我经常混淆和编辑导致错误的代码。

以上是关于即使关闭连接后,数据仍然存在于h2数据库表中的主要内容,如果未能解决你的问题,请参考以下文章

为啥hibernate关闭连接后h2的数据库文件仍然会被锁定一段时间?

即使光标关闭,Psycopg 请求也会挂起

连接关闭后 H2 模式消失

即使在删除部分数据并重新加载 UICollectionView 后,部分标题仍然存在

H2 数据库损坏

最新的 H2 (1.4.200) 数据库是不是仍然存在安全漏洞