Spring Boot中无需entity能否创建repository?多表查询无对应实体如何处理?
问题结论
完全可以不创建整合后字段对应的实体类来实现数据查询,无需强制为多表关联结果单独绑定Repository,以下是常用实现方案:
方案1:基于现有Spring Data JPA Repository扩展
不需要新增实体,直接在现有单表对应的Repository中编写多表查询逻辑:
- 直接返回
Object[]集合,数组元素顺序和SQL查询字段顺序一一对应:// 基于现有任意单表的Repository编写,以下以User实体的Repository为例 public interface UserRepository extends JpaRepository<User, Long> { // nativeQuery=true表示执行原生SQL,可自由关联任意表 @Query(value = "SELECT u.id, u.user_name, o.order_no, o.create_time FROM t_user u LEFT JOIN t_order o ON u.id = o.user_id WHERE u.id = :userId", nativeQuery = true) List<Object[]> listUserWithOrder(Long userId); } - 若需要结构化返回结果,可以用Spring Data JPA的投影功能直接映射到普通DTO,DTO无需标注
@Entity:- 先定义接口投影(无需实现类):
public interface UserOrderDTO { // 方法名要和SQL查询的字段别名完全匹配 Long getUserId(); String getUserName(); String getOrderNo(); LocalDateTime getOrderCreateTime(); }- 调整Repository查询方法:
@Query(value = "SELECT u.id as userId, u.user_name as userName, o.order_no as orderNo, o.create_time as orderCreateTime FROM t_user u LEFT JOIN t_order o ON u.id = o.user_id WHERE u.id = :userId", nativeQuery = true) List<UserOrderDTO> listUserOrderDTO(Long userId);
方案2:基于JdbcTemplate实现(完全无实体依赖)
如果不想依赖JPA的实体体系,可以直接用JdbcTemplate执行SQL,结果映射到普通POJO即可:
@Service public class UserOrderService { @Resource private JdbcTemplate jdbcTemplate; public List<UserOrderVO> listUserWithOrder(Long userId) { String sql = "SELECT u.id as userId, u.user_name as userName, o.order_no as orderNo, o.create_time as orderCreateTime " + "FROM t_user u LEFT JOIN t_order o ON u.id = o.user_id WHERE u.id = ?"; // BeanPropertyRowMapper会自动将字段别名和VO的属性名匹配映射 return jdbcTemplate.query(sql, new Object[]{userId}, new BeanPropertyRowMapper<>(UserOrderVO.class)); } }
注意要点
- 使用JPA投影时,SQL字段的别名必须和DTO的getter方法名(驼峰)完全匹配,否则会出现字段映射为null的问题
- 原生SQL写法要适配所用数据库的语法,避免出现跨库兼容性问题
内容的提问来源于stack exchange,提问作者Can Sahin
相关产品推荐
相关产品推荐

