如何将Cassandra BoundStatement的ResultSet映射/转换/强制转换为使用对象映射API构建的Java类的最有效方法?

7
有没有一种内置的方式可以在DataStax Java for Apache Cassandra中,将来自BoundStatement的ResultSet映射到使用Object-mapping API构建的域对象Java类?我是一个新手,从Mapper + Accessor方法转移到BoundStatement方法,并希望继续使用使用Object-mapping API构建的域对象的Java类,以便在移动到BoundStatement时对DAO方法的实现进行最小更改。我希望以通用的方式完成这项工作,并避免迭代每个ResultSet行并为每个域对象单独执行row.get。使用Mapper + Accessor方法时,Result.all()可以很好地完成此操作。但无法找到与BoundStatement方法类似的任何内容。谢谢IPVP
2个回答

12

您可以通过实例化一个Mapper对象,然后使用Mapper.map来将 ResultSet 映射到一个com.datastax.driver.mapping.Result中。下面是一个示例,取自于java driver的测试代码,它从一个常规查询的ResultSet中获取数据,并将其映射到Result<Post>中,然后通过迭代Result对象访问每个映射的 Post:

MappingManager manager = new MappingManager(session);

Mapper<Post> m = manager.mapper(Post.class);
...
// Retrieve posts with a projection query that only retrieves some of the fields
ResultSet rs = session.execute("select user_id, post_id, title from posts where user_id = " + u1.getUserId());

Result<Post> result = m.map(rs);
for (Post post : result) {
    assertThat(post.getUserId()).isEqualTo(u1.getUserId());
    assertThat(post.getPostId()).isNotNull();
    assertThat(post.getTitle()).isNotNull();

    assertThat(post.getDevice()).isNull();
    assertThat(post.getTags()).isNull();
}

我正在使用DataStax Cassandra Java驱动程序3.0.2,但它没有MappingManager类。您上面的示例是否也适用于3.x版本的驱动程序? - Vinod Jayachandran
映射器由cassandra-driver-mapping模块提供(https://mvnrepository.com/artifact/com.datastax.cassandra/cassandra-driver-mapping) - Andy Tolbert

3

使用新的对象映射器

从 DataStax Java Driver 4.1.0 版本开始,有一种不同的方式来映射对象,使用新的对象映射器

Andy Tolbert 的答案中的代码会像下面的代码一样。

首先,我们需要启用注释处理器。使用 Maven,将以下内容添加到 pom.xml 中:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>com.datastax.oss</groupId>
                        <artifactId>java-driver-mapper-processor</artifactId>
                        <version>4.4.0</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

假设有一个名为 posts 的键空间,其中包含一张名为 posts 的表,该表具有列 user_idpost_idtitle

我们需要创建一个名为 Post 的类(使用 @CqlName 注解将其映射到表名 posts),如下所示。
import com.datastax.oss.driver.api.mapper.annotations.CqlName;
import com.datastax.oss.driver.api.mapper.annotations.Entity;
import com.datastax.oss.driver.api.mapper.annotations.PartitionKey;

@Entity
@CqlName("posts")
public class Post {

    @PartitionKey
    private String postId;
    private String title;
    private String userId;

    // add getters/setters/no-args constructor/equals/hashCode
}

现在我们创建一个名为PostDao的接口,里面包含我们想要执行的查询。
import com.datastax.oss.driver.api.mapper.annotations.Dao;
import com.datastax.oss.driver.api.mapper.annotations.Select;

@Dao
public interface PostDao {

    @Select
    Post findById(String postId);
}

最后,我们为映射器创建了一个接口。
import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.mapper.annotations.DaoFactory;
import com.datastax.oss.driver.api.mapper.annotations.DaoKeyspace;
import com.datastax.oss.driver.api.mapper.annotations.Mapper;

@Mapper
public interface PostMapper {

    @DaoFactory
    PostDao postDao(@DaoKeyspace CqlIdentifier keyspace);
}

当我们运行mvn compile命令时,注解处理器将生成一个名为PostMapperBuilder的类(我们需要它来运行查询)。
CqlSession session = CqlSession.builder().build();

PostMapper postMapper = new PostMapperBuilder(session).build();

PostDao dao = postMapper.postDao(CqlIdentifier.fromCql("posts"));

Post post = dao.findById("a1b2c3d4"); // or whatever the postId is...

请务必查阅注释处理器配置以及实体创建的文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接