我在MySQL中使用Spring Boot 1.5和spring data JPA。我试图在单个表上运行一个简单的计数查询,但是找不到比这更好的映射查询结果的方法:
仓库:
public interface VehicleRepository extends JpaRepository<Vehicle, String> { @Query("select v.sourceModule as sourceModule, count(v) as vehicleCount from Vehicle v group by v.sourceModule") List<Object[]> sourceModuleStats(); }
服务:
@Override public List<SourceModuleStatDTO> getSourceModuleStats() { List<Object[]> objects = vehicleRepository.sourceModuleStats(); return objects.stream() .map(o->SourceModuleStatDTO.from((String)o[0], (Long)o[1])) .collect(Collectors.toList()); }
我使用org.immutables,所以使用DTO:
@Value.Immutable @JsonSerialize(as = ImmutableSourceModuleStatDTO.class) @JsonDeserialize(as = ImmutableSourceModuleStatDTO.class) public abstract class SourceModuleStatDTO { public abstract String sourceModule(); public abstract long vehicleCount(); public static SourceModuleStatDTO from(String sm, long c) { return ImmutableSourceModuleStatDTO.builder() .sourceModule(sm) .vehicleCount(c) .build(); } }
这里的问题是映射,我需要强制转换结果或手动检查所有内容。即使JdbcTemplate具有更好的映射功能,我也无法相信没有更好的方法可以做到这一点。
JdbcTemplate
我也尝试过此方法,但是您需要将类路径硬编码到Query中才能使其正常工作,而且我仍然需要将对象映射到Immutables。
使用JdbcTemplate,可以使用RowMapper(src):
RowMapper
private static final class EmployeeMapper implements RowMapper<Employee> { @Override public Employee mapRow(ResultSet rs, int rowNum) throws SQLException { Employee employee = new Employee(); employee.setCountry(rs.getString("country")); employee.setEmployeeName(rs.getString("employee")); return employee; } }
弹簧数据JPA是否有类似的东西@Query?
@Query
如下使用投影如何?
static interface VehicleStats { public String getSourceModule(); public Long getVehicleCount(); }
你的存储库方法是
@Query("select v.sourceModule as sourceModule, count(v) as vehicleCount from Vehicle v group by v.sourceModule") List<VehicleStats> sourceModuleStats();
在Service类中,可以使用以下接口方法。
List<VehicleStats> objects = vehicleRepository.sourceModuleStats(); return objects.stream() .map(o->SourceModuleStatDTO.from(getSourceModule(),getVehicleCount() ) .collect(Collectors.toList());