PostgreSQL™ 扩展到 JDBC API 极品教程

来源:互联网 发布:vs2015可以写c语言吗 编辑:程序博客网 时间:2024/06/05 19:53

几何数据类型

PostgreSQL™有一组数据类型可以存储到表的几何特性。这些包括单点、线和多边形。我们支持这些类型在Java org.postgresql。几何包。请参考提供的细节类的Javadoc和特性在第十二章提到,进一步阅读。

例9.1。使用JDBC数据类型

进口java.sql。*;

进口org.postgresql.geometric。PGpoint;进口org.postgresql.geometric.PGcircle;

public class GeometricTest {

public static void main(String args[]) throws Exception {    Class.forName("org.postgresql.Driver");    String url = "jdbc:postgresql://localhost:5432/test";    Connection conn = DriverManager.getConnection(url,"test","");    Statement stmt = conn.createStatement();    stmt.execute("CREATE TEMP TABLE geomtest(mycirc circle)");    stmt.close();    insertCircle(conn);    retrieveCircle(conn);    conn.close();}private static void insertCircle(Connection conn) throws SQLException {    PGpoint center = new PGpoint(1, 2.5);    double radius = 4;    PGcircle circle = new PGcircle(center, radius);    PreparedStatement ps = conn.prepareStatement("INSERT INTO geomtest(mycirc) VALUES (?)");    ps.setObject(1, circle);    ps.executeUpdate();    ps.close();}private static void retrieveCircle(Connection conn) throws SQLException {    Statement stmt = conn.createStatement();    ResultSet rs = stmt.executeQuery("SELECT mycirc, area(mycirc) FROM geomtest");    rs.next();    PGcircle circle = (PGcircle)rs.getObject(1);    double area = rs.getDouble(2);    PGpoint center = circle.center;    double radius = circle.radius;    System.out.println("Center (X, Y) = (" + center.x + ", " + center.y + ")");    System.out.println("Radius = " + radius);    System.out.println("Area = " + area);}

}

///////////////////////////////////////////////////////////

听/通知

听并通知提供一个简单形式的信号或进程间通信机制的集合过程访问相同的PostgreSQL™数据库。有关通知参考主服务器文档的更多信息。本节只处理JDBC特定方面的通知。

标准听、通知和UNLISTEN命令通过标准的发布声明接口。检索和处理检索通知连接必须将PostgreSQL™PGConnection特定的扩展接口。从那里getNotifications()方法可以用于检索任何杰出的通知。

请注意

JDBC驱动程序的主要限制是它不能接收异步通知,必须调查后端来检查是否有通知了。

例9.2。接收通知

