zoukankan      html  css  js  c++  java
  • solr开发从查询结果集中获取对象数据

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

    转载请注明出处:[http://www.cnblogs.com/dennisit/p/3621728.html]

  • 相关阅读:
    Oracle 查看表空间的大小及使用情况sql语句
    Oracle审计--AUD$占用空间较大处理方案
    system表空间爆满解决方法
    Oracle查询库中记录数大于2千万的所有表
    oracle 百万行数据优化查询
    React (Native) Rendering Lifecycle
    React于React native的渲染机制
    Virtual DOM的渲染机制--猜测
    react的优点:兼容了dsl语法与UI的组件化管理
    What is Babel?---JSX and React
  • 原文地址:https://www.cnblogs.com/dennisit/p/3621728.html
Copyright © 2011-2022 走看看