/** *@Title: ElasticsearchSqlUtil.java *@Package com.nis.util *@Description TODO *@author dell *@date 2016年10月17日 下午4:09:17 *@version 版本号 */ package com.nis.util.elasticsearch; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.zdjizhi.utils.StringUtil; import org.apache.http.client.ClientProtocolException; import org.apache.ibatis.mapping.ResultMap; import org.apache.ibatis.mapping.ResultMapping; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.log4j.Logger; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.nis.domain.LogEntity; import com.nis.domain.Page; import com.nis.util.Constants; import com.nis.util.JsonMapper; import com.nis.util.StringUtils; import com.nis.util.httpclient.HttpClientUtil; import com.nis.web.service.SpringContextHolder; /** * @ClassName: ElasticsearchSqlUtil.java * @Description: 在service中替代oracle查询 * @author (wx) * @date 2016年10月17日 下午4:09:17 * @version V1.0 */ @SuppressWarnings({"unchecked","rawtypes"}) public class ElasticsearchSqlDao { private static final Logger logger=Logger.getLogger(ElasticsearchSqlDao.class); private static final SqlSessionFactory sqlSessionFactory=SpringContextHolder.getBean(SqlSessionFactory.class); private static final Map> fieldsMapMap=new HashMap<>(); public void init(Class clazz){ Map fieldsMap=new HashMap<>(); ResultMap data=sqlSessionFactory.getConfiguration().getResultMap(clazz.getSimpleName()+"Map"); List mappingList=data.getResultMappings(); for(ResultMapping map:mappingList){ fieldsMap.put(map.getColumn().toUpperCase(), map.getProperty()); } fieldsMapMap.put(clazz, fieldsMap); } /** * 获取elasticsearch中的mapping field * getSearchFields(这里用一句话描述这个方法的作用) * (这里描述这个方法适用条件 – 可选) * @param page * @param clazz * @return *List * @exception * @since 1.0.0 */ private String getSearchFields(Page page,Class clazz){ String fields=page.getFields(); if(StringUtil.isBlank(fields)){ fields="*"; }else{ String[] fieldArray=fields.split(","); for(String field :fieldArray){ if(fieldsMapMap.get(clazz).containsKey(field.toUpperCase())){ fields=fields.replace(field, fieldsMapMap.get(clazz).get(field.toUpperCase())); } } } return fields; } /** * * getWhereCondition(where 条件转换) * (这里描述这个方法适用条件 – 可选) * @param entity * @param givenDateFormat * @return * @throws ParseException * @throws IllegalArgumentException * @throws IllegalAccessException *String * @exception * @since 1.0.0 */ private String getWhereCondition(LogEntity entity,SimpleDateFormat givenDateFormat) throws ParseException, IllegalArgumentException, IllegalAccessException{ StringBuffer where=new StringBuffer(); //使用反射获取entity的所有字段值 Class clazz=entity.getClass(); List fieldList=new ArrayList(); fieldList.addAll(Arrays.asList(clazz.getDeclaredFields())); fieldList.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); for(Field field:fieldList){ if(Modifier.isFinal(field.getModifiers()))continue; if(Modifier.isPrivate(field.getModifiers())||Modifier.isProtected(field.getModifiers())){ field.setAccessible(true); } String type=field.getType().getSimpleName(); Object value=field.get(entity); if(value==null)continue; if(field.getName().endsWith("StartTime")){ String startTime=value.toString(); if(!StringUtil.isBlank(startTime)){ String fieldName=field.getName() .replace("search", "") .replace("Start", ""); fieldName=fieldName.replace(fieldName.substring(0, 1),fieldName.substring(0, 1).toLowerCase()); where.append(" AND "+fieldName +">="); where.append(givenDateFormat.parse(startTime).getTime()/1000); } }else if(field.getName().endsWith("EndTime")){ String endTime=value.toString(); if(!StringUtil.isBlank(endTime)){ String fieldName=field.getName() .replace("search", "") .replace("End", ""); fieldName=fieldName.replace(fieldName.substring(0, 1),fieldName.substring(0, 1).toLowerCase()); where.append(" AND "+fieldName +"<"); where.append(givenDateFormat.parse(endTime).getTime()/1000); } }else{ String fieldName=field.getName().replace("search", ""); fieldName=fieldName.replace(fieldName.substring(0, 1),fieldName.substring(0, 1).toLowerCase()); if(fieldsMapMap.get(clazz).containsValue(fieldName)){ if("Date".equals(type)){ Date date=(Date)value; where.append(" AND "+fieldName+"="); where.append(date.getTime()/1000); }else{ where.append(" AND "+fieldName +"="); where.append("'"+value.toString()+"'"); } } } } where.delete(0, " AND ".length()); return where.toString().trim(); } /** * * getOderbys(排序转换) * (这里描述这个方法适用条件 – 可选) * @param page * @param clazz * @return *String * @exception * @since 1.0.0 */ private String getOderbys(Page page,Class clazz){ String orderBy=page.getOrderBy(); for(String field :orderBy.split(" ")){ if(fieldsMapMap.get(clazz).containsKey(field.toUpperCase())){ orderBy=orderBy.replace(field, fieldsMapMap.get(clazz).get(field.toUpperCase())); } } return orderBy; } public String geneEs4SQL(Class clazz,Page page,LogEntity entity) throws ParseException, IllegalArgumentException, IllegalAccessException{ if(!fieldsMapMap.containsKey(clazz)){ this.init(clazz); } SimpleDateFormat givenDateFormat=new SimpleDateFormat(Constants.SEARCH_DATEFORMAT); String indexName=clazz.getSimpleName().toUpperCase(); String fields=getSearchFields(page, clazz); String where=getWhereCondition(entity, givenDateFormat); where=StringUtils.isBlank(where)?" ":" where "+where; String groupBy=""; String orderBy=getOderbys(page,clazz); orderBy=StringUtils.isBlank(orderBy)?" ":" ORDER BY "+orderBy; String pageInfo=getPageInfo(page); String sql="SELECT "+fields+ " FROM "+indexName+where+groupBy+orderBy+pageInfo; logger.info("es-sql:"+sql); return sql.replaceAll(" ", "%20").replaceAll("<", "%3C").replaceAll(">", "%3E"); } public String search(LogEntity entity,String acticeSys) throws ParseException, IllegalArgumentException, IllegalAccessException, ClientProtocolException, IOException{ String sql=geneEs4SQL(entity.getClass(),entity.getPage(),entity); if(acticeSys.equals(Constants.ACTIVESYS_C)){ logger.info("查询C版ES"); return HttpClientUtil.get("http://"+Constants.SEARCH_ES_HOSTANDPORT_C+"/_sql?sql="+sql); }else if(acticeSys.equals(Constants.ACTIVESYS_A)){ logger.info("查询A版ES"); return HttpClientUtil.get("http://"+Constants.SEARCH_ES_HOSTANDPORT_A+"/_sql?sql="+sql); }else{ logger.info("查询B版ES"); return HttpClientUtil.get("http://"+Constants.SEARCH_ES_HOSTANDPORT_B+"/_sql?sql="+sql); } } private String getPageInfo(Page page){ int pageNo=page.getPageNo(); int pageSize=page.getPageSize(); return " limit "+(pageNo-1)*pageSize+", "+page.getPageSize(); } /** * * findLogs(查询方法) * (初始化好list 之后传入方法,查询结果会加入到list中) * @param logList * @param esHostAndPort * @param log * @param givenFormat * @throws ParseException * @throws JSONException * @throws IllegalArgumentException * @throws IllegalAccessException *void * @throws IOException * @throws ClientProtocolException * @exception * @since 1.0.0 */ public void findLogs(List logList,LogEntity log,String activeSys) throws ParseException, JSONException, IllegalArgumentException, IllegalAccessException, ClientProtocolException, IOException{ Class clazz=log.getClass(); JSONObject obj=new JSONObject(search(log,activeSys)); long count=obj.getJSONObject("hits").getLong("total"); long took=obj.getLong("took"); logger.info("search by es cost: "+took+"ms"); log.getPage().setCount(count); if(count>0){ JSONArray resultJson=obj.getJSONObject("hits").getJSONArray("hits"); for(int i=0;i