将 Cassandra BoundStatement 的结果集 map/transform/cast 转换为使用对象映射 API 构建的 Java 类的最有效方法是什么?

What is the most efficient way to map/transform/cast a Cassandra BoundStatement's ResultSet to a Java classe built using the Object-mapping API?

Apache Cassandra 在 DataStax Java 中是否有内置方法将来自 BoundStatement 的结果集映射到使用对象映射构建的域对象 Java 类 API?

我是一个从 Mapper + Accessor 方法转向 BoundStatement 方法的新手,我想继续使用通过对象映射 API 构建的域对象 Java 类所以我在转移到 BoundStatement 时对我的 DAO 方法的实现做了最小的改变。我希望以一种通用的方式进行操作,避免遍历每个 ResultSet 行并为每个域对象一个一个地执行 row.get。

在使用 Mapper + Accessor 方法时,Result.all() 做得很好。找不到与 BoundStatement 方法类似的任何内容。

谢谢

IPVP

您可以通过为您的对象实例化 Mapper,然后使用带有 ResultSetMapper.map. Here is an example, taken from the java driver's tests 来完成 ResultSetcom.datastax.driver.mapping.Result 的映射来自定期执行的查询并将其映射到 Result<Post>,然后迭代结果以访问每个映射的 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 Java 驱动程序的 4.1.0 版开始,使用 new object mapper.

映射对象的方式有所不同

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 的键空间,其中有一个 table posts,其中包含列 user_idpost_idtitle.

我们需要创建一个名为 Post 的 class(我们将使用 @CqlName 注释将其映射到 table 名称 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 的 class(我们需要 运行 查询).

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...

一定要查看 configuring the annotation processor and on creating entities 上的文档。