在点燃中创建和查询二进制缓存

时间:2017-07-28 10:26:14

标签: ignite

我正在尝试使用BinaryObjects在运行时创建缓存。例如,我不需要编写像Employee这样的pojo类并将其配置为缓存值类型,而是需要能够使用特定缓存的字段名称和字段类型动态配置缓存。

以下是一些示例代码:

public class EmployeeQuery {

public static void main(String[] args) throws Exception {
    Ignition.setClientMode(true);
    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
        if (!ExamplesUtils.hasServerNodes(ignite))
            return;
        CacheConfiguration<Integer, BinaryObject> cfg = getbinaryCache("emplCache", 1); 
        ignite.destroyCache(cfg.getName());
        try (IgniteCache<Integer, BinaryObject> emplCache = ignite.getOrCreateCache(cfg)) {

            SqlFieldsQuery top5Qry = new SqlFieldsQuery("select * from Employee where salary > 500 limit 5", true);
            while (true) {
                QueryCursor<List<?>> top5qryResult = emplCache.query(top5Qry);

                    System.out.println(">>> Employees ");
                    List<List<?>> all = top5qryResult.getAll();
                    for (List<?> list : all) {
                        System.out.println("Top 5 query result : "+list.get(0) + " , "+ list.get(1) + " , " + list.get(2));
                    }
                    System.out.println("..... ");
                Thread.sleep(5000);
            }
        }
        finally {
            ignite.destroyCache(cfg.getName());
        }
    }
}

private static QueryEntity createEmployeeQueryEntity() {
    QueryEntity employeeEntity = new QueryEntity();
    employeeEntity.setTableName("Employee");
    employeeEntity.setValueType(BinaryObject.class.getName());
    employeeEntity.setKeyType(Integer.class.getName());
    LinkedHashMap<String, String> fields = new LinkedHashMap<>();

    fields.put("id", Integer.class.getName());
    fields.put("firstName", String.class.getName());
    fields.put("lastName", String.class.getName());
    fields.put("salary", Float.class.getName());
    fields.put("gender", String.class.getName());

    employeeEntity.setFields(fields);
    employeeEntity.setIndexes(Arrays.asList(
        new QueryIndex("id"),
        new QueryIndex("firstName"),
        new QueryIndex("lastName"),
        new QueryIndex("salary"),
        new QueryIndex("gender")
    ));

    return employeeEntity;
}

public static CacheConfiguration<Integer, BinaryObject> getbinaryCache(String cacheName, int duration) {
    CacheConfiguration<Integer, BinaryObject> cfg = new CacheConfiguration<>(cacheName);
    cfg.setCacheMode(CacheMode.PARTITIONED);
    cfg.setName(cacheName);
    cfg.setStoreKeepBinary(true);
    cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
    cfg.setIndexedTypes(Integer.class, BinaryObject.class);
    cfg.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new CreatedExpiryPolicy(new Duration(SECONDS, duration))));
    cfg.setQueryEntities(Arrays.asList(createEmployeeQueryEntity()));
    return cfg;
}

}

我正在尝试使用employeeId(Integer)作为键配置缓存,并将整个员工记录(BinaryObject)配置为值。当我运行上面的类时,我得到以下异常:

Caused by: org.h2.jdbc.JdbcSQLException: Table "EMPLOYEE" not found; SQL statement:
select * from "emplCache".Employee where salary > 500 limit 5

我在这里做错了什么?还有除此之外的其他内容:

employeeEntity.setTableName("Employee");

接下来,我正在尝试将数据流式传输到缓存中。这是正确的方法吗?

public class CsvStreamer {

public static void main(String[] args) throws IOException {
    Ignition.setClientMode(true);

    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
        if (!ExamplesUtils.hasServerNodes(ignite))
            return;
        CacheConfiguration<Integer, BinaryObject> cfg = EmployeeQuery.getbinaryCache("emplCache", 1);
        try (IgniteDataStreamer<Integer, BinaryObject> stmr = ignite.dataStreamer(cfg.getName())) {
            while (true) {
                InputStream in = new FileInputStream(new File(args[0]));
                try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in))) {
                    int count =0;
                    for (String line = rdr.readLine(); line != null; line = rdr.readLine()) {
                        String[] words = line.split(",");
                        BinaryObject emp = getBinaryObject(words);

                        stmr.addData(new Integer(words[0]), emp);
                        System.out.println("Sent data "+count++ +" , sal : "+words[6]);
                    }
                }
            }
        }
    }
}

private static BinaryObject getBinaryObject(String[] rawData) {
    BinaryObjectBuilder builder = Ignition.ignite().binary().builder("Employee");
    builder.setField("id", new Integer(rawData[0]));
    builder.setField("firstName", rawData[1]);
    builder.setField("lastName", rawData[2]);
    builder.setField("salary", new Float(rawData[6]));
    builder.setField("gender", rawData[4]);
    BinaryObject binaryObj = builder.build();
    return binaryObj;
}

}

注意:我在群集模式下运行它。 EmployeeQuery和CsvStreamer都是从一台机器上运行的,而且我已经点燃了另外两台机器在服务器模式下运行的情况。理想情况下,我想避免在我的应用程序中使用pojo类,并尽可能使事物变得动态和通用。

1 个答案:

答案 0 :(得分:2)

您收到此异常是因为您没有配置SQL方案。在你的情况下(你不想创建pojo对象等)我建议使用类似于自2.0版以来添加到Apache Ignite的语法的SQL。我确信以下示例可以帮助您进行配置:https://github.com/apache/ignite/blob/master/examples/src/main/java/org/apache/ignite/examples/datagrid/CacheQueryDdlExample.java