Lucene

2018-06-27 09:44:31来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

概述及应用场景

1、Lucene:是一个世界上最流行的开源的全文检索框架

 

   官网网址:http://lucene.apache.org

版本:7.3.3

Jdk要求:1.8

1、Lucene的作用?

   1、比如购物商城:假设通过传统的SQL语句进行书籍查询的时候 ,输入关键字‘Lucene实战’,进行查询的时候,查询字段中的数据必须有 ‘Lucene实战’这些关键字必须连在一块 这是通过sql语句搞不定

 

   2、性能问题:在对大数据进行检索时,lucene的检索速度明显快于传统的sql检索

 

   3、实现高亮效果

 

   4、 做系统的站内检索,即对一个系统内的资源进行搜索。

     BBS、BLOG中的文章搜索,网上商店中的商品搜索、OA系统中公文检索、邮件检索……

▲2、Lucene的使用

   1、解压下载的Lucene压缩包,得到如下文件(Lucene/api/lucene-7.3.0)

      analysis:分词器

      core:Lucene核心jar包

      demo:Lucene示例

      docs:Lucene使用文档

      highlighter:实现高亮效果

  2Lucene与mysql、oracle等数据库的比较

      -1、mysql、oracle等数据库需要建立自己的数据库以及表

      -2、Lucene需要建立自己的索引库

索引的创建_更新_删除

一、代码实现

/**

*添加索引(单字分词器)

*/

private static void addIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//创建分词器   单字分词器

Analyzer analyzer=new StandardAnalyzer();

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//往索引库中添加记录  Lucene中一个document实例代表数据表中的一条记录

Document document=new Document();

/*

 *StringFiled:不会对关键字进行分词

 *TextFiled:会对关键字进行分词

 *

 * Store.YES:会将数据进行存储并分词

 * Store.NO:不会将数据进行存储,不会分词,索引还是会创建。有索引,没有内容。

 */

document.add(new StringField("articalId", "0001", Store.YES));

document.add(new TextField("title", "生活不止眼前的苟且", Store.YES));

document.add(new TextField("content", "妈妈坐在门前,哼着花儿与少年,虽已隔多年。", Store.YES));

 

indexWriter.addDocument(document);

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("添加成功");

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 更新索引(单字分词器)

*/

private static void updateIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//创建分词器   单字分词器

Analyzer analyzer=new StandardAnalyzer();

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//往索引库中添加记录  Lucene中一个document实例代表数据表中的一条记录

Document document=new Document();

/*

 *StringFiled:不会对关键字进行分词

 *TextFiled:会对关键字进行分词

 *

 * Store.YES:会将数据进行存储并分词

 * Store.NO:不会将数据进行存储,不会分词,索引还是会创建。有索引,没有内容。

 */

document.add(new StringField("articalId", "0001", Store.YES));

document.add(new TextField("title", "幽幽而来", Store.YES));

document.add(new TextField("content", "这世界真好呀", Store.YES));

 

//更新的原理:先删除之前的索引,再创建新的索引====删除与添加两个动作的合集

indexWriter.updateDocument(new Term("articalId","0001"), document);

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("更新成功");

} catch (Exception e) {

e.printStackTrace();

}

}

 

/**

* 删除索引(单字分词器)

*/

private static void deleteIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//创建分词器   单字分词器

Analyzer analyzer=new StandardAnalyzer();

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//删除索引库中指定的索引

indexWriter.deleteDocuments(new Term("articalId","0001"));

 

//删除索引库中全部的索引

//indexWriter.deleteAll();

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("删除成功");

} catch (Exception e) {

e.printStackTrace();

}

}

 

▲二. 用到的API:

       a. IndexWriter : 对索引库进行CUD操作.

       b. Directory : 存储的目录.

          -- FSDirectory : 文件磁盘目录。

      -- RAMDirectory: 内存中。

       c. IndexWriterConfig: 指定创建索引需要的配置信息.

       d. Analyzer : 分词器

       e. OpenMode : 指定打开索引库的模式。

          -- OpenMode.CREATE : 创建(每次都会创建).

  -- OpenModel.APPEND :  追加模式

  -- OpenMode.CREATE_OR_APPEND: 创建或追加模式。

       f. Document: 文档

 

       g. Store : 是否存储

 

          -- YES: 存储

      -- NO: 不存储

全文检索

代码实现

/**

 * 全文检索(单字分词器)

 */

private static void searchIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//DirectoryReader的open方法指定需要读取的索引库信息,并返回相应的实例

IndexReader indexReader=DirectoryReader.open(directory);

//创建IndexSearcher实例,通过IndexSearcher实例进行全文检索

IndexSearcher   indexSearcher = new IndexSearcher(indexReader);

 

//TermQuery:指定了查询的关键字以及查询哪一个字段;不会对关键字进行分词

Query query=new TermQuery(new Term("title","生"));

  /*通过indexSearch进行检索,并指定两个参数   

    *第一个参数:封装查询的相关信息,比如查询的关键字、分词器,是否需要分词,或者需要分词的话,采取什么分词器

    *第二个参数:最多只要多少条记录

    *

    *查询数据,最终都封装在TopDocs的实例中

 */

TopDocs topDocs=indexSearcher.search(query, 100);

//通过topDocs获取匹配全部记录

ScoreDoc[] scoreDocs=topDocs.scoreDocs;

 

System.out.println("获取到的记录数"+scoreDocs.length);

 

for (int i = 0; i < scoreDocs.length; i++) {

//获取记录的id

int id=scoreDocs[i].doc;

System.out.println("id:"+id);

 

//获取文章得分

float score=scoreDocs[i].score;

System.out.println("score :"+score);

 

Document document=indexSearcher.doc(id);

String articalId= document.get("articalId");

String title= document.get("title");

String content= document.get("content");

System.out.println("articalId:"+articalId+" title:"+title+" content:"+content);

}

} catch (Exception e) {

e.printStackTrace();

}

}

分词器测试

一、代码实现

package org.crdit.com;

 

import java.util.Arrays;

 

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.CharArraySet;

import org.apache.lucene.analysis.TokenStream;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;

import org.apache.lucene.util.BytesRef;

 

/**

 * @author crd

 * 分词效果演示

 */

public class AnalyzerTest

{

public static void main(String[] args) throws Exception

{

String str = "广西桂林好玩的地方";

 

//单字分词

//Analyzer analyzer = new StandardAnalyzer();

 

// 二分法分词

//Analyzer analyzer = new CJKAnalyzer();

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

//Analyzer analyzer = new SmartChineseAnalyzer();

    

// 词库分词    智能分词器

Analyzer analyzer = new SmartChineseAnalyzer(new CharArraySet(Arrays.asList("的", "了","啊"), true));//使用自定义的停用词集合

 

// 对指定的字符串进行分词

TokenStream ts = analyzer.tokenStream(null, str);

 

ts.reset(); // 先要对tokenStream执行reset

 

// 采用循环,不断地获取下一个token

while(ts.incrementToken()) {

// 获取其中token信息

TermToBytesRefAttribute attr = ts.getAttribute(TermToBytesRefAttribute.class);

final BytesRef bytes = attr.getBytesRef();

System.out.println(bytes.utf8ToString());

}

ts.close();

}

}

 

 

▲二、分词器比较说明

英文分词器:

       a. 按空格来分词。welcome to fkjava

       b. 去掉停用词(stop word).

          is、an、a、the、of、的、地、吗、嘛、了、得、标识符号(, ; :)

       c. 大写字母转成小写字母。

 

   中文分词器:

   a、去掉停用词(stop word).

          is、an、a、the、of、的、地、吗、嘛、了、得、标识符号(, ; :)

  

   中华人民共和国,采用不同分词器效果如下

   单字分词器:(StandardAnalyzer):中|华|人|民|共|和|国

 

   二分法分词(CJKAnalyzer):中华|华人|人民|民共|共和|和国

 

   智能分词器(SmartChineseAnalyzer):中华|华人|人民|共和国

以上项目代码在code/01

智能分词器

/**

 * 添加索引

 */

private static void addIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

 

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//往索引库中添加记录  Lucene中一个document实例代表数据表中的一条记录

