Hibernate Search是一个库,通过自动索引实体,将Hibernate ORM与Apache Lucene或Elasticsearch集成,实现高级搜索功能:全文、地理空间、聚合等。更多信息,请参阅hibernate.org上的Hibernate Search。

在本周早些时候,我在VoxxedVienna的演讲中使用Hibernate Search与Elasticsearch时,有人提出了一个有趣的问题,我一时无法回答

"在运行具有字段投影的全文查询时,能否将结果以POJOs列表的形式返回,而不是以Object数组列表的形式返回?"

答案是:是的,这是可能的,结果转换器正是这个问题的正确工具。

假设你想将演讲中展示的VideoGame实体的投影查询结果转换为以下DTO(数据传输对象)

public static class VideoGameDto {

    private String title;
    private String publisherName;
    private Date release;

    public VideoGameDto(String title, String publisherName, Date release) {
        this.title = title;
        this.publisherName = publisherName;
        this.release = release;
    }

    // getters...
}

这就是通过结果转换器实现它的方法

FullTextEntityManager ftem = ...;

QueryBuilder qb = ftem.getSearchFactory()
    .buildQueryBuilder()
    .forEntity( VideoGame.class )
    .get();

FullTextQuery query = ftem.createFullTextQuery(
    qb.keyword()
        .onField( "tags" )
        .matching( "round-based" )
        .createQuery(),
    VideoGame.class
    )
    .setProjection( "title", "publisher.name", "release" )
    .setResultTransformer( new BasicTransformerAdapter() {
        @Override
        public VideoGameDto transformTuple(Object[] tuple, String[] aliases) {
            return new VideoGameDto( (String) tuple[0], (String) tuple[1], (Date) tuple[2] );
        }
    } );

List<VideoGameDto> results = query.getResultList();

我已经将这个例子推送到GitHub上的演示存储库

还有一些现成的ResultTransformer接口的实现,你可能觉得它们很有帮助。所以请确保查看其类型层次结构。对于这个例子,我发现扩展BasicTransformerAdapter并手动实现transformTuple()方法最容易。

向提问者致谢:谢谢,希望这个答案对您有所帮助!


返回顶部