使用Java连接到PostgreSQL数据库

首先

由于最近接触各种程序连接到PostgreSQL的机会增多,所以我整理了一下步骤。
由于篇幅较长,本次将尝试连接Java和PostgreSQL。
此外,本文包含了在12/16(六)举办的PostgreSQL非官方会议上的演讲内容。
当天的资料可以在这里查看。

[2018/11/20更新]
我已经发布了一篇关于C#的文章,对当天公布的内容做了一些额外的补充。
如果您想了解有关C#连接方法的信息,请参阅那篇文章。

[2019/2/20修正及追加]
感謝@takuya-fujiwara提供的评论,我修改了JDBC驱动程序的加载部分。
非常感谢您的指正。
关于修正的详细信息,请参阅追加内容。

连接Java到PostgreSQL。

    • 環境情報

OS:Windows 10
PostgreSQL: 10.1
Java:1.8
JDBC:4.2

首先,假设PostgreSQL和Java的环境已经安装好。
要从Java连接到PostgreSQL,首先需要获取PostgreSQL的JDBC驱动程序。

    • PostgreSQL JDBC Driver

 

    https://jdbc.postgresql.org/download.html

在Eclipse中,右键单击要创建的项目并选择”构建路径” -> “配置构建路径”。
然后,在”库”选项卡中选择”添加外部JAR”,并添加从上述来源获取的PostgreSQL JDBC。

然后,我写下了以下代码以连接到PostgreSQL。
作为测试,我们将执行SELECT和INSERT语句的事务。

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

public class Sample_pos_conn {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rset = null;

        //接続文字列
        String url = "jdbc:postgresql://123.45.67.89:5432/postgres";
        String user = "postgres";
        String password = "password";

        try{
            //PostgreSQLへ接続
            conn = DriverManager.getConnection(url, user, password);

            //自動コミットOFF
            conn.setAutoCommit(false);

            //SELECT文の実行
            stmt = conn.createStatement();
            String sql = "SELECT 1";
            rset = stmt.executeQuery(sql);

            //SELECT結果の受け取り
            while(rset.next()){
                String col = rset.getString(1);
                System.out.println(col);
            }

            //INSERT文の実行
            sql = "INSERT INTO jdbc_test VALUES (1, 'AAA')";
            stmt.executeUpdate(sql);
            conn.commit();
        }
        catch (SQLException e){
            e.printStackTrace();
        }
        finally {
            try {
                if(rset != null)rset.close();
                if(stmt != null)stmt.close();
                if(conn != null)conn.close();
            }
            catch (SQLException e){
                e.printStackTrace();
            }

        }
    }
}

我会依次解释上面代码中的关键部分。

连接至PostgreSQL数据库

明确指定要连接的数据库。
这是连接到PostgreSQL的情况(字符串中包含了“postgres”之类的)。
因此,如果要连接其他数据库,字符串当然是不同的。
换句话说,只要重新解释连接相关字符串,对于相同的RDBMS,可以用JDBC做的事情和行为是类似的。

链接字符串

String url = "jdbc:postgresql://<接続先DBサーバのIP or ホスト名>:<DBのポート番号>/<DB名>";

以下是连接到PostgreSQL的信息。此次是一个示例,但根据环境不同,将提供上述信息。
请参考最初的示例代码以获取具体示例。

执行SQL文

在Java中执行SQL语句时,有两种方法,分别是”Statement”和”PreparedStatement”。
“Statement”是直接执行输入的字符串,非常简单。
“PreparedStatement”是预编译并优化过的,还可以后续更改参数,非常优秀。
通常情况下,如果使用相同的SQL语句,我们基本上会使用”PreparedStatement”。
不过这次我们将使用简单的”Statement”。

查询语句

Statement stmt = conn.createStatement();

String sql = "SELECT 1";
rset = stmt.executeQuery(sql);

//SELECT結果の受け取り
while(rset.next()){
    String col = rset.getString(1);
    System.out.println(col);
}

为了执行SQL语句,我们通过”createStatement”方法初始化”Statement”。尽管它们看起来相似,但通过传递给”createStatement”方法的参数可以改变SELECT结果的接收方式。在下面给出了简单的说明,但通常情况下,您无需指定参数,只需使用默认值即可。

第1引数説明ResultSet.TYPE_FORWARD_ONLYデフォルト値。
カーソルは順方向にのみ移動可能。
ResultSetのlast()、first()等は使用できない。ResultSet.TYPE_FORWARD_ONLYカーソルは順方向・逆方向に移動可能。
データ取得後に、他の接続によって変更されたデータを反映しない。ResultSet.TYPE_SCROLL_INSENSITIVEカーソルは順方向・逆方向に移動可能。
データ取得後に、他の接続によって変更されたデータを反映する。
読み取り一貫性が保証されなくなるため非推奨。
第1引数説明ResultSet.CONCUR_READ_ONLYデフォルト値。
ResultSetによる更新不可。ResultSet.CONCUR_UPDATABLEResultSetによる更新可能。
updateXXX()等が使用できる。

在 SELECT 语句中,使用 “ResultSet” 类来接收结果。
基本上,可以使用 next() 方法按顺序提取获取到的数据。
在最后一行数据之后再执行 next() 方法,结果将变为 null,因此可以使用 while 循环来获取全部数据。
当从 ResultSet 中提取数据时,需要指定列。
指定列的方法可以是列的索引(从第 0 列开始),或者是列的名称。

