Spring data JPA 多表联合分页查询 自定义实体类
程序员文章站
2022-05-04 11:42:06
Spring data jpa 实现多表联合分页查询,自定义实体类接收返回对象集合1.定义返回结果实体类:2.DAO层方法编写3.定义Controller层方法调用工具类定义1.定义返回结果实体类:public class TestDTO{ private String name; // 名称 private String orgName; // 机构名称 private Date grantTime; // 授权时间 public TestDTO() {...
JPA 实现多表联合分页查询,自定义实体类接收返回对象集合
1.定义返回结果实体类:
public class TestDTO{
private String name; // 名称
private String orgName; // 机构名称
private Date grantTime; // 授权时间
public TestDTO() { }
public TestDTO(String name,String orgName,Date grantTime) {
this.name=name;
this.orgName=orgName;
this.grantTime = grantTime;
}
// 生成getter setter 方法;
}
2.DAO层方法编写
在dao层中编写两个方法,一个查询集合的分页数据;一个查询返回的总条数;
public interface TestDao extends JpaRepository<BaseEntity,String> {
/**
* 查询分页列表
* @param id 查询条件
* @param start 分页起始位
* @param size 终止位
* @return
*/
@Query((value="select t1.name,t2.orgName,t2.grantTime "+
"from table1 t1
left join t2 on t1.id=t2.id "+
"where t1.id=?1 limit ?2,?3 ",
nativeQuery=true)
public List<Object[]> getList(String id, @Param("start") long start, @Param("size") int size);
/**
* 查询分页列表
* @param id 查询条件
* @param start 分页起始位
* @param size 终止位
* @return
*/
@Query((value="select count(*) from
"(select t1.name,t2.orgName,t2.grantTime "+
"from table1 t1
"left join t2 on t1.id=t2.id "+
"where t1.id=?1 ) as testTable",
nativeQuery=true)
public Integer getCountNum(String id);
}
查询方法的返回集合须是List<Object[]> ;
3.定义Controller层方法调用
@RequestMapping("/grantList")
public Object queryUserByParam( @RequestParam(defaultValue = "1") int pageNumber,
@RequestParam(defaultValue = "10") int pageSize,
@RequestParam(value="") String id) {
// 分页- 根据入参计算起始位置,jpa分页开始页数默认从0开始,这里-1
PageRequest pageRequest = PageRequest.of(pageNum-1, pageSize);
// 查询总条数
int totalNum = testDao.getCountNum(id);
// 查询集合
List<Object[]> objList = testDao.getList(id,pageRequest.getOffset(),pageRequest.getPageSize());
// 转换为实体类的集合
List<TestDTO> retList = EntityUtils.castEntity(objList, TestDTO.class,new TestDTO());
// 定义分页
PageDTO<TestDTO> dto = null;
// 总条数
dto.setTotal(totalNum);
// 封装数据
if (!retList.isEmpty()) {
for(TestDTO tDto:retList){
dto.addItem(tDto);
}
}
// 返回
return dto.toMap();
}
4.工具类定义
/**
* Spring Data JPA映射自定义实体类 工具类
* 转换实体
*/
public class EntityUtils {
// 日志
private final static Logger logger = LoggerFactory.getLogger(EntityUtils.class);
/**
* 反射转换
* @param list
* @param clazz
* @param model
* @param <T>
* @return
*/
public static <T> List<T> castEntity(List<Object[]> list, Class<T> clazz, Object model) {
List<T> returnList = new ArrayList<T>();
if (list.isEmpty()) {
return returnList;
}
//获取每个数组集合的元素个数
Object[] co = list.get(0);
//获取当前实体类的属性名、属性值、属性类别
List<Map> attributeInfoList = getFiledsInfo(model);
//创建属性类别数组
Class[] c2 = new Class[attributeInfoList.size()];
//如果数组集合元素个数与实体类属性个数不一致则发生错误
if (attributeInfoList.size() != co.length) {
return returnList;
}
//确定构造方法
for (int i = 0; i < attributeInfoList.size(); i++) {
c2[i] = (Class) attributeInfoList.get(i).get("type");
}
try {
for (Object[] o : list) {
Constructor<T> constructor = clazz.getConstructor(c2);
returnList.add(constructor.newInstance(o));
}
} catch (Exception ex) {
logger.error("实体数据转化为实体类发生异常:异常信息:{}", ex.getMessage());
return returnList;
}
return returnList;
}
/**
* * 获取属性类型(type),属性名(name),属性值(value)的map组成的list
* @param model 实体类
* @return list集合
*/
private static List<Map> getFiledsInfo(Object model) {
Field[] fields = model.getClass().getDeclaredFields();
List<Map> list = new ArrayList(fields.length);
Map infoMap = null;
for (int i = 0; i < fields.length; i++) {
infoMap = new HashMap(3);
infoMap.put("type", fields[i].getType());
infoMap.put("name", fields[i].getName());
infoMap.put("value", getFieldValueByName(fields[i].getName(), model));
list.add(infoMap);
}
return list;
}
/**
* 根据属性名获取属性值
*/
private static Object getFieldValueByName(String fieldName, Object modle) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = modle.getClass().getMethod(getter, new Class[]{});
Object value = method.invoke(modle, new Object[]{});
return value;
} catch (Exception e) {
return null;
}
}
/**
* 分页DTO返回 格式化类
* @param <T>
*/
public class PageDTO <T> {
long total;
List<T> items = new ArrayList<>();
String totalName;
String dataName ;
public PageDTO(String totalName,String dataName) {
this.total = total;
this.totalName = totalName;
this.dataName = dataName;
}
public void addItem(T t){
this.items.add(t);
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public Map<String,Object> toMap(){
Map<String,Object> map = new HashMap<>();
map.put(totalName,total);
map.put(dataName,this.items);
return map;
}
}
实体类与查询的sql列的字段顺序要保持一直。
本文地址:https://blog.csdn.net/weixin_43494358/article/details/107348243
上一篇: 【工具类】图片压缩工具类,可压缩jpg, png等图片
下一篇: synchronized详解
推荐阅读
-
Spring data JPA 多表联合分页查询 自定义实体类
-
Spring data jpa的使用与详解(复杂动态查询及分页,排序)
-
在Spring Boot中使用Spring-data-jpa实现分页查询
-
序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询
-
Spring Data JPA实现查询结果返回map或自定义的实体类
-
spring data jpa 关联join查询出自定义实体java bean的坑
-
Spring data jpa的使用与详解(复杂动态查询及分页,排序)
-
Spring data JPA 多表联合分页查询 自定义实体类
-
Spring Data JPA中的多表查询
-
【JPA】Spring Data JPA 实现分页和条件查询