Hibernate表关联对象转Json双向关联解析过度

来源:互联网 发布:淘宝学生背包 编辑:程序博客网 时间:2024/06/16 11:26

在做SSH中,遇到了Hibernate 表与表的关联过多,很多双向关联,然后在转Json后,查询内容,查询出很多数据,基本每个表都查询了一次或两次,造成了内存溢出。所以写了一个工具。

package com.gxa.bj.util;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Timestamp;import java.util.ArrayList;import java.util.Date;import java.util.HashSet;import java.util.List;import java.util.Set;import org.hibernate.collection.internal.PersistentSet;public class ConverHelper {public static Object getCopy(int layer, Object t)throws ClassNotFoundException, InstantiationException,IllegalAccessException, NoSuchMethodException, SecurityException,IllegalArgumentException, InvocationTargetException {if (t == null)return null;if (layer > 0) {layer--;} else {return null;}//class内的泛型,得到t的classClass<?> otClass = (Class<?>) t.getClass();//查找到此class中实体对象的名字;如com.gxa.bj.model.Dept_$$_jvst6_7 找到的是com.gxa.bj.model.DeptString ntClassName = otClass.getName().split("_")[0];@SuppressWarnings("unchecked")//根据com.gxa.bj.model.Dept找到Dept.class实例Class ntClass = Class.forName(ntClassName);//根据Dept.class创建了一个实例Object newT = ntClass.newInstance();//找到Dept.class中的属性(注:不会找到父类的属性),getFields()方法找到public中的属性,也会找到父类的属性Field[] fields = ntClass.getDeclaredFields();for (Field f : fields) {//反射获取对象拼出get,set方法String fieldName = f.getName();String getMethodName = "get"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);String setMethodName = "set"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);//获取get方法Method getMethod = otClass.getMethod(getMethodName);Object obj = getMethod.invoke(t);//获取代理对象中属性的值if (obj != null) {System.out.println("转换"+obj);System.out.println("转换"+obj.getClass());System.out.println("转换"+ntClass);//再次查找此class中的实体对象的名字String objClassName = obj.getClass().getName().split("_")[0];//查找到实体对象的class实例Class objClass=Class.forName(objClassName);//如果查找到的实体对象属于Set类型if(objClass.isAssignableFrom(PersistentSet.class))objClass=Set.class;//如果查找到的实体对象属于Date类型else if(objClass.isAssignableFrom(Timestamp.class))objClass=Date.class;//获取set方法Method setmethod = ntClass.getMethod(setMethodName,objClass);//如果获取的是基本类型if (obj instanceof String || obj instanceof Date|| obj instanceof Integer) {setmethod.invoke(newT, obj);//直接使用set赋值}//如果属于Set类型就调用getSetCopy方法else if (obj instanceof Set) {Set<Object> set = (Set<Object>) obj;setmethod.invoke(newT, getSetCopy(set, layer));} //属于其他类型,也就是代理类型或者model类型使用getCopy方法;else {setmethod.invoke(newT, getCopy(layer, obj));}}}return newT;}public static Set<Object> getSetCopy(Set<Object> set, int layer)throws ClassNotFoundException, InstantiationException,IllegalAccessException, NoSuchMethodException, SecurityException,IllegalArgumentException, InvocationTargetException {if (layer <= 0) {return null;}layer--;Set<Object> newSet = new HashSet<>();for (Object obj : set) {newSet.add(getCopy(layer, obj));}return newSet;}public static List<Object> getListCopy(List list, int layer)throws ClassNotFoundException, InstantiationException,IllegalAccessException, NoSuchMethodException, SecurityException,IllegalArgumentException, InvocationTargetException {System.out.println(list);if (list == null)return null;ArrayList<Object> arrayList = new ArrayList<>();for (Object obj : list) {arrayList.add(getCopy(layer, obj));}return arrayList;}}
在查询的时候,你想调用几层,调用几层。

下面是一个例子:

package com.gxa.bj.action;import java.lang.reflect.InvocationTargetException;import java.util.HashMap;import java.util.List;import java.util.Map;import com.gxa.bj.model.Dept;import com.gxa.bj.model.Employees;import com.gxa.bj.model.Travel;import com.gxa.bj.service.TravelService;import com.gxa.bj.util.ConverHelper;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class BseAction extends ActionSupport{public Map<Object, Object> getMap() {return map;}public void setMap(Map<Object, Object> map) {this.map = map;}private int page;private int rows;private Map<Object,Object> map;public int getPage() {return page;}public void setPage(int page) {this.page = page;}public int getRows() {return rows;}public void setRows(int rows) {this.rows = rows;}public Travel getTravel() {return travel;}public void setTravel(Travel travel) {this.travel = travel;}public TravelService getTravelService() {return travelService;}public void setTravelService(TravelService travelService) {this.travelService = travelService;}public List<Travel> getTravleList() {return travleList;}public void setTravleList(List<Travel> travleList) {this.travleList = travleList;}private Travel travel;private TravelService travelService;private List<Travel> travleList;private String result;public String getResult() {return result;}public void setResult(String result) {this.result = result;}public String select() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{System.out.println(1);System.out.println(2);Travel t =new Travel();List<Object> list=null;if((Employees) ActionContext.getContext().getSession().get("login")!=null){Employees e = (Employees) ActionContext.getContext().getSession().get("login");System.out.println(e.getUserName());System.out.println("1110 ++++++0"+e.getDept().getDeptId());t.setExpense(e);t.setDeptInfo(e.getDept());}travleList=travelService.getList(t,page,rows);try { list=ConverHelper.getListCopy(travleList,2);//解析2层System.out.println(list);} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();}Dept dept=travleList.get(0).getDeptInfo();int a =travelService.getList(t).size();map=new HashMap<>();map.put("total", a);map.put("rows",list);return SUCCESS;}}



1 0
原创粉丝点击