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); }
