实现mybatis关联 in查询

在平时的项目开发中我们很容易碰到这样的问题;我们当实现一个业务接口时;需要到多张数据库表中取出所要的信息,一般情况下我们回选择在DDL层直接发起一条关联查询的sql将所需的字段关联查出来。最近公司的框架里引用另一种让开发者更方便的解决办法;相对我们通常的使用关联查询可能这种方法对查询性能稍稍若了点;先上代码。。。

/**
 * step 1.反射类添加
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public abstract class DataRequiredReflect {


	protected List<String[]> getNeedDetailMethod(Class dataClass,Class needDetailed) {
		List<String[]> result = new ArrayList<String[]>();
		while (dataClass != null) {
			for (Field field : dataClass.getDeclaredFields()) {
				if (needDetailed.isAssignableFrom(field.getType())) {
					String methodNamePostfix = field.getName().substring(0, 1).toUpperCase()+ field.getName().substring(1);
					String[] tmp = new String[2];
					tmp[0] = "get" + methodNamePostfix;
					tmp[1] = "set" + methodNamePostfix;
					result.add(tmp);
				}
			}
			dataClass = dataClass.getSuperclass();
		}
		return result;
	}


	protected Object[] getNeedDetailIds(List list, Class dataClass,Class needDetailed, List<String[]> detailMethodNames) {
		Set<Object> result = new HashSet<Object>();
		try {
			List<Method> getMethods = new ArrayList<Method>();
			for (String[] getSetName : detailMethodNames) {
				Method getMethod = dataClass.getMethod(getSetName[0], null);
				if (getMethod != null)
					getMethods.add(getMethod);
			}
			if (getMethods.isEmpty())
				return null;
			
			Method getIdMethod = needDetailed.getMethod("getId", null);
			for (Object obj : list) {
				if(obj==null){
					continue;
				}
				for (Method method : getMethods) {
					Object detailedObj = method.invoke(obj, null);
					if (detailedObj != null) {
						Object tmpId = (Object) getIdMethod.invoke(detailedObj);
						if (tmpId!=null)
							result.add(tmpId);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toArray(new Object[0]);
	}


	protected String[] getNeedDetailStringIds(List list, Class dataClass,
			Class needDetailed, List<String[]> detailMethodNames) {
		Set<String> result = new HashSet<String>();
		try {
			List<Method> getMethods = new ArrayList<Method>();
			for (String[] getSetName : detailMethodNames) {
				Method setMethod = dataClass.getMethod(getSetName[0], null);
				if (setMethod != null)
					getMethods.add(setMethod);
			}
			if (getMethods.isEmpty())
				return null;
			Method getIdMethod = needDetailed.getMethod("getId", null);
			if (getIdMethod != null)
				for (Object obj : list) {
					for (Method method : getMethods) {
						Object propertyVal = method.invoke(obj, null);
						if (propertyVal != null) {
							Object idVal = getIdMethod.invoke(propertyVal);
							if (idVal != null && !"0".equals(idVal))
								result.add((String) idVal);
						}
					}
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toArray(new String[0]);
	}


	@SuppressWarnings("unchecked")
	protected void detailDatas(List list, Class dataClass, Map cachedDatas,
			Class needDetailed, List<String[]> detailMethodNames) {


		try {
			if (detailMethodNames == null || detailMethodNames.isEmpty()
					|| cachedDatas == null || cachedDatas.isEmpty()
					|| list == null || list.isEmpty())
				return;
			Method getIdMethod = needDetailed.getMethod("getId", null);
			if (getIdMethod != null)
				for (Object obj : list) {
					if(obj==null){
						continue;
					}
					for (String[] getSetName : detailMethodNames) {


						Method getMethod = dataClass.getMethod(getSetName[0],null);
						Method setMethod = dataClass.getMethod(getSetName[1],needDetailed);


						if (getMethod != null && setMethod != null) {


							Object detailedObj = getMethod.invoke(obj, null);


							if (detailedObj != null) {


								Object datailedVal = cachedDatas.get(getIdMethod.invoke(detailedObj,new Object[]{}));
								
								if(datailedVal==null){
									datailedVal = cachedDatas.get(getIdMethod.invoke(detailedObj,new Object[]{})+"");
								}


								if (datailedVal != null)
									setMethod.invoke(obj, datailedVal);
							}
						}
					}
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}

 
/**
 * shep 2填充主类的添加
 */
public class DataPopulateServiceImpl extends DataRequiredReflect implements DataPopulateService{

	private MyBatisDAO myBatisDAO = null;//mybatis基类
	
	private DataCacheService dataCacheService;
	
	@Override
	public void setObjectInfo(Object obj, Class fillClass, String searchStrId) {

		if (obj == null)
			return;
		List list = new ArrayList();
		list.add(obj);
		setListInfos(list, fillClass, searchStrId);
	}

	@Override
	public void setListInfos(List list, Class fillClass, String searchStrId) {

		fillDataDetail(list, fillClass, searchStrId);
	}

	@Override
	public void setObjectInfo(Object obj, String property, Class fillClass,String searchStrId) {

		setObjectInfo(ObjectUtil.getNestedProperty(obj, property), fillClass,searchStrId);
	}

	@Override
	public void setListInfos(List list, String property, Class fillClass,
			String searchStrId) {

		if (list == null || list.isEmpty()) {
			return;
		}

		List objects = new ArrayList();
		for (Object object : list) {
			objects.add(ObjectUtil.getNestedProperty(object, property));
		}

		fillDataDetail(objects, fillClass, searchStrId);
	}

	protected Map findDataMapByIds(Object[] ids, String sqlMapId) {
		Map result = new HashMap();
		if (ids == null || ids.length == 0)
			return result;
		List list = myBatisDAO.findForList(sqlMapId, ids);
		try {
			for (Object obj : list) {
				Long id = (Long) obj.getClass().getMethod("getId", null).invoke(obj, null);
				result.put(id, obj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	private void fillDataDetail(List list, Class fillClass, String searchStr) {

		if (list == null || list.isEmpty()) {
			return;
		}
		
		Class dataClass = list.get(0).getClass();
		List<String[]> detailMethodNames = super.getNeedDetailMethod(dataClass,fillClass);
		Object[] ids = super.getNeedDetailIds(list, dataClass, fillClass,detailMethodNames);
		Map map = dataCacheService.getDataMapByTypeKeys(fillClass, ids); //先从从缓存中查询
		if(map==null || map.size()==0)
		   map = findDataMapByIds(ids, searchStr);
		
		super.detailDatas(list, dataClass, map, fillClass, detailMethodNames);
	}
	
	

	public void setMyBatisDAO(MyBatisDAO myBatisDAO) {
		this.myBatisDAO = myBatisDAO;
	}

	public MyBatisDAO getMyBatisDAO() {
		return myBatisDAO;
	}

	public DataCacheService getDataCacheService() {
		return dataCacheService;
	}

	public void setDataCacheService(DataCacheService dataCacheService) {
		this.dataCacheService = dataCacheService;
	}
}
public interface DataPopulateService {

	/**
	 * 填兖单个对象的信息
	 * 
	 * @param obj
	 *            需要被填充的对象
	 * @param fillClass
	 *            需要填充属性所属的类
	 * @param searchStrId
	 *            查询条件
	 * @throws WSMessage
	 */
	public void setObjectInfo(Object obj, Class fillClass, String searchStrId);

	/**
	 * 批量填兖对象的信息
	 * 
	 * @param list
	 *            需要被填充的对象
	 * @param fillClass
	 *            需要填充属性所属的类
	 * @param searchStrId
	 *            查询条件
	 * @throws WSMessage
	 */
	public void setListInfos(List list, Class fillClass, String searchStrId);
	
	/**
	 * 根据属性填兖单个对象的信息
	 * 
	 * @param obj
	 *            需要被填充的对象
	 * @param property
	 *            需要被填充的属性
	 * @param fillClass
	 *            需要填充属性所属的类
	 * @param searchStrId
	 *            查询条件
	 * @throws WSMessage
	 */
	public void setObjectInfo(Object obj, String property, Class fillClass,String searchStrId);

	/**
	 * 根据属性批量填兖对象的信息
	 * 
	 * @param list
	 *            需要被填充的对象
	 * @param property
	 *            需要被填充的属性
	 * @param fillClass
	 *            需要填充属性所属的类
	 * @param searchStrId
	 *            查询条件
	 */
	public void setListInfos(List list, String property, Class fillClass,String searchStrId);
}

/**
 * shep 3.抽象的填充接口
 */
public abstract class AbstractDataPopulateDaoImpl implements DataPopulateDao{

	@Autowired
	public DataPopulateService dataPopulateService;

	/**
	 * 获取In查询的sqlMapId
	 * 
	 * @return
	 */
	public abstract String getFindInSqlMapId();//实现此抽象方法的dao返回selectId

	@Override
	public void setObjectInfo(Object obj, Class fillClass) {

		dataPopulateService.setObjectInfo(obj, fillClass, getFindInSqlMapId());
	}

	@Override
	public void setListInfos(List list, Class fillClass) {

		dataPopulateService.setListInfos(list, fillClass, getFindInSqlMapId());
	}

	@Override
	public void setObjectInfo(Object obj, String property, Class fillClass) {

		dataPopulateService.setObjectInfo(obj, property, fillClass, getFindInSqlMapId());
	}

	@Override
	public void setListInfos(List list, String property, Class fillClass) {

		dataPopulateService.setListInfos(list, property, fillClass, getFindInSqlMapId());
	}
}

public interface DataPopulateDao {

	/**
	 * 填兖单个对象的信息
	 * 
	 * @param obj
	 *            需要被填充的对象
	 */
	public void setObjectInfo(Object obj, Class fillClass);

	/**
	 * 批量填兖对象的信息
	 * 
	 * @param list
	 */
	public void setListInfos(List list, Class fillClass);

	/**
	 * 根据属性填兖单个对象的信息
	 * 
	 * @param obj
	 *            需要被填充的对象
	 */
	public void setObjectInfo(Object obj, String property, Class fillClass);

	/**
	 * 根据属性批量填兖对象的信息
	 * 
	 * @param list
	 *            需要被填充的对象
	 */
	public void setListInfos(List list, String property, Class fillClass);
}

**********************************************割一下********************************************************************

接下来这样调用:

POJO:

private DoctorServiceInfo doctorServiceInfo;
public class DoctorInfo {
public DoctorServiceInfo getDoctorServiceInfo() {

		return doctorServiceInfo;
	}

	public void setDoctorServiceInfo(DoctorServiceInfo doctorServiceInfo) {

		this.doctorServiceInfo = doctorServiceInfo;
	}}


mybatis mappering:

<pre name="code" class="html"><pre name="code" class="java"><select id="findDoctorServiceInfoIn" resultMap="doctorServiceInfoMap">
      SELECT <include refid="Base_Column_List" /> FROM doctor_service_info WHERE DOCTOR_ID IN
      <foreach item="item" index="index" collection="array" open="(" separator="," close=")">
          #{item}
      </foreach>
  </select>

 
 

DAO:

public interface DoctorServiceInfoDao extends DataPopulateDao{...}

@Repository("doctorServiceInfoDao")
public class DoctorServiceInfoDaoImpl extends AbstractDataPopulateDaoImpl implements DoctorServiceInfoDao {
<span style="white-space:pre">	</span>@Override
	public String getFindInSqlMapId() {
		return FIND_IN;
	}
}

最后service调用:

doctorServiceInfoDao.setObjectInfo(doctor, DoctorServiceInfo.class);

搞定...



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值