266 lines
9.3 KiB
Java
266 lines
9.3 KiB
Java
/**
|
||
*@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<Class,Map<String,String>> fieldsMapMap=new HashMap<>();
|
||
public void init(Class clazz){
|
||
Map<String,String> fieldsMap=new HashMap<>();
|
||
ResultMap data=sqlSessionFactory.getConfiguration().getResultMap(clazz.getSimpleName()+"Map");
|
||
List<ResultMapping> 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<String>
|
||
* @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<Field> fieldList=new ArrayList<Field>();
|
||
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<resultJson.length();i++){
|
||
JSONObject re=(JSONObject)resultJson.get(i);
|
||
JSONObject json=re.getJSONObject("_source");
|
||
Iterator it=json.keys();
|
||
//找出时间字段,由于中心时间戳没有存毫秒,在这里转换时间的时候需要将10位的时间戳转换为13位的时间戳
|
||
//默认以Time结尾的字段为时间字段
|
||
while(it.hasNext()){
|
||
String key=it.next().toString();
|
||
if(key.endsWith("Time")&&json.has(key)&&!json.isNull(key)){
|
||
long time=json.getLong(key);
|
||
if(String.valueOf(time).length()==10){
|
||
json.put(key, time*1000);
|
||
}
|
||
}
|
||
}
|
||
logList.add(JsonMapper.fromJsonString(json.toString(), clazz));
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
}
|