1、可能是目前最好理解的spring-data-jpa原SQL关联查询+分页自定义返回

1、在数据库写好,多表关联Sql语句

SELECT a.*,b.id as item_id FROM tb_test a,tb_item b WHERE a.id = b.test_id AND a.id = '123'

2、在项目Dao层,开启本地查询(nativeQuery = true)

package com.tc.jpa.dao;

import com.tc.jpa.domain.User;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;

import java.util.List;
import java.util.Map;

public interface UserRepository extends JpaRepository<User,String>, JpaSpecificationExecutor<User> {
    
    // 多表查询+分页,自定义查询返回的结果集用 List<Map<String,object>> 接收
    @Query(value = "SELECT a.*,b.id as item_id FROM tb_test a,tb_item b WHERE a.id = b.test_id AND a.id =?1",
           nativeQuery = true)
    public List<Map<String,Object>> userAndItemListMap(String id, Pageable pageable);

}

3、定义数据转换对象DTO(用来封装多表查询返回的数据)

package com.tc.jpa.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class UserDTO {

    private String id;

    private  String username;

    private String password;

    private String name;

    private String bz;

    // 指定序列化的名称
    @JsonProperty("itemId")
    private String item_id;

}

4、service层

package com.tc.jpa.service;

import com.tc.jpa.dao.UserRepository;
import com.tc.jpa.dto.UserDTO;
import com.tc.jpa.utils.MapObjUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    
    public List<UserDTO> findByUserAndItemList(String id,int page,int size){
        // 分页初始化默认值
        if (page <= 0){
            page = 1;
        }
        if (size <= 0){
            size = 10;
        }
        Pageable pageable = PageRequest.of(page - 1, size);
        List<Map<String, Object>> mapList = userRepository.userAndItemListMap(id, pageable);
        if (mapList == null || mapList.isEmpty()){
            return null;
        }
        List<UserDTO> resultList = new ArrayList<>();
        for (Map<String, Object> map: mapList){
            UserDTO  userDTO = MapObjUtil.map2Object(map,UserDTO.class);
            resultList.add(userDTO);
        }
        return resultList;
    }
}

5、MapObjUtil 装换工具类

package com.tc.jpa.utils;
 
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
 
public class MapObjUtil {
 
    /**
     * 实体对象转成Map
     *
     * @param obj 实体对象
     * @return
     */
    public static Map<String, Object> object2Map(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (obj == null) {
            return map;
        }
        Class clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
 
    /**
     * Map转成实体对象
     *
     * @param map   map实体对象包含属性
     * @param clazz 实体对象类型
     * @return
     */
    public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) {
        if (map == null) {
            return null;
        }
        T obj = null;
        try {
            obj = clazz.newInstance();
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                int mod = field.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                    continue;
                }
                field.setAccessible(true);
                String filedTypeName = field.getType().getName();
                if (filedTypeName.equalsIgnoreCase("java.util.date")) {
                    String datetimestamp = String.valueOf(map.get(field.getName()));
                    if (datetimestamp.equalsIgnoreCase("null")) {
                        field.set(obj, null);
                    } else {
                        field.set(obj, new Date(Long.parseLong(datetimestamp)));
                    }
                } else {
                    field.set(obj, map.get(field.getName()));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

6、controller层

package com.tc.jpa.controller;

import com.tc.jpa.dto.UserDTO;
import com.tc.jpa.response.model.ResultVO;
import com.tc.jpa.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/list/{id}/{page}/{size}")
    public ResultVO userList(@PathVariable("id") String id,@PathVariable("page") int page,@PathVariable("size") int size){
        List<UserDTO> userDTOList = userService.findByUserAndItemList(id, page, size);
        return new ResultVO(true,20000,"查询成功",userDTOList);
    }

}

7、统一数据响应格式封装

package com.tc.jpa.response.model;

import lombok.Data;

/**
 * 统一响应标准
 */
@Data
public class ResultVO{

    private boolean flag;//是否成功
    private Integer code;// 返回码
    private String message;//返回信息
    private Object data;// 返回数据

    public ResultVO() {
    }

    public ResultVO(boolean flag, Integer code, String message) {
        this.flag = flag;
        this.code = code;
        this.message = message;
    }

    public ResultVO(boolean flag, Integer code, String message, Object data) {
        this.flag = flag;
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

8、测试

以上,个人整理。如有错漏之处,欢迎大家指正。谢谢!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【2021年,将Spring全家桶系列课程进行Review,修复顺序等错误。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并新增高级的Spring Security等内容,通过手把手一步步教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待】 本课程是Spring案例精讲课程的第四部分Spring Cloud,Spring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Cloud的核心知识点:注册中心、服务提供者与消费者、服务的调用OpenFeign、Hystrix监控、服务网关gateway、消息驱动的微服务Spring Cloud Stream、分布式集群、分布式配置中心的案例介绍, 快速掌握Spring Cloud的核心知识,快速上手,为学习及工作做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring理等不会做过多介绍,希望了解理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾理,这样能够促进大家对理有更好的理解。【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值