import java.sql.*;public class NotificationTest{    public static void main(String args[]) throws Exception    {        Class.forName("org.postgresql.Driver");        String url = "jdbc:postgresql://localhost:5432/test";        // Create two distinct connections, one for the notifier        // and another for the listener to show the communication        // works across connections although this example would        // work fine with just one connection.        Connection lConn = DriverManager.getConnection(url,"test","");        Connection nConn = DriverManager.getConnection(url,"test","");        // Create two threads, one to issue notifications and        // the other to receive them.        Listener listener = new Listener(lConn);        Notifier notifier = new Notifier(nConn);        listener.start();        notifier.start();    }}
class Listener extends Thread{    private Connection conn;    private org.postgresql.PGConnection pgconn;    Listener(Connection conn) throws SQLException    {        this.conn = conn;        this.pgconn = conn.unwrap(org.postgresql.PGConnection.class);        Statement stmt = conn.createStatement();        stmt.execute("LISTEN mymessage");        stmt.close();    }    public void run()    {        while (true)        {            try            {                // issue a dummy query to contact the backend                // and receive any pending notifications.                Statement stmt = conn.createStatement();                ResultSet rs = stmt.executeQuery("SELECT 1");                rs.close();                stmt.close();                org.postgresql.PGNotification notifications[] = pgconn.getNotifications();                                if (notifications != null)                {                    for (int i=0; i<notifications.length; i++)                        System.out.println("Got notification: " + notifications[i].getName());                }                // wait a while before checking again for new                // notifications                                Thread.sleep(500);            }            catch (SQLException sqle)            {                sqle.printStackTrace();            }            catch (InterruptedException ie)            {                ie.printStackTrace();            }        }    }}
class Notifier extends Thread{    private Connection conn;    public Notifier(Connection conn)    {        this.conn = conn;    }    public void run()    {        while (true)        {            try            {                Statement stmt = conn.createStatement();                stmt.execute("NOTIFY mymessage");                stmt.close();                Thread.sleep(2000);            }            catch (SQLException sqle)            {                sqle.printStackTrace();            }            catch (InterruptedException ie)            {                ie.printStackTrace();            }        }    }}
/////////////////////////////////////////////////

服务器准备好的语句

PostgreSQL™服务器允许客户机编译sql语句将被重用,避免解析的开销和规划每个执行的语句。这个功能可以在SQL级通过准备和执行从server version 7.3开始,并在协议级别从server version 7.4开始,但作为Java开发人员,我们真的只是想使用标准的PreparedStatement接口。

请注意

以前版本的驱动程序使用的准备和执行来实现server-prepared语句。这是支持所有服务器版本从7.3开始,但生产application-visible查询结果的变化,如丢失的结果集元数据和行更新计数。当前驱动程序使用V3协议一级等价物,避免这些查询结果的变化,但V3协议才可以开始与服务器7.4版。启用server-prepared语句将没有影响当连接到一个7.3服务器或者显式地使用V2协议连接到7.4服务器。

有很多方法使服务器端准备好的语句根据应用程序的需要。一般的方法是设置一个阈值PreparedStatement。内部计数器跟踪语句被执行的次数,当达到阈值,它将开始使用服务器端准备好的语句。

请注意

服务器端准备好的语句由服务器只计划一次。这避免了重新规划查询每次的成本,但也意味着规划者不能利用特定的参数值用于特定查询的执行。你应该谨慎使全球服务器端预处理语句的使用。

Example 9.3. Using server side prepared statements

import java.sql.*;

public class ServerSidePreparedStatement{

public static void main(String args[]) throws Exception{    Class.forName("org.postgresql.Driver");    String url = "jdbc:postgresql://localhost:5432/test";    Connection conn = DriverManager.getConnection(url,"test","");    PreparedStatement pstmt = conn.prepareStatement("SELECT ?");    // cast to the pg extension interface    org.postgresql.PGStatement pgstmt = pstmt.unwrap(org.postgresql.PGStatement.class);    // on the third execution start using server side statements    pgstmt.setPrepareThreshold(3);    for (int i=1; i<=5; i++)    {        pstmt.setInt(1,i);        boolean usingServerPrepare = pgstmt.isUseServerPrepare();        ResultSet rs = pstmt.executeQuery();        rs.next();        System.out.println("Execution: "+i+", Used server side: " + usingServerPrepare + ", Result: "+rs.getInt(1));        rs.close();    }    pstmt.close();    conn.close();}

}

Which produces the expected result of using server side prepared statements uponthe third execution.

Execution: 1, Used server side: false, Result: 1
Execution: 2, Used server side: false, Result: 2
Execution: 3, Used server side: true, Result: 3
Execution: 4, Used server side: true, Result: 4
Execution: 5, Used server side: true, Result: 5

The example shown above requires the programmer to use PostgreSQL™ specific codein a supposedly portable API which is not ideal. Also it sets the threshold onlyfor that particular statement which is some extra typing if we wanted to use thatthreshold for every statement. Let's take a look at the other ways to set thethreshold to enable server side prepared statements. There is already a hierarchyin place above aPreparedStatement, the Connection it was created from, andabove that the source of the connection be it aDatasource or a URL. The serverside prepared statement threshold can be set at any of these levels such thatthe value will be the default for all of it's children.

// pg extension interfaces
org.postgresql.PGConnection pgconn;
org.postgresql.PGStatement pgstmt;

// set a prepared statement threshold for connections created from this url
String url = "jdbc:postgresql://localhost:5432/test?prepareThreshold=3";

// see that the connection has picked up the correct threshold from the url
Connection conn = DriverManager.getConnection(url,"test","");
pgconn = conn.unwrap(org.postgresql.PGConnection.class);
System.out.println(pgconn.getPrepareThreshold()); // Should be 3

// see that the statement has picked up the correct threshold from the connection
PreparedStatement pstmt = conn.prepareStatement("SELECT ?");
pgstmt = pstmt.unwrap(org.postgresql.PGStatement.class);
System.out.println(pgstmt.getPrepareThreshold()); // Should be 3

// change the connection's threshold and ensure that new statements pick it up
pgconn.setPrepareThreshold(5);
PreparedStatement pstmt = conn.prepareStatement("SELECT ?");
pgstmt = pstmt.unwrap(org.postgresql.PGStatement.class);
System.out.println(pgstmt.getPrepareThreshold()); // Should be 5


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 满月宝宝脾气急怎么办 多颗牙齿缺失怎么办 孩子没有学习动力怎么办 裤子穿着往上跑怎么办 伤囗发炎了怎么办 玩派派背包食物不足怎么办 80岁老人植物人怎么办 steam账户创不起怎么办 小孩读书没有居住证怎么办 小孩上学没有准生证怎么办 小学在外地初中怎么办 小孩上学没准生证怎么办 没结婚出生证明怎么办 异地上高中高考怎么办 高中去外地上学怎么办 农村在城里上学怎么办? 父母没钱不工作怎么办 qq被家长偷看怎么办 孩子考差了怎么办 父母翻看qq记录怎么办 孩子qq屏蔽父母怎么办 杜鹃花老叶脱落怎么办 父母对孩子不好怎么办 家长看孩子手机怎么办 六年级打四年级学生怎么办 儿童被家长打怎么办 老师打孩子耳光怎么办 孩子动手打母亲怎么办 小孩被老师体罚怎么办 儿子跟父母对打怎么办 两个孩子争东西怎么办 大人吵架小孩该怎么办 小孩老爱顶嘴怎么办 孩子老爱顶嘴怎么办 孩子不愿分房睡怎么办 孩子不愿意去补课怎么办 高中孩子不愿意补课怎么办 孩子协调性不好怎么办 孩子暑假不愿意补课怎么办 话唠的孩子怎么办 孩孑不做作业怎么办