如何在访问器中动态定义键空间

时间:2016-06-20 18:00:46

标签: java cassandra mapping accessor

我正在尝试创建一个访问器,以便在使用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定义中的键空间,但如果需要,我只在那里更改它并更新与之有关的所有内容。如果我在Accessor中的每个@Query定义中对密钥空间进行硬编码,那么如果密钥空间得到更新,我将不得不更改一堆不同的项目,而不是仅仅在@Table定义中将其更改为一个位置。 我一直在搜索谷歌几个小时,我找不到一个动态声明带有访问器的密钥空间的实例,只有成千上万的访问器示例,他们将密钥空间硬编码到@Query中,如下所示: / p>

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

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

1 个答案:

答案 0 :(得分:1)

@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()时,不是默认连接到两个会话,而是只连接到通过“host”参数请求的会话。

Anywho,我希望这会帮助你。如果你需要它,这是我的另一个使用它的库的例子......

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
    }
}