使用 VGet 类为可路由查询定义查询
如果不需要联接表或使用 group by 子句,您可以使用 VGet 类从单个节点直接访问表数据。与 VerticaRoutableExecutor 一样,VGet 直接查询包含查询所需的数据的 Vertica 节点,从而避免产生与正常的 Vertica 执行关联的分布式规划和执行成本。但是,VGet 不使用 SQL。相反,您可以定义谓词和值以对单个表执行键/值类型查找。VGet 非常适用于对单个表执行键/值类型查找。
可以通过对连接对象调用 prepareGet 方法来创建 VGet。
prepareGet( schema‑name, { table‑name | projection‑name } )
例如:
VerticaRoutableConnection conn;
try {
conn = (VerticaRoutableConnection)
jdbcSettings.getConnection();
System.out.println("Connected.");
VGet get = conn.prepareGet("public", "users");
...
}...
VGet 操作跨越多个 JDBC 连接(和多个 Vertica 会话),并且不遵循父连接的事务语义。如果需要在多个执行之间保持一致性,您可以使用父 VerticaRoutableConnection 的一致读取 API 来保证所有操作在同一时期进行。
VGet 是线程安全的,但会同步所有方法,因此共享 VGet 实例的线程永远不会并行运行。为了提高并行度,每个线程应具有各自的 VGet 实例。对同一个表执行操作的不同 VGet 实例共享池连接和元数据,以便实现较高的并行度。
VGet 方法
VGet 包含以下方法:
默认情况下,VGet 提取可满足多个谓词的逻辑 AND 的所有行的所有列,这些谓词通过 addPredicate 方法传递。您可以使用以下方法进一步自定义 get 操作:addOutputColumn、addOutputExpression、addPredicateExpression、addSortColumn 和 setLimit。
addPredicate
addPredicate(string, object)
向查询添加谓词列和常量值。必须为用作表的分段依据的每个列包含一个谓词。谓词充当查询 WHERE 子句。多个 addPredicate 方法调用由 AND 修饰符联接。每次调用并执行后,VGet 都会保留此值。要移除它,请使用 clearPredicates。
不能使用以下数据类型作为列值。同样,如果表在具有以下数据类型的任何列上分段,则不能使用可路由查询 API 查询此表:
addPredicateExpression
addPredicateExpression(string)
接受对表列执行操作的任意 SQL 表达式作为查询的输入。谓词表达式和谓词由 AND 修饰符联接。可以在谓词表达式中使用已分段的列,但您必须同时使用 addPredicate 将这些谓词表达式指定为常规谓词。每次调用并执行后,VGet 都会保留此值。要移除它,请使用 clearPredicates。
驱动程序将表达式发送至服务器之前不会验证表达式的语法。如果表达式不正确,则查询会失败。
addOutputColumn
addOutputColumn(string)
添加要包含到输出的列。默认情况下,查询作为 SELECT *
运行,并且您不需要定义任何用于返回数据的输出列。如果要添加输出列,则您必须添加要返回的所有列。每次调用并执行后,VGet 都会保留此值。要移除它,请使用 clearOutputs。
addOutputExpression
addOutputExpression(string)
接受对表列执行操作的任意 SQL 表达式作为输出。每次调用并执行后,VGet 都会保留此值。要移除它,请使用 ClearOutputs。
存在以下限制:
-
驱动程序将表达式发送至服务器之前不会验证表达式的语法。如果表达式不正确,则查询会失败。
-
addOutputExpression 在查询 Flex 表时不受支持。如果尝试对 Flex 表查询使用 addOutputExpression,则会引发 SQLFeatureNotSupportedException。
addSortColumn
addSortColumn(string, SortOrder)
向输出列添加排序顺序。输出列既可以是默认查询 (SELECT *) 所返回的一个列,也可以是 addSortColumn 或 addOutputExpress 中定义的列之一。可以定义多个排序列。
setLimit
setLimit(int)
对返回的结果数设置限制。值为 0 的限制表示无限制。
clearPredicates
clearPredicates()
移除由 addPredicate 和 addPredicateExpression 添加的谓词。
clearOutputs
clearOutputs()
移除由 addOutputColumn 和 addOutputExpression 添加的输出。
clearSortColumns
clearSortColumns()
移除先前由 addSortColumn 添加的排序列。
执行
execute()
运行查询。必须格外小心,以确保谓词列存在于 VGet 所使用的表和投影上,并确保表达式不需要在多个节点上执行。如果表达式由于十分复杂而需要在多个节点上执行,execute 将在 FailOnMultiNodePlans 连接属性设置为 true 时引发 SQLException。
关闭
close()
通过释放由此 VGet 使用的资源来关闭此 VGet。它不会关闭与 Vertica 的父 JDBC 连接。
getWarnings
getWarnings()
检索对此 VGet 的调用所报告的第一个警告。其他警告均为链式,可使用 JDBC 方法 getNextWarning 进行访问。
示例
以下代码查询在创建与可路由查询 API 一起使用的表和投影中定义的 users
表。该表定义了一个使用哈希算法进行分段的 id
列。
import java.sql.*;
import com.vertica.jdbc.kv.*;
public class verticaKV2 {
public static void main(String[] args) {
com.vertica.jdbc.DataSource jdbcSettings
= new com.vertica.jdbc.DataSource();
jdbcSettings.setDatabase("exampleDB");
jdbcSettings.setHost("v_vmart_node0001.example.com");
jdbcSettings.setUserID("dbadmin");
jdbcSettings.setPassword("password");
jdbcSettings.setEnableRoutableQueries(true);
jdbcSettings.setPort((short) 5433);
VerticaRoutableConnection conn;
try {
conn = (VerticaRoutableConnection)
jdbcSettings.getConnection();
System.out.println("Connected.");
VGet get = conn.prepareGet("public", "users");
get.addPredicate("id", 5);
ResultSet rs = get.execute();
rs.next();
System.out.println("ID: " +
rs.getString("id"));
System.out.println("Username: "
+ rs.getString("username"));
System.out.println("Email: "
+ rs.getString("email"));
System.out.println("Closing Connection.");
conn.close();
} catch (SQLException e) {
System.out.println("Error! Stacktrace:");
e.printStackTrace();
}
}
}
该代码将生成以下输出:
Connected.
ID: 5
Username: userE
Email: usere@example.com
Closing Connection.