MyBatis Cassandra 结果集映射
MyBatis Cassandra Result Set Map
我们正在使用 MyBatis-Spring 来管理 DBMS 事务 (Cassandra)。在 Cassandra 中,我们有一个用映射列定义的 table,它用作分区键(我们的键必须是复杂类型,因此不能更改它)。
CREATE TABLE mykeyspace.mytable ( name text, level frozen<map<text,text>>, effective_ts timestamp ... PRIMARY KEY ((name, level), effective_ts))
如果我在 csqlsh 中执行针对 Cassandra 的查询,如下所示,我会返回一个结果(即预期的正确结果集)。
SELECT * FROM mykeyspace.mytable where name = 'somename' and level = {'mykey','myvalue'} ;
但是,当通过 MyBatis 执行此操作时,我没有返回任何结果。查询没有抛出任何异常,我可以清楚地看到 MyBatis 框架日志中的查询与我在 cqlsh 提示符中使用的查询匹配。
01/11/2017 14:35:24:644 [DEBUG] getSetForName - ==> Preparing: SELECT * FROM mykeyspace.mytable WHERE NAME = 'somename' AND LEVEL = {'mykey':'myvalue'}
01/11/2017 14:35:24:777 [DEBUG] getValueSetForParameterSet - ==> Parameters:
01/11/2017 14:35:24:890 [DEBUG] getValueSetForParameterSet - <== Total: 0
01/11/2017 14:35:24:890 [DEBUG] SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22b1651]
另一个注意事项我尝试使用 DataStax 驱动程序核心(即在没有 MyBatis 的情况下执行查询)并且也获得了预期的结果集。因此,我的问题必须与 MyBatis 有关,但此时我已经用尽了所有想法。有什么想法或建议吗?
供参考...映射器配置...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mycompany.mapper.MyMapper">
<select id="getSetForName" resultType="string" parameterType="map">
SELECT * FROM MYKEYSPACE.MYTABLE WHERE NAME = '${name}' AND LEVEL = ${level}
</select>
</mapper>
参考...使用DataStax核心API...
private Cluster cluster;
private Session session;
public void doQuery(String name, String level) {
String query = "select * from mykeyspace.mytable where name = '" + name + "' and level = " + level;
Session s = get Session();
ResultSet results = s.execute(query);
for(Row r: results) {
...
}
}
private Session getSession() {
cluster = connectCluster("myhost");
session = cluster.connect();
return session;
}
private Cluster connectCluster(String node) {
return Cluster.builder().addContactPoint(node).build();
}
版本信息:mybatis-spring1.3,mybatis v3.4.1,spring4.3.4-RELEASE
当执行带有嵌入式映射文字的 cql 字符串时,例如 ... where level = {'key2':'value2', 'key1':'value1'}
,键将根据键类型按降序排列 re-ordered。在这种情况下,键类型是 varchar,因此键将按字母顺序 case-sensitive 降序排列。插入 {'zbc':'', 'abc':'', '1':'', '1abc':'', 'q12':'', 'abbc':'', 'Abbc':''}
会导致实际插入 [1=, 1abc=, Abbc=, abbc=, abc=, q12=, zbc=]
。
当使用绑定参数执行语句时,绑定映射对象中键的顺序将被保留。这意味着如果您使用像 HashMap<K, V>
这样的无序映射结构,则无法保证顺序。
比较地图对象时,顺序很重要。映射条目顺序的差异导致比较失败并且没有返回结果。
您可以使用 SortedMap<K,V>
实现解决此问题,例如 TreeMap<K,V>
,默认情况下,键按字母顺序排序 case-sensitive。
我们正在使用 MyBatis-Spring 来管理 DBMS 事务 (Cassandra)。在 Cassandra 中,我们有一个用映射列定义的 table,它用作分区键(我们的键必须是复杂类型,因此不能更改它)。
CREATE TABLE mykeyspace.mytable ( name text, level frozen<map<text,text>>, effective_ts timestamp ... PRIMARY KEY ((name, level), effective_ts))
如果我在 csqlsh 中执行针对 Cassandra 的查询,如下所示,我会返回一个结果(即预期的正确结果集)。
SELECT * FROM mykeyspace.mytable where name = 'somename' and level = {'mykey','myvalue'} ;
但是,当通过 MyBatis 执行此操作时,我没有返回任何结果。查询没有抛出任何异常,我可以清楚地看到 MyBatis 框架日志中的查询与我在 cqlsh 提示符中使用的查询匹配。
01/11/2017 14:35:24:644 [DEBUG] getSetForName - ==> Preparing: SELECT * FROM mykeyspace.mytable WHERE NAME = 'somename' AND LEVEL = {'mykey':'myvalue'}
01/11/2017 14:35:24:777 [DEBUG] getValueSetForParameterSet - ==> Parameters:
01/11/2017 14:35:24:890 [DEBUG] getValueSetForParameterSet - <== Total: 0
01/11/2017 14:35:24:890 [DEBUG] SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@22b1651]
另一个注意事项我尝试使用 DataStax 驱动程序核心(即在没有 MyBatis 的情况下执行查询)并且也获得了预期的结果集。因此,我的问题必须与 MyBatis 有关,但此时我已经用尽了所有想法。有什么想法或建议吗?
供参考...映射器配置...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mycompany.mapper.MyMapper">
<select id="getSetForName" resultType="string" parameterType="map">
SELECT * FROM MYKEYSPACE.MYTABLE WHERE NAME = '${name}' AND LEVEL = ${level}
</select>
</mapper>
参考...使用DataStax核心API...
private Cluster cluster;
private Session session;
public void doQuery(String name, String level) {
String query = "select * from mykeyspace.mytable where name = '" + name + "' and level = " + level;
Session s = get Session();
ResultSet results = s.execute(query);
for(Row r: results) {
...
}
}
private Session getSession() {
cluster = connectCluster("myhost");
session = cluster.connect();
return session;
}
private Cluster connectCluster(String node) {
return Cluster.builder().addContactPoint(node).build();
}
版本信息:mybatis-spring1.3,mybatis v3.4.1,spring4.3.4-RELEASE
当执行带有嵌入式映射文字的 cql 字符串时,例如 ... where level = {'key2':'value2', 'key1':'value1'}
,键将根据键类型按降序排列 re-ordered。在这种情况下,键类型是 varchar,因此键将按字母顺序 case-sensitive 降序排列。插入 {'zbc':'', 'abc':'', '1':'', '1abc':'', 'q12':'', 'abbc':'', 'Abbc':''}
会导致实际插入 [1=, 1abc=, Abbc=, abbc=, abc=, q12=, zbc=]
。
当使用绑定参数执行语句时,绑定映射对象中键的顺序将被保留。这意味着如果您使用像 HashMap<K, V>
这样的无序映射结构,则无法保证顺序。
比较地图对象时,顺序很重要。映射条目顺序的差异导致比较失败并且没有返回结果。
您可以使用 SortedMap<K,V>
实现解决此问题,例如 TreeMap<K,V>
,默认情况下,键按字母顺序排序 case-sensitive。