如果只想获取最后一条或第一条数据,可以使用last()和first()方法。但是需要注意的是,这两个方法需要在”createStatement”方法的第一个参数中传递ResultSet.TYPE_FORWARD_ONLY。

DML(插入、删除、更新)操作语句

//INSERT文の実行
sql = "INSERT INTO jdbc_test VALUES (1, 'AAA')";
stmt.executeUpdate(sql);
conn.commit();

DML与SELECT不同,不接收结果,所以不使用ResultSet。
因此,在使用「createStatement」方法时不需要指定参数。
但是,必须使用「executeUpdate()」方法来执行SQL语句。
另外,自动提交是关闭的情况下,需要使用commit()方法进行提交,后面会详细说明。

创建语句(CREATE …)

这次的示例中没有包含,但是可以使用与 DML 语句相同的方法执行。
对于 PostgreSQL 来说,DDL 语句不会自动提交,所以在自动提交关闭的情况下,需要像 DML 语句一样显式地提交。

//CREATE文の実行
sql = "CREATE TABLE hoge (col1 integer)";
stmt.executeUpdate(sql);
conn.commit();

提交,回滚

正如前面提到的,可以通过函数执行COMMIT和ROLLBACK操作。
因此,不再需要编写SQL语句了。

//COMMITの実行
conn.commit();
//ROLLBACKの実行
conn.rollback();

交易

自动提交

在使用JDBC时,默认情况下会启用自动提交功能。对于使用PostgreSQL的人来说,这没有问题,但对于其他关系数据库管理系统来说,则需要注意。请注意,由于PostgreSQL也默认启用自动提交功能。

自动提交的启用/禁用是通过setAutoCommit()方法来实现的。
当为true时为启用(默认),当为false时为禁用。

//自動コミットOFF
conn.setAutoCommit(false);

如果想在Java中进行事务处理,通常要禁用自动提交。由于后续的原因,很少需要输入SQL语句的BEGIN。

当自动提交被关闭时的事务处理

如果自动提交被关闭的情况下,JDBC会在SQL开始时自动输入BEGIN。因此,如果明确地写出BEGIN,则数据库中会执行两次BEGIN。由于COMMIT和ROLLBACK也是通过函数提供的,因此在使用Java进行事务处理时,很少会有机会输入与事务相关的SQL。

//BEGIN文の実行
stmt = conn.createStatement();
String sql = "BEGIN";
rset = stmt.executeQuery(sql);
LOG:  execute <unnamed>: BEGIN
LOG:  execute <unnamed>: BEGIN
WARNING:  there is already a transaction in progress

我已将PostgreSQL参数log_statement设置为’all’。

附注:有关加载JDBC驱动程序的补充信息。

如果是JDBC 4.0之前的版本,需要通过Class.forName来明确加载JDBC驱动程序,如下所示:

try{
    Class.forName("org.postgresql.Driver");
    
}
catch (ClassNotFoundException e) {
    
}

对于不同种类的JDBC驱动程序,上述字符串的描述是不同的。
如果要声明它,就需要进行ClassNotFoundException的异常处理。

然而,自从JDBC 4.0(=Java 1.6)以后,它会自动加载,因此不再需要上述的手动加载。

在以前版本的JDBC中,要获取一个连接,您首先需要通过调用方法Class.forName来初始化JDBC驱动程序。这个方法需要一个java.sql.Driver类型的对象。每个JDBC驱动程序包含一个或多个实现java.sql.Driver接口的类。Java DB的驱动程序是org.apache.derby.jdbc.EmbeddedDriver和org.apache.derby.jdbc.ClientDriver,而MySQL Connector/J的驱动程序是com.mysql.jdbc.Driver。请查阅您的DBMS驱动程序的文档以获取实现java.sql.Driver接口的类的名称。

任何在您的类路径中找到的JDBC 4.0驱动程序都会被自动加载。(但是,在JDBC 4.0之前您必须手动加载任何驱动程序,可以使用方法Class.forName)。


在早期的JDBC版本中,要获取连接,首先需要调用Class.forName方法来初始化JDBC驱动程序。这个方法需要一个java.sql.Driver类型的对象。每个JDBC驱动程序都包含一个或多个实现java.sql.Driver接口的类。对于Java DB,驱动程序是org.apache.derby.jdbc.EmbeddedDriver和org.apache.derby.jdbc.ClientDriver;对于MySQL Connector / J,驱动程序是com.mysql.jdbc.Driver。要获取实现java.sql.Driver接口的类的名称,请参考DBMS驱动程序的手册。

在类路径中的JDBC 4.0驱动程序将自动加载。(然而,您仍需要使用Class.forName方法手动加载JDBC 4.0之前的驱动程序。)

    • JDBC Basics Tutorial ~Establishing a Connection~より引用

 

    • https://docs.oracle.com/javase/tutorial/jdbc/basics/connecting.html#drivermanager

 

    • 参考:The PostgreSQL JDBC Interface ~Chapter 3. Initializing the Driver~

 

    https://jdbc.postgresql.org/documentation/head/load.html
广告
将在 10 秒后关闭
bannerAds