Document document=new Document();

/*

 *StringFiled:不会对关键字进行分词

 *TextFiled:会对关键字进行分词

 *

 * Store.YES:会将数据进行存储并分词

 * Store.NO:不会将数据进行存储,不会分词,索引还是会创建。有索引,没有内容。

 */

document.add(new StringField("articalId", "0001", Store.YES));

document.add(new TextField("title", "桂林好玩的地方", Store.YES));

document.add(new TextField("content", "可以竹筏游漓江,观美景", Store.YES));

 

indexWriter.addDocument(document);

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("添加成功");

} catch (Exception e) {

e.printStackTrace();

}

}

/**

 * 更新索引

 */

private static void updateIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

 

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//往索引库中添加记录  Lucene中一个document实例代表数据表中的一条记录

Document document=new Document();

/*

 *StringFiled:不会对关键字进行分词

 *TextFiled:会对关键字进行分词

 *

 * Store.YES:会将数据进行存储并分词

 * Store.NO:不会将数据进行存储,不会分词,索引还是会创建。有索引,没有内容。

 */

document.add(new StringField("articalId", "0001", Store.YES));

document.add(new TextField("title", "幽幽而来", Store.YES));

document.add(new TextField("content", "这世界真好呀", Store.YES));

 

//更新的原理:先删除之前的索引,再创建新的索引====删除与添加两个动作的合集

indexWriter.updateDocument(new Term("articalId","0001"), document);

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("更新成功");

} catch (Exception e) {

e.printStackTrace();

}

}

/**

 * 删除索引

 */

private static void deleteIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

 

//创建IndexWriterConfig实例  指定添加索引的配置信息

IndexWriterConfig config=new IndexWriterConfig(analyzer);

//如果索引不存在,则创建。存在,则追加。

config.setOpenMode(OpenMode.CREATE_OR_APPEND);

 

//创建IndexWriter

IndexWriter indexWriter=new IndexWriter(directory, config);

 

//删除索引库中指定的索引

indexWriter.deleteDocuments(new Term("articalId","0001"));

 

//删除索引库中全部的索引

//indexWriter.deleteAll();

 

//提交事务

indexWriter.commit();

//关闭事务

indexWriter.close();

 

System.out.println("删除成功");

} catch (Exception e) {

e.printStackTrace();

}

}

/**

 * 全文检索

 */

private static void searchIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//DirectoryReader的open方法指定需要读取的索引库信息,并返回相应的实例

IndexReader indexReader=DirectoryReader.open(directory);

//创建IndexSearcher实例,通过IndexSearcher实例进行全文检索

IndexSearcher   indexSearcher = new IndexSearcher(indexReader);

 

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

//创建QueryParser实例 通过QueryParser可以指定需要查询的字段以及分词器信息

QueryParser queryParser=new QueryParser("title", analyzer);

//通过queryParser实例得到query实例,并指定查询的关键字

Query query =queryParser.parse("桂林有哪些好玩的地方");

/*通过indexSearch进行检索,并指定两个参数   

    *第一个参数:封装查询的相关信息,比如查询的关键字、分词器,是否需要分词,或者需要分词的话,采取什么分词器

    *第二个参数:最多只要多少条记录

    *

    *查询数据,最终都封装在TopDocs的实例中

 */

TopDocs topDocs=indexSearcher.search(query, 100);

//通过topDocs获取匹配全部记录

ScoreDoc[] scoreDocs=topDocs.scoreDocs;

 

System.out.println("获取到的记录数"+scoreDocs.length);

 

for (int i = 0; i < scoreDocs.length; i++) {

//获取记录的id

int id=scoreDocs[i].doc;

System.out.println("id:"+id);

 

//获取文章得分

float score=scoreDocs[i].score;

System.out.println("score :"+score);

 

Document document=indexSearcher.doc(id);

String articalId= document.get("articalId");

String title= document.get("title");

String content= document.get("content");

System.out.println("articalId:"+articalId+" title:"+title+" content:"+content);

}

} catch (Exception e) {

e.printStackTrace();

}

}

通过MultiFieldQueryParser进行多条件查询

