Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql Postgres 9.6.17和JDBC 42.2.1如何将连接模式切换到';扩展的';_Postgresql_Jdbc - Fatal编程技术网

Postgresql Postgres 9.6.17和JDBC 42.2.1如何将连接模式切换到';扩展的';

Postgresql Postgres 9.6.17和JDBC 42.2.1如何将连接模式切换到';扩展的';,postgresql,jdbc,Postgresql,Jdbc,我有一个Postgres9.6.17DBMS和一个简单的Java独立程序(没有Spring),它连接到DBMS并发出查询。根据Postgres文档,查询可以在“简单模式”或“扩展模式”(解析和查询重写一次完成)下执行,但绑定会重复进行 我有一个简单的表customer(cust\u id integer,first\u name varchar(100),last\u name varchar(100))。我正在执行的代码如下所示: Properties props = new Properti

我有一个Postgres9.6.17DBMS和一个简单的Java独立程序(没有Spring),它连接到DBMS并发出查询。根据Postgres文档,查询可以在“简单模式”或“扩展模式”(解析和查询重写一次完成)下执行,但绑定会重复进行

我有一个简单的表
customer(cust\u id integer,first\u name varchar(100),last\u name varchar(100))
。我正在执行的代码如下所示:

Properties props = new Properties();
....//typical properties such as user, password, database etc
props.setProperty("preferQueryMode", "extendedForPrepared");
Connection con = DriverManager.getConnection(url, props);
PreparedStatement st = con.prepareStatement("select * from ecommerce.customer where cust_id = ?");
st.setInt(1, 22);
ResultSet rs = st.executeQuery();    
我希望这将在JDBC客户机和DBMS后端之间产生一个“扩展查询模式”协议。但它始终产生一种“简单查询模式”交互。我通过为postgres驱动程序启用JDBC日志来验证这一点。我还研究了JDBC驱动程序中
Query
接口的实现,我能找到的只有以下3种实现:

Properties props = new Properties();
....//typical properties such as user, password, database etc
props.setProperty("preferQueryMode", "extendedForPrepared");
Connection con = DriverManager.getConnection(url, props);
PreparedStatement st = con.prepareStatement("select * from ecommerce.customer where cust_id = ?");
st.setInt(1, 22);
ResultSet rs = st.executeQuery();    
  • BatchedQuery
  • CompositeQuery
  • SimpleQuery
  • 尽管名称为
    CompositeQuery
    ,它所做的只是将涉及多个语句的查询拆分为
    SimpleQuery
    对象列表


    所以我的问题是,我该怎么做才能让我的连接使用扩展模式的协议

    默认情况下,Postgres JDBC驱动程序仅在准备好的语句使用5次后才开始使用服务器端语句。从:

    prepareThreshold=int

    在切换到使用服务器端准备语句之前,确定所需的PreparedStatement执行次数。默认值为5,这意味着在同一PreparedStatement对象的第五次执行时开始使用服务器端准备的语句。有关服务器端准备语句的更多信息,请参阅“服务器准备语句”一节

    但这种属性是可以改变的

    这是我测试的程序:

    Properties props = new Properties();
    props.setProperty("user", "test");
    props.setProperty("password", "test");
    props.setProperty("loggerLevel", "TRACE");
    props.setProperty("prepareThreshold", "1");
    try (Connection con = DriverManager.getConnection("jdbc:postgresql:test", props);
         PreparedStatement stat = con.prepareStatement("select * from app_user where username = ?"))
    {
        for (String username : List.of("user1", "user2", "user3"))
        {
            stat.setString(1, username);
            try (ResultSet rs = stat.executeQuery())
            {
                if (rs.next())
                    System.out.println("User " + username + " has ID: " + rs.getString(1));
            }
        }
    }
    

    prepareThreshold
    设置为
    1
    时,日志显示:

    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@33065d67, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendParse
    FINEST:  FE=> Parse(stmt=S_1,query="select * from app_user where username = $1",oids={1043})
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user1'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal
    FINEST:  FE=> Describe(portal=null)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    ...
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@35dab4eb, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user2'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    ...
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@2d901eb0, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user3'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    
    Feb 18, 2020 2:06:19 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@33065d67, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:19 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user1'")
    ...
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@28261e8e, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user2'")
    ...
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@d737b89, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user3'")
    
    其中有3个单独的语句解析和绑定。然而,在5次查询之后,它们应该开始被重用


    关于“简单”与“扩展”的查询模式,看起来日志总是打印出“简单执行”,但区别在于真正的简单模式参数不会绑定在准备语句中,而是整个查询将作为文本发送。在此示例中,如果
    preferQueryMode
    属性设置为
    simple
    ,则日志显示:

    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@33065d67, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendParse
    FINEST:  FE=> Parse(stmt=S_1,query="select * from app_user where username = $1",oids={1043})
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user1'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendDescribePortal
    FINEST:  FE=> Describe(portal=null)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    ...
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@35dab4eb, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user2'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    ...
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@2d901eb0, maxRows=0, fetchSize=0, flags=16
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendBind
    FINEST:  FE=> Bind(stmt=S_1,portal=null,$1=<'user3'>)
    Feb 18, 2020 1:56:59 PM org.postgresql.core.v3.QueryExecutorImpl sendExecute
    FINEST:  FE=> Execute(portal=null,limit=0)
    
    Feb 18, 2020 2:06:19 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@33065d67, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:19 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user1'")
    ...
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@28261e8e, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user2'")
    ...
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl execute
    FINEST:   simple execute, handler=org.postgresql.jdbc.PgStatement$StatementResultHandler@d737b89, maxRows=0, fetchSize=0, flags=1,041
    Feb 18, 2020 2:06:20 PM org.postgresql.core.v3.QueryExecutorImpl sendSimpleQuery
    FINEST:  FE=> SimpleQuery(query="select * from app_user where username = 'user3'")
    
    请注意这与默认值之间的差异-没有参数,“user1”、“user2”和“user3”值与每个查询一起内联发送


    我认为您真正需要的是立即重用服务器端语句并重新绑定参数。在这种情况下,将
    prepareThreshold
    设置为
    1
    将完成此工作