Lucene第一讲——概述与入门

一、概述

  1.什么是Lucene?

    Lucene是apache下的一个开源的全文检索引擎工具包

    它为软件开发人员提供一个简单易用的工具包(类库),以方便的在目标系统中实现全文检索的功能。

  2.能干什么?

    主要运用:全文检索

  3.全文检索定义   

    全文检索首先将要查询的目标文档中的词提取出来,组成索引,通过查询索引达到搜索目标文档的目的。这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search

 二、实现流程

  

 

  流程主要分为:索引流程  搜索流程

三、入门程序  

  1.准备数据(数据库)

  

  2.引入依赖(使用maven)

 <!--版本管理--><properties><lucene.version>5.3.1</lucene.version><junit.version>4.12</junit.version></properties><dependencies><!-- lucene-core --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>${lucene.version}</version></dependency><!-- lucene-query-parser --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-queryparser</artifactId><version>${lucene.version}</version></dependency><!-- lucene-analyzers-common --><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-analyzers-common</artifactId><version>${lucene.version}</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version><scope>test</scope></dependency></dependencies>
View Code

  //使用数据库作为数据源请添加数据库依赖

  3.其它:如JDK(7及以上),mysql等不再赘述

  4.索引流程

    1.为什么采集数据

  全文检索搜索的内容的格式是多种多样的,比如:视频、mp3、图片文档等等。对于这种格式不同的数据,需要先将他们采集到本地,然后统一封装到lucene的文档对象中,也就是说需要将存储的内容进行统一才能对它进行查询。

    2.采集数据的方式

  l 对于互联网中的数据,使用爬虫工具(http工具)将网页爬取到本地

  l 对于数据库中的数据使用jdbc程序进行数据采集

  l 对于文件系统的数据,使用io流采集

    常用数据采集爬虫工具(了解):

Solr(http://lucene.apache.org/solr) ,solr是apache的一个子项目,支持从关系数据库、xml文档中提取原始数据。

Nutch(http://lucene.apache.org/nutch), Nutch是apache的一个子项目,包括大规模爬虫工具,能够抓取和分辨web网站数据。

jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix 是一个由 java 开发的、开源的网络爬虫,用户可以使用它来从网上抓取想要的资源。其最出色之处在于它良好的可扩展性,方便用户实现自己的抓取逻辑。

    3.索引文件逻辑结构

    

 

   与字典的 结构类似,一边目录一边文档,目录是索引域,文档是lucene封装的统一文档格式 

    文档域

      文档域存储的信息就是采集到的信息通过Document对象来存储具体说是通过Document对象中field域来存储数据

      比如数据库中一条记录会存储一个一个Document对象数据库中一列会存储成Document中一个field

      文档域中,Document对象之间是没有关系的而且每个Document中的field域也不一定一样 

     索引域

      索引域主要是为了搜索使用的索引域内容是经过lucene分词之后存储的

    倒排索引表

      传统方法是先找到文件,如何在文件中找内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大就搜索慢。

      倒排索引结构是根据内容(词语)找文档,倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它是在索引中匹配搜索关键字,由于索引内容量有限并且采用固定优化算法搜索速度很快,找到了索引中的词汇,词汇与文档关联,从而最终找到了文档。

    

  5.索引

     1.采集数据

    对应上文数据库的PO类:

package com.itheima.lucene.po;/***  * <p>* Title: Book* </p>*  * <p>* Description: TODO(这里用一句话描述这个类的作用) * <p>* <p>* Company: www.itcast.com* </p>*  @author 传智.关云长   @date 2015-12-27 上午10:03:11    @version 1.0*/
public class Book {// 图书IDprivate Integer id;// 图书名称private String name;// 图书价格private Float price;// 图书图片private String pic;// 图书描述private String description;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Float getPrice() {return price;}public void setPrice(Float price) {this.price = price;}public String getPic() {return pic;}public void setPic(String pic) {this.pic = pic;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}}
View Code

    使用传统JDBC从数据库采集数据进行封装:

package com.itheima.lucene.dao;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;import com.itheima.lucene.po.Book;/***  * <p>* Title: BookDaoImpl* </p>*  * <p>* Description: TODO(这里用一句话描述这个类的作用) * <p>* <p>* Company: www.itcast.com* </p>*  @author 传智.关云长   @date 2015-12-27 上午10:04:30    @version 1.0*/
public class BookDaoImpl implements BookDao {@Overridepublic List<Book> queryBooks() {// 数据库链接Connection connection = null;// 预编译statementPreparedStatement preparedStatement = null;// 结果集ResultSet resultSet = null;// 图书列表List<Book> list = new ArrayList<Book>();try {// 加载数据库驱动Class.forName("com.mysql.jdbc.Driver");// 连接数据库connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/solr", "root", "root");// SQL语句String sql = "SELECT * FROM book";// 创建preparedStatementpreparedStatement = connection.prepareStatement(sql);// 获取结果集resultSet = preparedStatement.executeQuery();// 结果集解析while (resultSet.next()) {Book book = new Book();book.setId(resultSet.getInt("id"));book.setName(resultSet.getString("name"));book.setPrice(resultSet.getFloat("price"));book.setPic(resultSet.getString("pic"));book.setDescription(resultSet.getString("description"));list.add(book);}} catch (Exception e) {e.printStackTrace();}return list;}}
View Code

    2.创建索引

    

    Document就是封装数据的文档对象

    IndexWriter是索引过程的核心组件,通过IndexWriter可以创建新索引、更新索引、删除索引操作。IndexWriter需要通过Directory对索引进行存储操作。

    Directory描述了索引的存储位置,底层封装了I/O操作,负责对索引进行存储。它是一个抽象类,它的子类常用的包括FSDirectory(在文件系统存储索引)、RAMDirectory(在内存存储索引)。

     创建索引过程:

   // 采集数据  // 将采集到的数据封装到Document对象中  // 创建分词器,标准分词器  // 创建IndexWriter

  // 指定索引库的地址  // 通过IndexWriter对象将Document写入到索引库中  // 关闭writer

package com.itheima.lucene.first;import java.io.File;
import java.util.ArrayList;
import java.util.List;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FloatField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;import com.itheima.lucene.dao.BookDao;
import com.itheima.lucene.dao.BookDaoImpl;
import com.itheima.lucene.po.Book;/***  * <p>* Title: IndexManager* </p>*  * <p>* Description: TODO(这里用一句话描述这个类的作用) * <p>* <p>* Company: www.itcast.com* </p>*  @author 传智.关云长   @date 2015-12-27 上午10:08:12    @version 1.0*/
public class IndexManager {@Testpublic void createIndex() throws Exception {// 采集数据BookDao dao = new BookDaoImpl();List<Book> list = dao.queryBooks();// 将采集到的数据封装到Document对象中List<Document> docList = new ArrayList<>();Document document;for (Book book : list) {document = new Document();// store:如果是yes,则说明存储到文档域中// 图书ID// 不分词、索引、存储 StringFieldField id = new StringField("id", book.getId().toString(), Store.YES);// 图书名称// 分词、索引、存储 TextFieldField name = new TextField("name", book.getName(), Store.YES);// 图书价格// 分词、索引、存储 但是是数字类型,所以使用FloatFieldField price = new FloatField("price", book.getPrice(), Store.YES);// 图书图片地址// 不分词、不索引、存储 StoredFieldField pic = new StoredField("pic", book.getPic());// 图书描述// 分词、索引、不存储 TextFieldField description = new TextField("description",book.getDescription(), Store.NO);// 设置boost值if (book.getId() == 4)description.setBoost(100f);// 将field域设置到Document对象中
            document.add(id);document.add(name);document.add(price);document.add(pic);document.add(description);docList.add(document);}// 创建分词器,标准分词器// Analyzer analyzer = new StandardAnalyzer();// 使用ikanalyzerAnalyzer analyzer = new IKAnalyzer();// 创建IndexWriterIndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);// 指定索引库的地址File indexFile = new File("E:\\11-index\\hm19\\");Directory directory = FSDirectory.open(indexFile);IndexWriter writer = new IndexWriter(directory, cfg);// 通过IndexWriter对象将Document写入到索引库中for (Document doc : docList) {writer.addDocument(doc);}// 关闭writer
        writer.close();}@Testpublic void deleteIndex() throws Exception {// 创建分词器,标准分词器Analyzer analyzer = new StandardAnalyzer();// 创建IndexWriterIndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);Directory directory = FSDirectory.open(new File("E:\\11-index\\hm19\\"));// 创建IndexWriterIndexWriter writer = new IndexWriter(directory, cfg);// Terms// writer.deleteDocuments(new Term("id", "1"));// 删除全部(慎用)
        writer.deleteAll();writer.close();}@Testpublic void updateIndex() throws Exception {// 创建分词器,标准分词器Analyzer analyzer = new StandardAnalyzer();// 创建IndexWriterIndexWriterConfig cfg = new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer);Directory directory = FSDirectory.open(new File("E:\\11-index\\hm19\\"));// 创建IndexWriterIndexWriter writer = new IndexWriter(directory, cfg);// 第一个参数:指定查询条件// 第二个参数:修改之后的对象// 修改时如果根据查询条件,可以查询出结果,则将以前的删掉,然后覆盖新的Document对象,如果没有查询出结果,则新增一个Document// 修改流程即:先查询,再删除,在添加Document doc = new Document();doc.add(new TextField("name", "lisi", Store.YES));writer.updateDocument(new Term("name", "zhangsan"), doc);writer.close();}
}
View Code

  模拟:

package com.itheima.lucene;import com.itheima.lucene.PO.Book;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;/*** Lucene的入门程序* 作者: Administrator* 日期: 2017/9/6**/
public class LuceneFirst {public static void main(String[] args) throws IOException {// 模拟采集数据List<Book> bookList = new ArrayList<>();Book book1 = new Book(1, "java", 100f, "pic1", "java入门书籍");Book book2 = new Book(2, "C", 100.6f, "pic2", "C语言入门书籍");Book book3 = new Book(3, "python", 90.7f, "pic3", "python入门书籍");bookList.add(book1);bookList.add(book2);bookList.add(book3);// 封装数据到Document对象中List<Document> docList = new ArrayList<>();Document doc;for (Book book : bookList) {doc = new Document();// 创建文档中的Field域,Store可以确定是否存储到文档域中Field idField = new TextField("id", book.getId().toString(), Field.Store.YES);Field nameField = new TextField("name", book.getName(), Field.Store.YES);Field priceField = new TextField("price", book.getPrice().toString(), Field.Store.YES);Field picField = new TextField("pic", book.getPic(), Field.Store.YES);Field descriptionField = new TextField("description", book.getDescription(), Field.Store.YES);// 将域放入文档中
            doc.add(idField);doc.add(nameField);doc.add(priceField);doc.add(picField);doc.add(descriptionField);// 将文档放入文档列表
            docList.add(doc);}// 创建分词器Analyzer analyzer = new StandardAnalyzer();// 创建IndexWriterIndexWriterConfig conf = new IndexWriterConfig(analyzer);String path = "D:\\BdiduYunDownload\\lucene\\index";Directory dir = FSDirectory.open(Paths.get(path));IndexWriter indexWriter = new IndexWriter(dir, conf);// 通过索引写对象将docList写入索引库for (Document document : docList) {indexWriter.addDocument(document);}// 流的关闭
        indexWriter.close();}
}
View Code

  索引文件:

  

 

   6.分词过程

    Lucene中分词主要分为两个步骤分词过滤   

     分词field域中的内容一个个的分词

    过滤将分好的词进行过滤比如去掉标点符号大写转小写词的型还原(复数转单数、过去式转成现在式)、停用词过滤(没有去重过滤)

    停用词单独应用没有特殊意义的词比如的英文中的this is a the等等

    分词示例讲解:

要分词的内容
Lucene is a Java full-text search engine. 分词
Lucene 
is 
a 
Java 
Full
-
text 
search 
engine
.过滤去掉标点符号
Lucene 
is 
a 
Java 
Full
text 
search 
engine去掉停用词
Lucene 
Java 
Full
text 
search 
engine大写转小写
lucene 
java 
full
text 
search 
engine
View Code

    语汇单元生成过程:

  

  同一个域中相同的语汇单元(Token)对应同一个Term(词),它记录了语汇单元的内容及所在域的域名等,还包括来该token出现的频率及位置。

  不同的域中拆分出来的相同的单词对应不同的term。

   相同的域中拆分出来的相同的单词对应相同的term。

  例如:图书信息里面,图书名称中的java和图书描述中的java对应不同的term

   使用luke工具可以查看索引信息

   7.搜索流程

    1.输入查询语句  

    同数据库的sql一样,lucene全文检索也有固定的语法:

    最基本的有比如:AND, OR, NOT 等

    举个例子,用户想找一个description中包括java关键字和lucene关键字的文档。

    它对应的查询语句:description:java AND lucene

    2.搜索流程:

    

    3.代码实现:

package com.itheima.lucene.first;import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;/***  * <p>* Title: IndexSearch* </p>*  * <p>* Description: TODO(这里用一句话描述这个类的作用) * <p>* <p>* Company: www.itcast.com* </p>*  @author 传智.关云长   @date 2015-12-27 上午11:05:35    @version 1.0*/
public class IndexSearch {private void doSearch(Query query) {// 创建IndexSearcher// 指定索引库的地址try {File indexFile = new File("E:\\11-index\\hm19\\");Directory directory = FSDirectory.open(indexFile);IndexReader reader = DirectoryReader.open(directory);IndexSearcher searcher = new IndexSearcher(reader);// 通过searcher来搜索索引库// 第二个参数:指定需要显示的顶部记录的N条TopDocs topDocs = searcher.search(query, 10);// 根据查询条件匹配出的记录总数int count = topDocs.totalHits;System.out.println("匹配出的记录总数:" + count);// 根据查询条件匹配出的记录ScoreDoc[] scoreDocs = topDocs.scoreDocs;for (ScoreDoc scoreDoc : scoreDocs) {// 获取文档的IDint docId = scoreDoc.doc;// 通过ID获取文档Document doc = searcher.doc(docId);System.out.println("商品ID:" + doc.get("id"));System.out.println("商品名称:" + doc.get("name"));System.out.println("商品价格:" + doc.get("price"));System.out.println("商品图片地址:" + doc.get("pic"));System.out.println("==========================");// System.out.println("商品描述:" + doc.get("description"));
            }// 关闭资源
            reader.close();} catch (IOException e) {e.printStackTrace();}}@Testpublic void indexSearch() throws Exception {// 创建query对象// 使用QueryParser搜索时,需要指定分词器,搜索时的分词器要和索引时的分词器一致// 第一个参数:默认搜索的域的名称QueryParser parser = new QueryParser("description",new StandardAnalyzer());// 通过queryparser来创建query对象// 参数:输入的lucene的查询语句(关键字一定要大写)Query query = parser.parse("description:java AND lucene");doSearch(query);}@Testpublic void termQuery() {// 创建TermQuery对象Query query = new TermQuery(new Term("description", "java"));doSearch(query);}@Testpublic void numericRangeQuery() {// 创建NumericRangeQuery对象// 参数:域的名称、最小值、最大值、是否包含最小值、是否包含最大值Query query = NumericRangeQuery.newFloatRange("price", 55f, 60f, true,false);doSearch(query);}@Testpublic void booleanQuery() {// 创建BooleanQueryBooleanQuery query = new BooleanQuery();// 创建TermQuery对象Query q1 = new TermQuery(new Term("description", "lucene"));// 创建NumericRangeQuery对象// 参数:域的名称、最小值、最大值、是否包含最小值、是否包含最大值Query q2 = NumericRangeQuery.newFloatRange("price", 55f, 60f, true,false);// 组合关系代表的意思如下:// 1、MUST和MUST表示“与”的关系,即“交集”。// 2、MUST和MUST_NOT前者包含后者不包含。// 3、MUST_NOT和MUST_NOT没意义// 4、SHOULD与MUST表示MUST,SHOULD失去意义;// 5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。// 6、SHOULD与SHOULD表示“或”的概念。
query.add(q1, Occur.MUST_NOT);query.add(q2, Occur.MUST_NOT);doSearch(query);}@Testpublic void multiFieldQueryParser() throws Exception {// 创建7.3.2 MultiFieldQueryParser// 默认搜索的多个域的域名String[] fields = { "name", "description" };Analyzer analyzer = new StandardAnalyzer();Map<String, Float> boosts = new HashMap<String, Float>();boosts.put("name", 200f);MultiFieldQueryParser parser = new MultiFieldQueryParser(fields,analyzer, boosts);// Query query = parser.parse("name:lucene OR description:lucene");Query query = parser.parse("java");System.out.println(query);doSearch(query);}
}
View Code

    QueryParser实现:

package com.itheima.lucene;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;import java.io.IOException;
import java.nio.file.Paths;/*** Lucene的搜索功能* 作者: Administrator* 日期: 2017/9/6**/
public class LuceneSearch {public static void main(String[] args) throws ParseException, IOException {// 使用QueryParser 参数分别为默认搜索域与分词器String f = "description";Analyzer a = new StandardAnalyzer();QueryParser parser = new QueryParser(f, a);// 通过parser创建Query对象String q = "description:java"; // 查询语句(Luncene语法)Query query = parser.parse(q);// 创建IndexSearcherString path = "D:\\BdiduYunDownload\\lucene\\index";Directory dir = FSDirectory.open(Paths.get(path));IndexReader reader = DirectoryReader.open(dir);IndexSearcher searcher = new IndexSearcher(reader);// 通过searcher搜索,分别为查询对象和需要显示的条数TopDocs topDocs = searcher.search(query, 10);// 结果处理int totalHits = topDocs.totalHits; // 总记录数System.out.println("总记录数:"+totalHits);ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 经过打分的文档for (ScoreDoc scoreDoc : scoreDocs) {// 获取doc的IDint docID = scoreDoc.doc;// 根据docID获取文档(类似数据库的一条记录)Document doc = searcher.doc(docID);System.out.println("ID为:"+doc.get("id"));System.out.println("name为:"+doc.get("name"));System.out.println("price为:"+doc.get("price"));System.out.println("pic为:"+doc.get("pic"));System.out.println("description为:"+doc.get("description"));}// 关闭reader
        reader.close();}
}
View Code

    结果:

    

   关于Lucene的更多详细介绍,请参见 xingoo 的随笔:http://www.cnblogs.com/xing901022/p/3933675.html

转载于:https://www.cnblogs.com/jiangbei/p/7482249.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(一)svn介绍

项目管理中的版本控制问题 通常软件开发由多人协作开发,如果对代码文件、文档等没有进行版本控制&#xff0c;将会出现很多问题&#xff1a; 备份多个版本&#xff0c;占用磁盘空间大解决代码冲突困难容易引发BUG难于恢复至以前正确版本无法进行权限控制项目版本发布困难什么是…

训练不出结果_训练赛惨败SKT?FPX直播透露拿冠军原因!Karsa再谈离开RNG?

都说人逢喜事精神爽&#xff0c;小凤凰拿了世界冠军当然更爽。一回国就开启了快乐直播&#xff0c;人均阴阳怪气&#xff0c;信息量巨大&#xff0c;让我们一起来康康吧&#xff01;“刘青松赢了装自己很淡定&#xff0c;其实耳机里叫得最大声。”“把林炜翔冠军奖牌给大家抽了…

linux ns级定时器_预热 | 万众期待的单片机、Linux二合一的STM32MP157开发板亮相

STM32mp157 GUI操作体验视频GUI架构简介支持多种应用场景的HMI2.0应用&#xff0c;根据应用的类型将整个UI分为五个大类&#xff1a;多媒体&#xff0c;智能家电&#xff0c;卫生医疗&#xff0c;公共服务&#xff0c;系统。均支持于100ask_stm32mp157_pro硬件开发平台&#x…

Spring加载properties文件的两种方式

在项目中如果有些参数经常需要修改&#xff0c;或者后期可能需要修改&#xff0c;那我们最好把这些参数放到properties文件中&#xff0c;源代码中读取properties里面的配置&#xff0c;这样后期只需要改动properties文件即可&#xff0c;不需要修改源代码&#xff0c;这样更加…

c++2010修复不了_汽车凹痕太小修复不了?汽车无痕修复是骗局还是技术不行?...

前段时间在网上看到一个推荐搜索说汽车凹痕太小修复不了&#xff0c;又是一个不知道从哪传出来的谣言。只听说过汽车凹陷变形太厉害修复不了的&#xff0c;没听说过凹陷的太小而修复不了的。但是我转念一想&#xff0c;能被搜索推荐说明搜遇到这个问题的人还挺多的&#xff0c;…

ege限制鼠标移动的函数_浅谈函数节流和函数防抖

什么是函数节流和函数防抖&#xff1f;下面本篇文章就来给大家浅谈一下函数节流和函数防抖。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。前言事件的触发权很多时候都属于用户&#xff0c;有些情况下会产生问题&#xff1a;向后台发…

〖Demo〗-- HAproxy配置文件操作

【HAproxy配置文件操作】 要求 1. 根据用户输入输出对应的backend下的server信息2. 可添加backend 和sever信息3. 可修改backend 和sever信息4. 可删除backend 和sever信息5. 操作配置文件前进行备份6 添加server信息时&#xff0c;如果ip已经存在则修改;如果backend不存在则创…

centos调整页面大小_这2种方法都能调整PDF文档的纸张大小

PDF文件大家都很熟悉了&#xff0c;在工作中是经常会遇到的&#xff0c;但是想对PDF文件进行修改和编辑的可能很多人都觉得为难。比如当你在阅读PDF文件时&#xff0c;发现PDF文档的页面尺寸不是自己想要的尺寸&#xff0c;要如何修改PDF的纸张大小呢&#xff1f;以下介绍2种简…

罗小黑用flash做的_中影星美好看罗小黑战记正式定档!

《罗小黑战记》定档的消息一发出&#xff0c;原微博已被转发45000次&#xff0c;大家真是太激动啦~罗小黑官博下热闹非凡在B站也同样壮观原是猫妖的小黑&#xff0c;在盗取宝珠后逃走&#xff0c;但被发现&#xff0c;而化为了一只猫&#xff0c;在街头流浪时&#xff0c;被小白…

An Overview of Cisco IOS Versions and Naming

An Overview of Cisco IOS Versions and Naming http://www.ciscopress.com/articles/article.asp?p2106547 By Sean Wilkins.Article is provided courtesy of Cisco Press.Date: Jun 28, 2013.SaveDiggDel.icio.usPrint Article Information Article Description   Versio…

ubuntu 查找qt是否安装_Ubuntu Qt 安装教程--快速下载连接(网盘)

做个笔记以便忘了&#xff08;这个笔记我用到三次了&#xff0c;现在都能记住步骤了&#xff0c;Ubuntu也装了四五次了。折腾。。。&#xff09;先下载Qt的安装包 .run文件 &#xff08;三个途径下载&#xff09;1官方&#xff1a; http://download.qt.io/archive/qt/5.12/5.12…

微信iOS收款到账语音提醒开发总结

本文来自于腾讯Bugly公众号&#xff08;weixinBugly&#xff09;&#xff0c;未经作者同意&#xff0c;请勿转载&#xff0c;原文地址&#xff1a;https://mp.weixin.qq.com/s/yYCaPMxHGT9LyRyAPewVWQ 作者&#xff1a;littleliang 一、背景 为了解决小商户老板们在频繁交易中不…

Jmeter连接Mysql

1、将mysql-connector-java-5.1.7-bin.jar放入Jmeter安装目录的bin文件夹中 2、在顶层目录<测试计划>中加载驱动 3、添加JDBC Connection Configuration 4、配置数据库信息 1&#xff09;Variable Name不能为空 2&#xff09;DataBase URL 格式为&#xff1a;jdbc:mysql:…

胃net的放大内镜_李锐:内镜下的早癌诊断

写在前面&#xff1a;这是一篇很专业的文章&#xff0c;因为很多术语对于大多数朋友来说看的不是很明白。简单讲&#xff0c;这是让消化内镜医生看的&#xff0c;说的是怎么样才能发现更多的早癌。这里需要说明一下&#xff0c;很容易造成误解&#xff1a;早癌就在那里&#xf…

单线程多线程_面试系列 redis为什么快amp;单线程amp;多线程

redis为什么这么快C语言实现&#xff0c;执行速度快纯内存操作&#xff0c;数据读写在内存中&#xff0c;异步持久化到磁盘丰富和高效的数据结构基于非阻塞的I/O多路复用机制单线程避免了上下文切换Redis单线程redis单线程的核心就是它基于一个假设&#xff1a;它在内存中执行的…

c语言float二进制输出代码_C语言学习笔记——学前知识概述

将我大一学习C语言时做的笔记拿来与大家分享&#xff0c;内容比较浅显&#xff0c;比较适合初学者&#xff0c;如有错误还请见谅&#xff0c;提出改正&#xff0c;谢谢&#xff01;前言&#xff1a;此C语言笔记是本人在自学时记录的一些重点或初学者常犯的错误&#xff0c;希望…

[Codevs] 1081 线段树练习 2 ----“分块!”

1081 线段树练习 2 时间限制: 1 s空间限制: 128000 KB题目等级 : 大师 Master题目描述 Description给你N个数&#xff0c;有两种操作 1&#xff1a;给区间[a,b]的所有数都增加X 2&#xff1a;询问第i个数是什么&#xff1f; 输入描述 Input Description第一行一个正整数n&#…

[Codevs] 1082 线段树练习3

1082 线段树练习 3 时间限制: 3 s空间限制: 128000 KB题目等级 : 大师 Master题目描述 Description给你N个数&#xff0c;有两种操作&#xff1a; 1&#xff1a;给区间[a,b]的所有数增加X 2&#xff1a;询问区间[a,b]的数的和。 输入描述 Input Description第一行一个正整数n&a…

双摄测距原理_双摄像头系列原理深度剖析

http://www.dzsc.com/data/2016-7-13/110171.html如之前文章介绍&#xff0c;双摄像头的应用主要分为&#xff1a;距离相关的应用&#xff0c;光学变焦&#xff0c;暗光补偿以及3D拍摄和建模。每种应用的原理都有些不同&#xff0c;我们就分别介绍一下相关的原理&#xff1a;从…

利用Maven快速创建一个简单的spring boot 实例

Spring Boot的好处&#xff1a;spring boot 大大减少了 使用spring的配置 和大量 xml 文件&#xff0c;并有效解决的项目之间的依赖问题&#xff0c;为想使用 spring项目 大大减轻的工作量 1.先创建一个Maven项目 2.配置pom.xml <project xmlns"http://maven.apache.or…