spring数据JPA / Hibernate。复杂的交叉表SQL,它不映射到表实体

时间:2016-05-26 09:53:06

标签: spring hibernate jpa spring-data spring-data-jpa

*编辑可能的解决方案 - 任何评论? *

spring 4.2.5 RELEASE

我开始在旧版数据库上创建Java Web服务。

遵循spring-data JPA存储库模式创建映射到表的实体,扩展CrudRepository的存储库运行良好。

As described in this great tutorial

我见过的所有例子都假设将表简单映射到实体。订单 - > OrderEntity,OrderLine,客户等。

如何处理不适合此模式的只读报告类型查询,其中查询结果包含来自许多表的列并使用复杂的交叉表连接。

我只是在努力解决如何应对这种情况。

可能的解决方案

我设法使用NamedParameterJdbcTemplate运行原生SQL,并使用BeanPropertyRowMapper将结果映射到POJO

ApplicationContext类

定义了NamedParameterJdbcTemplate bean(剩余的bean HikariCP,JPA Session Factory,JPA事务管理器,DozerBean映射器为简洁而省略)

@Configuration
@EnableTransactionManagement

@EnableJpaRepositories(basePackages = {"com.savant.test.spring.donorservicejpa.dao.repository"},
        repositoryBaseClass = com.savant.test.spring.donorservicejpa.dao.repository.BaseRepositoryImpl.class )

@ComponentScan(
        {"com.savant.test.spring.donorservicejpa.dao.jdbc.repository",
         "com.savant.test.spring.donorservicejpa.dao.query.objects"})


public class ApplicationContext {

    @Bean
    NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new NamedParameterJdbcTemplate(dataSource);
    }

}

搜索结果的POJO。没有Spring注释,只是一个简单的类

package com.savant.test.spring.donorservicejpa.dao.query.objects;

public class SessionSearchResult {

    private String sessno;
    private String sesdate;
    // etc

    // setters/getters
}

'存储库&#39 ;.它实际上并不是弹簧术语库,只是一个接口/类实现

package com.savant.test.spring.donorservicejpa.dao.jdbc.repository;

public interface SessionSearchRepository{
    List<SessionSearchResult> findByCriteria(String searchCriteria);
}

基础实施

package com.savant.test.spring.donorservicejpa.dao.jdbc.repository;

import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public class BaseJdbcRepositoryImpl {

    protected final NamedParameterJdbcTemplate jdbcTemplate;

    BaseJdbcRepositoryImpl(NamedParameterJdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

}

搜索的简单测试实现。

package com.savant.test.spring.donorservicejpa.dao.jdbc.repository;


import com.savant.test.spring.donorservicejpa.dao.query.objects.SessionSearchResult;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;


@Component
public class SessionSearchRepositoryImpl extends BaseJdbcRepositoryImpl implements SessionSearchRepository {

    private static final String SESSION_SEARCH_SQL
            = "SELECT sesdet.sessno, sessdays.sesdate "
            + "FROM sesdet, sessdays "
            + "WHERE sessdays.sessno = sesdet.sessno "
            + "AND sesdet.sessno = :sessno";


    @Autowired
    public SessionSearchRepositoryImpl(NamedParameterJdbcTemplate jdbcTemplate) {
        super(jdbcTemplate);
    }

    @Transactional(readOnly = true)
    @Override
    public List<SessionSearchResult> findByCriteria(String searchCriteria) {
        Map<String, String> queryParams = new HashMap<>();

        queryParams.put("sessno", searchCriteria);
        List<SessionSearchResult> searchResults = jdbcTemplate.query(SESSION_SEARCH_SQL, queryParams,
                new BeanPropertyRowMapper<>(SessionSearchResult.class));

        return searchResults;
    }
}

一个简单的测试就是运行SQL

@Autowired
SessionSearchRepository sessionSearchRepository;


@Test
public void a_testSessionSearch() throws Exception, Throwable {
    List<SessionSearchResult> sl =  sessionSearchRepository.findByCriteria("CA04AS");

    for (SessionSearchResult sessionSearchEntity : sl) {

    }

}

0 个答案:

没有答案