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

在做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的class
		Class<?> otClass = (Class<?>) t.getClass();
		//查找到此class中实体对象的名字;如com.gxa.bj.model.Dept_$$_jvst6_7 找到的是com.gxa.bj.model.Dept
		String 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 block
			e.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值