因为项目考虑把Cassandra作为备选平台,就使用CQL API实现了一些封装接口。在开发过程中,总结出一些小经验,供初接触的菜鸟们参考,也望大牛们多多指教。
1 PreparedStatement提前一次性创建
这一点是Cassandra中的PreparedStatement与关系型数据库的不同处之一。如果每次都创建相同的PreparedStatement,会收到警告信息提示说这样影响性能,所以最好是对常用操作提前一次性创建好PreparedStatement,建议用static方法。例如:
private static PrepareStatement insertStmt = null; ... public static PreparedStatement buildInsertStmt(Session session) { if (insertStmt==null) insertStmt = session.prepare("insert into yourtable(a, b, c) values (?, ?, ?)"); return insertStmt; }
2 关于BatchStatement的限制
BatchStatement是提高运行性能的首要选择,但有两个限制需要注意。其一是BatchStatemen只针对增删改而不包括查询,本人也是菜鸟就犯了这种错误。其二是BatchStatement对数据大小有限制,由配置参数batch_size_warn_threshold_in_kb(默认是5KB)和batch_size_fail_threshold_in_kb(默认是50KB)决定。使用时注意尽量不要超出限制,特别是第二个。
3 关于CQL 的where子句的限制
尽管CQL与SQL很相似,但两者还是有很大的差别,尤其是在Where子句的限制上。具体实在太多这里一言难尽,请参见官方文档(http://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause)。
在项目中,要使用的接口中有几个是用非主键的列作为删除条件,直接删除是肯定行不通的,变通方法:
- 先用非主键的列作为查询条件查询出满足条件的主键结果集,再用主键结果集作条件进行删除操作;
- 要使用非主键列进行查询,需要在非主键列上提前建索引(推荐),或使用ALLOW FILTERING选项扫描全部分区(不推荐)。
4 关于row.getByte()方法
当从Row中取列值时,CQL API提供了getLong(), getInt(), getString(), getByte()等多种方法,但对于getByte()本人没搞明白怎么用。因为Cassandra的列类型中貌似没有byte,只能用int代替,如此一来若用getByte()来获取该列的值会抛类型转换失败的Exception。为此,项目中也只能放弃getByte():
byte b = (byte) row.getInt("byte_col");