/**

 * 全文检索

 */

private static void searchIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//DirectoryReader的open方法指定需要读取的索引库信息,并返回相应的实例

IndexReader indexReader=DirectoryReader.open(directory);

//创建IndexSearcher实例,通过IndexSearcher实例进行全文检索

IndexSearcher   indexSearcher = new IndexSearcher(indexReader);

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

//创建QueryParser实例 通过MultiFieldQueryParser可以指定需要查询的多个字段以及分词器信息

QueryParser queryParser=new MultiFieldQueryParser(new String[]{"title","content"}, analyzer);

//通过queryParser实例得到query实例,并指定查询的关键字

Query query =queryParser.parse("桂林");

 

/*通过indexSearch进行检索,并指定两个参数   

  *第一个参数:封装查询的相关信息,比如查询的关键字、分词器,是否需要分词,或者需要分词的话,采取什么分词器

  *第二个参数:最多只要多少条记录

  *

  *查询数据,最终都封装在TopDocs的实例中

  */

TopDocs topDocs=indexSearcher.search(query, 100);

//通过topDocs获取匹配全部记录

ScoreDoc[] scoreDocs=topDocs.scoreDocs;

 

System.out.println("获取到的记录数"+scoreDocs.length);

 

for (int i = 0; i < scoreDocs.length; i++) {

//获取记录的id

int id=scoreDocs[i].doc;

System.out.println("id:"+id);

 

//获取文章得分

float score=scoreDocs[i].score;

System.out.println("score :"+score);

 

Document document=indexSearcher.doc(id);

String articalId= document.get("articalId");

String title= document.get("title");

String content= document.get("content");

System.out.println("articalId:"+articalId+" title:"+title+" content:"+content);

}

} catch (Exception e) {

e.printStackTrace();

}

}

 

条件过滤

// 广州   默认Field里包含"广州"关键词

Query query1 = queryParser.parse("广州");

// 景区 OR 广州   默认Field里包含"景区"或 "广州"

Query query2 = queryParser.parse("景区 广州");

//+白云山   +广州 (白云山  AND 广州)  AND必须为大写 默认Field里包含"广州"和"白云山"

Query query3 = queryParser.parse("广州  AND  白云山");

// title:广州         title字段中包含广州

Query query4 = queryParser.parse("title:广州");

//title:广州 -content:广州|景区 (title:广州 AND NOT content:广州|景区 )

//(title里包含广州,但content里不能包含"广州 或者 景区")

Query query5 = queryParser.parse("title:广州 -content:广州|景区");

 

高亮显示

导包:

lucene-highlighter-7.3.0.jar

lucene-memory-7.3.0.jar

/**

 * 全文检索

 */

