Spring Data JPA sql查询返回对象

问题概述:

JPA主要适用于强对象关系映射的场景,但是再做查询时需要返回的结果千差万别。所以,当我们使用非数据库对象作为返回结果对象时,

@Data
public class testDTO  {
    Integer ageSum;
    Integer count;
}

 

@Repository
public interface TestDTORepository extends JpaRepository, JpaSpecificationExecutor {
   
@Query(value = "select count(1) count,sum(age) ageSum from student",nativeQuery = true)
public testDTO get();

@Query(value = "select count(1) count,sum(age) ageSum from student",nativeQuery = true)
public List getList();
}

 

往往会启动报错。

Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.example.demo.dao.testDTO

再网上收了好久,只有一种Object[]去接受返回结果的方法(Map,Json同样报上面的错)。

当然会感觉到很蠢,应为不看Sql的话,我们完全没办法知道数组中的每一位代表的是对象中的哪一个值。

苦思无果。

最后在stackoverflow上找到了还算可以的解决方法。

地址参考:https://stackoverflow.com/questions/44436287/nativequery-spring-data-return-object?r=SearchResults

再repository中定义接口,接口中方法为sql返回参数的对应get方法(其他方法测试无效)。

返回此接口对象。

 

改造后代码:

package com.example.demo.repository;

import com.example.demo.dao.User;
import com.example.demo.dao.testDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface TestDTORepository extends JpaRepository, JpaSpecificationExecutor {
    public interface CountAndAgeSum {
        Integer getCount();
        Integer getAgeSum();
    }

    @Query(value = "select count(1) count,sum(age) ageSum from student",nativeQuery = true)
    public CountAndAgeSum get();

    @Query(value = "select count(1) count,sum(age) ageSum from student",nativeQuery = true)
    public List getList();

}

 

Spring Data JPA sql查询返回对象_第1张图片

那么接来的问题就好解决了。

可以通过放射去映射对象,从而得到你想要的对象。

如:

package com.example.demo.Util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

public class GetClassUtil {


    public static Object getClass(Object obj, Class cla) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        Object c = cla.newInstance();
        Method[] objMethodArray = obj.getClass().getDeclaredMethods();
        Method[] claMethodArray = cla.getDeclaredMethods();
        for (Method objMethod : objMethodArray) {
            for (Method claMethod : claMethodArray) {
                String claMethodName = claMethod.getName().toUpperCase();
                String objMethodName = objMethod.getName().toUpperCase().replaceAll("GET", "");
                if (claMethodName.startsWith("SET") && claMethodName.contains(objMethodName)) {
                    claMethod.invoke(c, objMethod.invoke(obj));
                    break;
                }
            }
        }
        return c;
    }

    public static List getClassList(List objList, Class cla) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        return (List) objList.stream().map(o -> {
            try {
                return GetClassUtil.getClass(o, cla);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return null;
        }).collect(Collectors.toList());
    }

}

该方法类的使用的话,可参考下面代码:

TestDTORepository.CountAndAgeSum c = testDTORepository.get();
testDTO t = null;
try {
     t = (testDTO)GetClassUtil.getClass(c,testDTO.class);
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

 

 

你可能感兴趣的:(Spring Data JPA sql查询返回对象)