您的位置:首页 > 其它

solr开发从查询结果集中获取对象数据

2014-03-24 20:09 435 查看
solrJ从查询结果集中获取对象数据.

方案一:自定义转换方式

/**
*
* SolrDocument与实体类转换 [测试通过]
*
* @author pudongping
*
* @param document
*                     SolrDocument对象
* @param clzz
*                     泛型类
* @return <T>
*/
public static <T> T solrDocument2Entity(SolrDocument document, Class<T> clzz) {
if (null != document) {
try {
Object obj = clzz.newInstance();
Method m = null;

Class<?> fieldType = null;

for (String fieldName : document.getFieldNames()) {

//需要说明的是返回的结果集中的FieldNames()比类属性多
Field[] filedArrays = clzz.getDeclaredFields();                        //获取类中所有属性
for (Field f : filedArrays) {
//如果实体属性名和查询返回集中的字段名一致,填充对应的set方法
if(f.getName().equals(fieldName)){

//获取到的属性名
//private java.lang.String com.test.model.Article.id
f = clzz.getDeclaredField(fieldName);

//属性类型
//private java.lang.String com.test.model.Article.id
fieldType = f.getType();

//构造set方法名  setId
String dynamicSetMethod = dynamicMethodName(f.getName(), "set");

//获取方法
//public void com.test.model.Article.setId(java.lang.String)
m = clzz.getMethod(dynamicSetMethod, fieldType);

//获取到的值
LOG.info(f.getName() + "-->" + dynamicSetMethod+ "=" + fieldType.cast(document.getFieldValue(fieldName)));

// 如果是 int, float等基本类型,则需要转型
if (fieldType.equals(Integer.TYPE)) {
fieldType = Integer.class;
} else if (fieldType.equals(Float.TYPE)) {
fieldType = Float.class;
} else if (fieldType.equals(Double.TYPE)) {
fieldType = Double.class;
} else if (fieldType.equals(Boolean.TYPE)) {
fieldType = Boolean.class;
} else if (fieldType.equals(Short.TYPE)) {
fieldType = Short.class;
} else if (fieldType.equals(Long.TYPE)) {
fieldType = Long.class;
} else if(fieldType.equals(String.class)){
fieldType = String.class;
}else if(fieldType.equals(Collection.class)){
fieldType = Collection.class;
}
m.invoke(obj, fieldType.cast(document.getFieldValue(fieldName)));
}
}

}
return clzz.cast(obj);
} catch (ClassCastException e) {
LOG.error("请检查schema.xml中的各个field的数据类型与PO类的是否一致.",e);
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
LOG.error("请检查PO类中的field对应的各个setter和getter是否存在.",e);
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
LOG.error("请检查schema中的field是否不存在于PO类中.", e);
e.printStackTrace();
}
}
LOG.warn("solrDocument is null.");
return null;
}

/**
* 批量转换, 将solrDocumentList转换为实体类 List [测试通过]
*
* @author pudongping
*
* @param documents
*                         solrDocumentList对象
* @param clzz
*                         泛型类
*
* @return List<T>
*
*/
public static <T>List<T> solrDocument2Entity(SolrDocumentList documents, Class<T> clzz) {
if (null != documents && documents.size() > 0) {
List<T> lists = new ArrayList<T>();
for (SolrDocument sd : documents) {
Object obj = solrDocument2Entity(sd, clzz);
if (null!=obj) {
lists.add(clzz.cast(obj));
}
}
return lists;
}
LOG.warn("即将要转换的solrDocumentList为null或者size为0.");
return null;
}


需要说明的是反射里边的那个双重循环

要转换的单个SolrDocument内容如下

SolrDocument{id=2d3f7323-b212-4fae-8d69-d7fcffb0c731, title=[萧萧衷曲无处诉;为伊故,乐所苦。, 锦色芳华,岂堪人虚度?欲寄相思情万缕,捎不到,君心处。], author=柳梦璃, author_s=柳梦璃, _version_=1463433353865723904}


而我们定义的实体类

public class Article implements Serializable{

private static final long serialVersionUID = 4017316764889231758L;

private String id;

private List<String> title;

private String author;

// getter and setter
}


SolrDocument中的fieldName个数比类的属性多,所以我们需要循环去判断.

方案二: 基于注解的内置获取方式

Javabean基于注解配置

package com.test.model;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.solr.client.solrj.beans.Field;

public class Article implements Serializable{

/**
*
*/
private static final long serialVersionUID = 4017316764889231758L;

@Field("id")
private String id;

@Field("title")
private List<String> title;

@Field
private String author;            //@Field无参数时,匹配当前字段

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}

public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public List<String> getTitle() {
return title;
}
public void setTitle(List<String> title) {
this.title = title;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

}


查询结果集的两种转换方式

/**
* 根据关键字查询 [测试通过 - 使用 solr内部转换机制]
* @param <T>
* @param server    solr客户端
* @param keyword    搜索关键字
* @param pageNum    当前页码
* @param pageSize    每页显示的大小
* @param clzz        对象类型
* @return
*/
public static <T>Page<T> queryBean(SolrServer server,String keyword,int pageNum,int pageSize, Class<T> clzz){
SolrQuery query = new SolrQuery();
query.setQuery(keyword);
query.setStart((pageNum-1)*pageSize);
query.setRows(pageSize);
QueryResponse response = null;
try {
response = server.query(query);
} catch (SolrServerException e) {
e.printStackTrace();
return null;
}

//查询到的记录总数
long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue();
//查询结果集
List<T> items = response.getBeans(clzz);
//填充page对象
return new Page<T>(pageNum, pageSize, totalRow, items);
}

/**
* 根据关键字查询 [测试通过 - 使用 solr内部转换机制]
* @param <T>
* @param server    solr客户端
* @param keyword    搜索关键字
* @param pageNum    当前页码
* @param pageSize    每页显示的大小
* @param clzz        对象类型
* @return
*/
public static <T>Page<T> queryBinderBean(SolrServer server,String keyword,int pageNum,int pageSize, Class<T> clzz){
SolrQuery query = new SolrQuery();
query.setQuery(keyword);
query.setStart((pageNum-1)*pageSize);
query.setRows(pageSize);
QueryResponse response = null;
try {
response = server.query(query);
} catch (SolrServerException e) {
e.printStackTrace();
return null;
}
//查询结果集
SolrDocumentList documents = response.getResults();

//使用DocumentObjectBinder获取
List<T> items = server.getBinder().getBeans(clzz,documents);

//查询到的记录总数
long totalRow = Long.valueOf(response.getResults().getNumFound()).intValue();
//填充page对象
return new Page<T>(pageNum, pageSize, totalRow, items);
}


Junit测试

@Test
public void pageQueryBinder(){
Page<Article> page = SolrEngineHandler.queryBinderBean(server, "柳梦璃", 1, 10, Article.class);
System.out.println(page);
}

@Test
public void pageQueryBean(){
Page<Article> page = SolrEngineHandler.queryBean(server, "苏若年", 1, 10, Article.class);
System.out.println(page);
}


转载请注明出处:[/article/4929403.html]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: