我试图创建一个访问器,以使用Java在Cassandra中运行稍微更复杂的查询。我的语法没有问题,可以正常使用,但是我的问题是:有没有一种方法可以在访问器中动态声明键空间?
例如,如果为MappingManager创建表映射,则将声明@Table并为其提供键空间和表名称,如下所示:

@Table(keypace="mykeyspace", name="orders")
public class Orders {
    @PartitionKey
    public UUID id;
    //blah blah blah, rest of code
}


现在为该特定表创建访问器很容易:

@Accessor
public interface OrdersAccessor {
    @Query("SELECT * FROM orders WHERE status = :status")
    Result pending(@Param("status") Integer status);
}


简单。问题是它需要一个键空间,而且我是从不对任何事情进行硬编码的忠实拥护者。我意识到我正在“硬编码” MappingManager类定义中Table定义中的键空间,但是如果需要的话,我只在那里更改它并更新与此有关的所有内容。如果我对访问器内部的每个@Query定义中的键空间进行硬编码,则如果更新键空间,则可能必须更改一堆不同的项目,而不是仅在@Table定义中更改一个位置。
我已经在Google上搜索了几个小时,但找不到一个有人动态地声明带有访问器的键空间的实例,只有成千上万个访问器示例,它们将键空间硬编码到@Query中,如下所示:

@Accessor
public interface OrdersAccessor {
    @Query("SELECT * FROM keyspace.orders WHERE status = :status")
    Result pending(@Param("status") Integer status);
}


我意识到我编写的查询并不是访问器的真正原因,为了示例起见,我只是对其进行了简化。所以我来社区寻求帮助,我在任何地方都找不到任何示例。我无法想象我是有史以来第一个想要这样做的人,我只是找不到任何其他人解决这个问题的例子。预先感谢您提供的任何帮助,我真的可以使用。

最佳答案

@Sudhir这是我想出的解决方案。我确信有更好的方法来处理连接,但是对于cassandra和Java来说我还是很陌生,这对于我的需求来说很好用。我希望这有帮助...

public class DbInterface {

private Cluster cluster;
private Session session;
private Map<String, Session> dbMap;
private Map<String, Map<String, Mapper<Class>>> mappers = new ConcurrentHashMap<>();

public DbInterface(String host) {
    Map<String, Session> connections = createConnection(host);
    Session crSession = connections.get("crSession");
    Session hppSession = connections.get("hppSession");
    cluster = Cluster.builder().addContactPoint(host).build();
    Session crSession = cluster.connect("mykeyspace");
    Session hppSession = cluster.connect("hpp");
    MappingManager crManager = new MappingManager(crSession);
    MappingManager hppManager = new MappingManager(hppSession);
    mappers.put("mykeyspace", new ConcurrentHashMap<>());
    mappers.put("mykeyspace2", new ConcurrentHashMap<>());
    Map cr = mappers.get("mykeyspace");
    Map hpp = mappers.get("mykeyspace2");
    cr.put("status", crManager.mapper(OrderStatus.class));
    hpp.put("status", hppManager.mapper(OrderStatus.class));
    cr.put("status_accessor", crManager.createAccessor(OrderStatusAccessor.class));
    hpp.put("status_accessor", hppManager.createAccessor(OrderStatusAccessor.class));
    cr.put("users", crManager.mapper(Users.class));
    hpp.put("users", hppManager.mapper(Users.class));
    cr.put("orders", crManager.mapper(Orders.class));
    hpp.put("orders", hppManager.mapper(Orders.class));
    cr.put("order_detail", crManager.mapper(OrderDetail.class));
    hpp.put("order_detail", hppManager.mapper(OrderDetail.class));
    cr.put("chal_orders", crManager.mapper(ChalOrder.class));
    hpp.put("chal_orders", hppManager.mapper(ChalOrder.class));
    cr.put("chal_order_detail", crManager.mapper(ChalOrderDetail.class));
    hpp.put("chal_order_detail", hppManager.mapper(ChalOrderDetail.class));
    cr.put("detail_accessor", crManager.createAccessor(OrderDetailAccessor.class));
    hpp.put("detail_accessor", hppManager.createAccessor(OrderDetailAccessor.class));
    cr.put("tracking_labels", crManager.mapper(TrackingLabels.class));
    hpp.put("tracking_labels", hppManager.mapper(TrackingLabels.class));

}

public Session getConnection(String type) {
    if(dbMap.containsKey(type)) {
        return dbMap.get(type);
    }
    if(dbMap.containsKey(type.toLowerCase() +"Session")) {
        return dbMap.get(type.toLowerCase() +"Session");
    }
    return dbMap.get("crSession");
}

public Map<String, Session> createConnection(String host) {
    dbMap = new HashMap<>();
    cluster = Cluster.builder().addContactPoint(host).build();
    Session crSession = cluster.connect("mykeyspace");
    Session hppSession = cluster.connect("hpp");
    dbMap.put("crSession", crSession);
    dbMap.put("hppSession", hppSession);
    return dbMap;
}

public Map getDBMap(String client) {
    if(mappers.containsKey(client)) {
        return mappers.get(client);
    }
    throw new RuntimeException("Unknown Client: " + client);
}


}

我正在考虑做的一件事是将会话创建和Map创建移到单独的功能,然后仅连接并构建所需会话的地图。就像在调用DbInterface()时默认不连接到两个会话一样,仅连接到通过“主机”参数请求的会话。

任何人,希望这对您有所帮助。如果您需要它,这是我的另一个使用此库的示例。

public class MyRestController {

    private final DbInterface db = new DbInterface(IPADDRESS);

    @CrossOrigin
    @RequestMapping("/status")
    public String getStatus() {
        Map managerMap = db.getDBMap("mykeyspace");
        OrderStatusAccessor statuses = (OrderStatusAccessor) managerMap.get("status_accessor");
        Result<OrderStatus> allStatuses = statuses.getAll();
        //rest of the code here
    }
}

09-26 15:03