2017-01-11 201 views
1

我们使用MyBatis-Spring来管理DBMS事务(Cassandra)。在Cassandra中,我们有一个用地图列定义的表格,它用作分区键(我们的键必须是复杂的类型,所以改变它不是一种选择)。MyBatis Cassandra结果集映射

CREATE TABLE mykeyspace.mytable (name text, level frozen<map<text,text>>, effective_ts timestamp ... PRIMARY KEY ((name, level), effective_ts)) 

如果我在csqlsh执行查询对卡桑德拉如下我得到一个结果回(即正确的结果集预期)。

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 [[email protected]] 

另外要注意我试图使用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的弹簧1.3,MyBatis的v3.4.1,spring 4.3.4-RELEASE

回答

1

当执行带嵌入式映射文字的cql字符串(如... where level = {'key2':'value2', 'key1':'value1'})时,将根据键类型按降序重新排序键。在这种情况下,键类型是varchar,因此键将按字母顺序降序区分大小写。插入{'zbc':'', 'abc':'', '1':'', '1abc':'', 'q12':'', 'abbc':'', 'Abbc':''}导致[1=, 1abc=, Abbc=, abbc=, abc=, q12=, zbc=]实际插入。

使用绑定参数执行语句时,绑定的地图对象内的键的顺序被保留。这意味着如果您使用像HashMap<K, V>这样的无序地图结构,则无法保证订单。

比较地图对象时,顺序很重要。映射条目的顺序差异导致比较失败并且不返回任何结果。

您可以通过使用SortedMap<K,V>实现(如TreeMap<K,V>)来解决此问题,默认情况下,这些实现按字母顺序区分大小写。