前两章讲的是如何搭建部署Solr环境和使用Solr创建数据集合进行存储查询,下面我们需要更进一步,直接使用客户端API进行开发,直接操作数据集合,进行增删改查。
使用客户端API的jar包有两种方式,一种是maven依赖,另外一种是下载jar包添加到path环境中。这里只说maven依赖,下载jar包我不说,但是我提供jar以及相关依赖包供你下载,点击jolrj依赖jar包(http://pan.baidu.com/s/1pJ209ZX),进行下载
<dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>4.10.4</version> </dependency>
包的依赖问题解决后,我们就可以直接在项目中使用solrj客户端进行开发了,还记得上一章里创建【schema.xml】里的字段吗,这次咱们就创建的实体类字段就应该对上,连大小写,下划线都不能有差别。
先写模型类代码,这个里面引入了一个Fieid类,在每个参数定义前注解,如果不注解,存储时就会提示存储异常,字段对应不上,相当于做了类似序列化之类的工作。最复杂的应该是查询部分,设置参数时,名称需要看SolrQuery的API。
Items类
import org.apache.solr.client.solrj.beans.Field; /** * @author shuang * */ public class Items { /** 编号 */ @Field private Integer id; /** 名称 */ @Field private String name; /** 价格 */ @Field private double price; /** 图片 */ @Field private String display_picture; /** 时间 */ @Field private Integer release_time; /** 状态 */ @Field private Integer release_state; /** 交易量 */ @Field private Integer deals; /** 浏览量 */ @Field private Integer hits; public String toString() { StringBuffer sb = new StringBuffer(); sb.append("编号:").append(id); sb.append(", 名称:").append(name); sb.append(", 价格:").append(price); sb.append(", 交易量:").append(deals); sb.append(", 浏览量:").append(hits); sb.append(", 时间:").append(release_time); return sb.toString(); } /** * 获取id 的值 * * @return the id */ public Integer getId() { return id; } /** * 设置id 的值 * * @param id * the id to set */ public void setId(Integer id) { this.id = id; } /** * 获取name 的值 * * @return the name */ public String getName() { return name; } /** * 设置name 的值 * * @param name * the name to set */ public void setName(String name) { this.name = name; } /** * 获取price 的值 * * @return the price */ public double getPrice() { return price; } /** * 设置price 的值 * * @param price * the price to set */ public void setPrice(double price) { this.price = price; } /** * 获取deals 的值 * * @return the deals */ public Integer getDeals() { return deals; } /** * 设置deals 的值 * * @param deals * the deals to set */ public void setDeals(Integer deals) { this.deals = deals; } /** * 获取hits 的值 * * @return the hits */ public Integer getHits() { return hits; } /** * 设置hits 的值 * * @param hits * the hits to set */ public void setHits(Integer hits) { this.hits = hits; } /** * 获取display_picture 的值 * * @return the display_picture */ public String getDisplay_picture() { return display_picture; } /** * 设置display_picture 的值 * * @param display_picture * the display_picture to set */ public void setDisplay_picture(String display_picture) { this.display_picture = display_picture; } /** * 获取release_time 的值 * * @return the release_time */ public Integer getRelease_time() { return release_time; } /** * 设置release_time 的值 * * @param release_time * the release_time to set */ public void setRelease_time(Integer release_time) { this.release_time = release_time; } /** * 获取release_state 的值 * * @return the release_state */ public Integer getRelease_state() { return release_state; } /** * 设置release_state 的值 * * @param release_state * the release_state to set */ public void setRelease_state(Integer release_state) { this.release_state = release_state; } }
/** * @author shuang * */ import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.common.params.ModifiableSolrParams; import com.bbmm.mbs.model.Items; import com.bbmm.mbs.model.Services; public class SolrTest { private final static String url = "http://localhost:8080/test/test"; public static void main(String[] args) { new SolrTest().add(); // new SolrTest().delete(); // new SolrTest().update(); // new SolrTest().query(); } /** * 添加 */ public void add() { try { HttpSolrServer server = getSolrServer(); List<Items> list = new ArrayList<Items>(); for(int i = 0 ; i < 5;i++){ Items item = new Items(); item.setId(i+1); item.setName("item_" + (i+1)); item.setPrice(500 * i); item.setRelease_time((int) (System.currentTimeMillis() /1000)); item.setDeals(10 +i); item.setHits(50 * i); list.add(item); } server.addBeans(list); server.commit(); System.out.println("添加完成"); } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 删除 */ public void delete() { try { HttpSolrServer server = getSolrServer(); server.deleteById("1"); server.commit(); System.out.println("删除完成"); } catch (SolrServerException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 修改 * **/ public void update() { try { HttpSolrServer server = getSolrServer(); Items item = new Items(); item.setId(2); item.setName("item_modify"); item.setPrice(5009); item.setRelease_time((int) (System.currentTimeMillis() /1000)); item.setDeals(109); item.setHits(509); server.addBean(item); server.commit(); System.out.println("修改完成"); } catch (IOException e) { e.printStackTrace(); } catch (SolrServerException e) { e.printStackTrace(); } } /** * 查询 */ @SuppressWarnings("unchecked") public void query() { try { HttpSolrServer server = getSolrServer(); ModifiableSolrParams params = new ModifiableSolrParams(); params.set("q", "id:1"); // q表示查询字符串 params.set("start", 0); // start是开始记录数 分页用 params.set("rows", 3); // rows是返回记录条数 分页用 params.set("sort", "price desc");//sort是排序字段 字段名 排序类型 params.set("fl", "id,name,price,releaseTime,deals,hits"); //fl是 fieldlist缩写,就是需要返回的字段列表,用逗号和空格隔开 QueryResponse response = server.query(params); SolrDocumentList results = response.getResults(); if (!results.isEmpty()) { List<Services> list = toBeanList(results, Services.class); for (Services s : list) { System.out.println(s); } } System.out.println("参数查询完成"); } catch (SolrServerException e) { e.printStackTrace(); } } /** * Solr文档对象转Java对象 * * @param <E> * @param record * @param clazz * @return Object */ public static Object toBean(SolrDocument record, Class<Object> clazz) { Object o = null; try { o = clazz.newInstance(); } catch (InstantiationException e) { System.out.println("Solr文档对象转Java对象实例化异常:" + e.getMessage()); } catch (IllegalAccessException e) { System.out.println("Solr文档对象转Java对象非法访问异常:" + e.getMessage()); } Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { // log.warn("------------" + record.toString()); Object value = record.get(field.getName()); try { if (value != null) { BeanUtils.setProperty(o, field.getName(), value); } } catch (IllegalAccessException e) { System.out.println("Solr文档对象转Java对象方法非法访问异常:" + e.getMessage()); } catch (InvocationTargetException e) { System.out.println("Solr文档对象转Java对象调用目标异常:" + e.getMessage()); } } return o; } @SuppressWarnings({ "rawtypes", "unchecked" }) public static List toBeanList(SolrDocumentList records, Class clazz) { List list = new ArrayList(); for (SolrDocument record : records) { list.add(toBean(record, clazz)); } return list; } private HttpSolrServer solrServer = null; // solrServer是线程安全的,所以在使用时需要使用单例的模式,减少资源的消耗 public HttpSolrServer getSolrServer() { if (solrServer == null) { solrServer = new HttpSolrServer(url); } return solrServer; } }
3. 测试数据增删改查
在SolrTest.java类中依次打开注释运行add、delete、update、query来感受一下Solr的增删改查功能,你就会发现她的魅力所在,当然,如果你要找到更大的成就感和快感,就需要更专心的学习Solr的API了
运行完成,在浏览器【http://localhost:8080/test/#/test/query】里,query选项中,通过查询,能看到刚才存储进去的数据,如果你再运行delete方法,再查询,就看不到编号为1的记录了。如果修改,就会看到数据内容的变更,查询就更要自己体会了。
总结:
到此,Solr单机的搭建部署、配置和java环境的开发已经全部完成。demo中的内容比较简单,是为了尽快写出文章与大家共勉,望大家谅解。其实Solr中还有很多更强大的功能待大家探索,比如联合索引、模糊字段匹配存储、中文分词等等。当然,这些功能,我会抽空写出一些文章供大家参考,共同学习,我也是三天前才接触Solr,所以写出来记录和加深自己印象,文中有不对的地方和建议,希望不吝赐教。