2021SC@SDUSC
一、mudule-product模块架构分析
1、module-product-model 实体层
在product模块里面的model层提供了实体对象:
base包里面的BaseProduct、BaseProductCategory、BaseProductComment、BaseProductImage,是四个抽象类,四个抽象类的属性各自对应数据库中的属性,并且提供了get和set方法
Product、ProductCategory、ProductComment、ProductImage分别继承了base类中的四个类,还提供了相应的业务方法
2、module-product-search 检索接口层
mudule-product-search 这一层提供的是检索类的一个接口层,整个一层提供了一个ProductSearcher接口,因为代码量比较少,所以后面不单独进行分层分析了,直接把源代码放在这里。
package io.jpress.module.product.service.search;
import com.jfinal.plugin.activerecord.Page;
import io.jpress.module.product.model.Product;
public interface ProductSearcher {
String HIGH_LIGHT_CLASS = "search-highlight";
void addProduct(Product article);
void deleteProduct(Object id);
void updateProduct(Product article);
Page<Product> search(String keyword, int pageNum, int pageSize);
}
这一个接口提供了addProduct、deleteProduct、updateProduct、search四个方法,分别提供增加产品、删除产品、更新产品和分页查询产品CURD功能,在下面的search层都会用到这个接口。
3、module-product-search-db 普通检索层
mudule-product-search-db 这一层实现了ProductSearcher接口,使用的是aop面向切面编程技术,引入包com.jfinal.aop.Inject,利用productService服务类来进行增删改查,具体代码如下:
/**
* Copyright (c) 2016-2020, Michael Yang 杨福海 (fuhai999@gmail.com).
* <p>
* Licensed under the GNU Lesser General Public License (LGPL) ,Version 3.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.gnu.org/licenses/lgpl-3.0.txt
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jpress.module.product.searcher;
import com.jfinal.aop.Inject;
import com.jfinal.plugin.activerecord.Page;
import io.jpress.module.product.model.Product;
import io.jpress.module.product.service.ProductService;
import io.jpress.module.product.service.search.ProductSearcher;
public class DbSearcher implements ProductSearcher {
@Inject
private ProductService productService;
@Override
public void addProduct(Product article) {
// do noting
}
@Override
public void deleteProduct(Object id) {
// do noting
}
@Override
public void updateProduct(Product article) {
// do noting
}
@Override
public Page<Product> search(String keyword, int pageNum, int pageSize) {
return productService.searchIndb(keyword, pageNum, pageSize);
}
}
4、module-product-search-es ES检索层
mudule-product-search-es es检索层 检索使用的技术是ElasticSearch服务器
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。
这一层的代码量较大,可以在之后单独进行分层分析代码,这里就只放一下引入的包:
import com.jfinal.kit.LogKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Page;
import io.jboot.utils.StrUtil;
import io.jpress.JPressOptions;
import io.jpress.module.product.model.Product;
import io.jpress.module.product.service.search.ProductSearcher;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.*;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
从引入包代码可以看出,ElasticSearcher类主要使用的是elasticsearch这一个检索服务器引擎。
并且,在网上搜索资料得到,使用elasticSearch的优点有:
Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:
1、分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
2、实时分析的分布式搜索引擎。
3、可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
5、module-product-search-lucene lucene检索层
在mudule-product-search-lucene lucene检索层使用的检索技术就是在上文提到的lucene,简单介绍一下
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。
具体的lucene入门可以点此下面的链接
lucene介绍与入门使用
下面是LuceneSearcher使用到的引入包,代码也比较多,考虑将这一层单独拿出来进行代码的分析
mport com.jfinal.kit.PathKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.Page;
import io.jpress.commons.utils.CommonsUtils;
import io.jpress.module.product.model.Product;
import io.jpress.module.product.service.search.ProductSearcher;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.NIOFSDirectory;
import org.lionsoul.jcseg.ISegment;
import org.lionsoul.jcseg.analyzer.JcsegAnalyzer;
import org.lionsoul.jcseg.dic.DictionaryFactory;
import org.lionsoul.jcseg.segmenter.SegmenterConfig;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
6、mudule-product-search-opensearch 阿里云开放搜索层
mudule-product-search-opensearch 阿里云开放搜索层使用的是阿里云自助研发的OpenSearch产品
开放搜索(OpenSearch)是基于阿里巴巴自主研发的大规模分布式搜索引擎搭建的一站式智能搜索业务开发平台,目前为包括淘宝、天猫在内的阿里集团核心业务提供搜索服务支持。通过内置各行业的查询语义理解、机器学习排序算法等能力,提供充分开放的引擎能力,助力开发者快速搭建智能搜索服务。阿里云开放搜索官网
AliyunOpenSearcher类使用的类包如下图所示,代码量比较多,考虑将其单独分层进行代码分析
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.opensearch.DocumentClient;
import com.aliyun.opensearch.OpenSearchClient;
import com.aliyun.opensearch.SearcherClient;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchResult;
import com.aliyun.opensearch.sdk.generated.search.Config;
import com.aliyun.opensearch.sdk.generated.search.SearchFormat;
import com.aliyun.opensearch.sdk.generated.search.SearchParams;
import com.aliyun.opensearch.sdk.generated.search.general.SearchResult;
import com.google.common.collect.Lists;
import com.jfinal.plugin.activerecord.Page;
import io.jpress.JPressOptions;
import io.jpress.module.product.model.Product;
import io.jpress.module.product.service.search.ProductSearcher;
import java.util.ArrayList;
import java.util.List;
7、mudule-product-service和module-product-service-provider 服务层
service层提供了服务的接口,在service-provider里面的provider实现了service层提供的服务接口,在search包里面提供了补充检索的方法,在task包里面提供了关于task的方法。
在之后的技术博客会进一步给出具体的代码分析
8、module-product-web 网络层
web层的内容比较多,主要是提供了Controller层和View层,具体的代码分析在之后给出
二、Module-product-model:模型层代码分析
这一次的技术博客主要会从module-product-model 模型层进行分析,这一层的代码复杂度较低,主要是分清base类各自对应了持久层中对象的哪些属性,并且通过代码分析清楚继承了base类提供了哪些特别的方法。
以BaseProduct和Product为例
下面是Product的持久层对象属性名、属性类型和注释
BaseProduct类的代码如下:
package io.jpress.module.product.model.base;
import com.jfinal.plugin.activerecord.IBean;
import io.jpress.base.BaseOptionsModel;
/**
* Generated by JPress, do not modify this file.
*/
@SuppressWarnings("serial")
public abstract class BaseProduct<M extends BaseProduct<M>> extends BaseOptionsModel<M> implements IBean {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
public void setId(java.lang.Long id) {
set("id", id);
}
/**
* 主键ID
*/
public java.lang.Long getId() {
return getLong("id");
}
// 下面的属性的get和set方法都和数据库中实体表的数据相对应
}
BaseProduct的继承树:
说明:鉴于这一篇博客的篇幅比较大并且model层的源码分析也比较多,所以将model层的代码分析放到了下一篇博客