*编辑可能的解决方案 - 任何评论? *
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) {
}
}