private static void searchIndex() {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//DirectoryReader的open方法指定需要读取的索引库信息,并返回相应的实例

IndexReader indexReader=DirectoryReader.open(directory);

//创建IndexSearcher实例,通过IndexSearcher实例进行全文检索

IndexSearcher   indexSearcher = new IndexSearcher(indexReader);

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

//创建QueryParser实例 通过MultiFieldQueryParser可以指定需要查询的多个字段以及分词器信息

QueryParser queryParser=new MultiFieldQueryParser(new String[]{"title","content"}, analyzer);

//通过queryParser实例得到query实例,并指定查询的关键字

Query query =queryParser.parse("桂林");

 

//通过格式器指定咋样对关键字进行处理

Formatter formatter=new SimpleHTMLFormatter("<font color='red'>", "</font>");

//通过Scorer包装query

Scorer fragmentScorer=new QueryScorer(query);

//创建高亮器

Highlighter highlighter=new Highlighter(formatter, fragmentScorer);

 

//创建格式化片段

Fragmenter fragmenter=new SimpleFragmenter(10);

 

//将格式化片段实例与高亮器关联,最终通过高亮器对文本信息进行处理

highlighter.setTextFragmenter(fragmenter);

 

/*通过indexSearch进行检索,并指定两个参数   

  *第一个参数:封装查询的相关信息,比如查询的关键字、分词器,是否需要分词,或者需要分词的话,采取什么分词器

  *第二个参数:最多只要多少条记录

  *

  *查询数据,最终都封装在TopDocs的实例中

  */

TopDocs topDocs=indexSearcher.search(query, 100);

//通过topDocs获取匹配全部记录

ScoreDoc[] scoreDocs=topDocs.scoreDocs;

 

System.out.println("获取到的记录数"+scoreDocs.length);

 

for (int i = 0; i < scoreDocs.length; i++) {

//获取记录的id

int id=scoreDocs[i].doc;

System.out.println("id:"+id);

 

//获取文章得分

float score=scoreDocs[i].score;

System.out.println("score :"+score);

 

Document document=indexSearcher.doc(id);

 

String articalId= document.get("articalId");

//获取标题信息,高亮前title

String title= document.get("title");

//获取内容信息,高亮前的content

String content= document.get("content");

System.out.println("articalId:"+articalId+" 高亮前title:"+title+" 高亮前content:"+content);

 

/*通过高亮器对title和content进行高亮处理

*三个参数的含义:

* 第一个:分词器

* 第二个:哪一个字段进行高亮

* 第三个:需要进行高亮的文本

                *   备注:如果需要高亮的文本信息不包括查询的关键字则getBestFragment会返回null

*/

String postTitle=highlighter.getBestFragment(analyzer, "title", title);

String postContent=highlighter.getBestFragment(analyzer, "content", content);

 

System.out.println("articalId:"+articalId+" 高亮后title:"+postTitle+" 高亮后content:"+postContent);

 

}

} catch (Exception e) {

e.printStackTrace();

}

}

 

 

分页

/**

 * 全文检索

 * @param pageIndex 当前页码

 * @param pageSize 每页显示的记录数

 */

private static void searchIndex(int pageIndex,int pageSize) {

try {

//指定索引所在目录

Directory directory=FSDirectory.open(Paths.get("E:\\Lucene\\Lucene_db\\artical_tb"));

 

//DirectoryReader的open方法指定需要读取的索引库信息,并返回相应的实例

IndexReader indexReader=DirectoryReader.open(directory);

//创建IndexSearcher实例,通过IndexSearcher实例进行全文检索

IndexSearcher   indexSearcher = new IndexSearcher(indexReader);

 

//词库分词   需要导jar包   lucene-analyzers-smartcn.jar

Analyzer analyzer = new SmartChineseAnalyzer();

//创建QueryParser实例 通过MultiFieldQueryParser可以指定需要查询的多个字段以及分词器信息

QueryParser queryParser=new MultiFieldQueryParser(new String[]{"title","content"}, analyzer);

//通过queryParser实例得到query实例,并指定查询的关键字

Query query =queryParser.parse("桂林");

 

/*通过indexSearch进行检索,并指定两个参数   

  *第一个参数:封装查询的相关信息,比如查询的关键字、分词器,是否需要分词,或者需要分词的话,采取什么分词器

  *第二个参数:最多只要多少条记录

  *

  *查询数据,最终都封装在TopDocs的实例中

  */

TopDocs topDocs=indexSearcher.search(query, 100);

//通过topDocs获取匹配全部记录

ScoreDoc[] scoreDocs=topDocs.scoreDocs;

 

System.out.println("获取到的记录数"+scoreDocs.length);

 

//定义查询的起始记录号以及结束的记录号

int startSize=(pageIndex-1)*pageSize;

int endSize=pageIndex*pageSize>scoreDocs.length?scoreDocs.length:pageIndex*pageSize;

 

for (int i = startSize; i < endSize; i++) {

//获取记录的id

int id=scoreDocs[i].doc;

System.out.println("id:"+id);

 

//获取文章得分

float score=scoreDocs[i].score;

System.out.println("score :"+score);

 

Document document=indexSearcher.doc(id);

String articalId= document.get("articalId");

String title= document.get("title");

String content= document.get("content");

System.out.println("articalId:"+articalId+" title:"+title+" content:"+content);

}

} catch (Exception e) {

e.printStackTrace();

}

}

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Apache Maven(六):存储库

下一篇:Spring集成Kafka-注解,xml配置2种方式实现