我正在尝试创建一个访问器,以便在使用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);
}
我意识到我写的查询对于访问者来说并不是真正的原因,我只是为了示例而简化它。所以我来到社区寻求帮助,我无法在任何地方找到任何这样的例子。我无法想象我是第一个想要这样做的人,我无法找到解决这个问题的其他任何人的例子。提前感谢您提供任何帮助,我真的可以使用它。
答案 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
}
}