黑马头条-day10
文章目录
- app端文章搜索
- 1、文章搜索
- 1.1 ElasticSearch环境搭建
- 1.2 索引库创建
- ①需求分析
- ②ES导入数据场景分析
- ③创建索引和映射
- 1.3 索引数据同步
- ①app文章历史数据导入ES
- ②文章实时数据导入ES
- 1.4 文章搜索多条件复合查询
- ①关键词搜索
- ②搜索接口定义
- 2、搜索历史记录
- 2.1 需求说明
- 2.2 数据存储说明
- 2.1 异步保存搜索历史
- ①实现思路
- 2.2 查看搜索历史列表
- ①接口定义
- 2.3 删除搜索历史
- 3、联想词查询
- 需求分析
- 3.1 联想词的来源
- 3.2 联想词功能实现
- 接口定义
- 正则表达式说明
app端文章搜索
1、文章搜索
1.1 ElasticSearch环境搭建
1、启动ElasticSearch
docker start elasticsearch
2、启动Kibana
docker start kibana
3、kibana测试分词效果
1.2 索引库创建
①需求分析
- 用户输入关键词 比如
java
只要文章titile、content包含此关键词就可以搜索出来,搜索黑马程序员
能把黑马、程序员
相关都搜索出来 - 搜索的文章结果里
词条
要高亮显示 - 用户点击搜索结果任意一条可查看文章详情
②ES导入数据场景分析
③创建索引和映射
搜索结果页面展示什么内容?
- 标题
- 布局
- 封面图片
- 发布时间
- 作者名称
- 文章id
- 作者id
- 静态url
哪些字段需要索引和分词?
- 标题
- 内容
使用Kibana添加映射
索引库名称:app_info_article
PUT /app_info_article
{"mappings":{"properties":{"id":{"type":"long"},"publishTime":{"type":"date"},"layout":{"type":"integer"},"images":{"type":"keyword","index": false},"staticUrl":{"type":"keyword","index": false},"authorId": {"type": "long"},"authorName": {"type": "keyword"},"title":{"type":"text","analyzer":"ik_max_word"},"content":{"type":"text","analyzer":"ik_max_word"}}}
}
1.3 索引数据同步
①app文章历史数据导入ES
1、创建es索引和映射
前面创建过了
2、文章微服务集成es功能
导入es服务的依赖
3、编写单元测试将历史状态正常的文章数据同步到es中
数据量特别少一次导入
数据量特别多分批导入,一次一两千条
mapper接口和sql语句
/**
* 查询es需要的全部文章数据* @return*/
List<SearchArticleVo> loadSearchArticleList();
<select id="loadSearchArticleList" resultType="com.heima.model.search.vos.SearchArticleVo">select aa.*, aacc.content from ap_article aaleft join ap_article_config aac on aa.id=aac.article_idLEFT JOIN ap_article_content aacc on aa.id = aacc.article_id
where aac.is_down=0 and aac.is_delete=0</select>
测试类代码
@Autowired
private RestHighLevelClient client;
/*** 将历史文章数据导入ES中*/
@Test
public void testImportES() throws IOException {// 1. 查询所有状态正常的文章列表List<SearchArticleVo> searchArticleVoList = apArticleMapper.loadSearchArticleList();// 2. 构建BulkRequest批量请求对象BulkRequest bulkRequest = new BulkRequest();// 3. 遍历文章列表逐一添加IndexRequestfor (SearchArticleVo searchArticleVo : searchArticleVoList) {IndexRequest indexRequest = new IndexRequest("app_info_article");indexRequest.source(JSON.toJSONString(searchArticleVo), XContentType.JSON).id(String.valueOf(searchArticleVo.getId()));bulkRequest.add(indexRequest);}// 4. 执行restHighLevelClient的bulk批量插入文档请求BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);// 5. 获取响应结果数据并输出int status = bulk.status().getStatus();System.out.println("导入完成,响应状态码"+status);System.out.println("==============================================================================================");BulkItemResponse[] items = bulk.getItems();for (BulkItemResponse item : items) {String result = item.getResponse().getResult().getLowercase();System.out.println(result);}
}
②文章实时数据导入ES
跨服务调用的异步,要使用mq
生产者
kafka:bootstrap-servers: 192.168.200.130:9092producer:retries: 10key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializer
// 5. 封装es所需的数据转为JSON,生产到Kafka中
SearchArticleVo searchArticleVo = new SearchArticleVo();
BeanUtils.copyProperties(apArticle,searchArticleVo);
searchArticleVo.setStaticUrl(url);
searchArticleVo.setContent(contentStr);
String articleJson = JSON.toJSONString(searchArticleVo);
kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC,articleJson);
消费者
spring:kafka:bootstrap-servers: 192.168.200.130:9092consumer:group-id: ${spring.application.name}key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializer
@Component
@Slf4j
public class ApArticleImportESListener {@Autowiredprivate RestHighLevelClient client;@KafkaListener(topics = ArticleConstants.ARTICLE_ES_SYNC_TOPIC)public void msg (ConsumerRecord<String,String> consumerRecord) {if (consumerRecord != null) {String articleJSON = consumerRecord.value();SearchArticleVo searchArticleVo = JSON.parseObject(articleJSON, SearchArticleVo.class);IndexRequest indexRequest = new IndexRequest("app_info_article");indexRequest.source(articleJSON, XContentType.JSON).id(searchArticleVo.getId().toString());try {IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);String result = indexResponse.getResult().getLowercase();String desc = result.equals("created") ? "导入成功" : "导入失败";log.info("[异步导入APP文章到ES],导入结果:{}", desc);} catch (IOException e) {throw new RuntimeException(e);}}}
}
1.4 文章搜索多条件复合查询
①关键词搜索
②搜索接口定义
2、搜索历史记录
2.1 需求说明
- 异步保存搜索记录
- 默认查询10条搜索记录,按照搜索关键词的时间倒序
- 可以删除搜索记录
2.2 数据存储说明
用户的搜索记录,需要给每一个用户都保存一份,数据量大,要求加载速度快,通常这样的数据存储到mongodb
更合适,不建议直接存储到关系型数据库中
2.1 异步保存搜索历史
①实现思路
保存的数据量太大,不想同步影响效率,采用异步保存
@Service
@Slf4j
public class ApUserSearchServiceImpl implements ApUserSearchService {@Autowiredprivate MongoTemplate mongoTemplate;@Async("taskExecutor")@Overridepublic void insert(String keyword, Integer userId) {// 1. 查询搜索记录Query query = Query.query(Criteria.where("keyword").is(keyword).and("userId").is(userId));ApUserSearch apUserSearch = mongoTemplate.findOne(query, ApUserSearch.class);// 2. 如果搜索记录不存在,则保存搜索记录if (apUserSearch == null) {apUserSearch = new ApUserSearch();SnowflakeIdWorker isWorker = new SnowflakeIdWorker(10, 10);apUserSearch.setId(isWorker.nextId());// 使用雪花算法的值当做主键IDapUserSearch.setUserId(userId);apUserSearch.setKeyword(keyword);apUserSearch.setIsDeleted(0); // 未删除apUserSearch.setCreatedTime(new Date());apUserSearch.setUpdatedTime(new Date());mongoTemplate.save(apUserSearch);return;}// 3. 如果搜索记录存在且未删除,则更新updatedTimeif (apUserSearch.getIsDeleted() == 0) {apUserSearch.setUpdatedTime(new Date());mongoTemplate.save(apUserSearch);return;}// 4. 如果搜索记录存在且已删除,则更新为未删除及更新updateTimeapUserSearch.setIsDeleted(0);apUserSearch.setUpdatedTime(new Date());mongoTemplate.save(apUserSearch);}
}
2.2 查看搜索历史列表
①接口定义
按照当前用户,按照时间倒序查询
@Overridepublic ResponseResult findUserSearch() {// 根据条件查询搜索记录列表(条件:userId和isDeleted 结果:updateTime倒序)Query query = Query.query(Criteria.where("userId").is(ThreadLocalUtil.getUserId()).and("isDeleted").is(0)).with(Sort.by(Sort.Direction.DESC,"updateTime"));query.limit(10);List<ApUserSearch> apUserSearchList = mongoTemplate.find(query, ApUserSearch.class);return ResponseResult.okResult(apUserSearchList);}
2.3 删除搜索历史
根据搜索历史id删除
@Overridepublic ResponseResult delUserSearch(HistorySearchDto dto) {ApUserSearch apUserSearch = mongoTemplate.findById(dto.getId(), ApUserSearch.class);if (apUserSearch == null) {return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"搜索记录不存在");}// 更新记录为已删除apUserSearch.setIsDeleted(1);apUserSearch.setUpdatedTime(new Date());mongoTemplate.save(apUserSearch);return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);}
3、联想词查询
需求分析
根据用户输入的关键字展示联想词
3.1 联想词的来源
通常是网上搜索频率比较高的一些词,通常在企业中有两部分来源:
第一:自己维护搜索词
通过分析用户搜索频率较高的词,按照排名作为搜索词
第二:第三方获取
关键词规划师(百度)、5118、爱站网
3.2 联想词功能实现
接口定义
正则表达式说明
@Service
@Slf4j
public class ApAssociateWordsServiceImpl implements ApAssociateWordsService {@Autowiredprivate MongoTemplate mongoTemplate;@Overridepublic ResponseResult search(UserSearchDto dto) {// 替换一切特殊字符dto.setSearchWords(dto.getSearchWords().replaceAll("[^\u4e00-\u9fa5a-zA-z0-9]", ""));List<ApAssociateWords> apAssociateWordsList = mongoTemplate.find(Query.query(Criteria.where("associateWords").regex(".*?\\" + dto.getSearchWords() + ".*")).limit(dto.getPageSize()), ApAssociateWords.class);return ResponseResult.okResult(apAssociateWordsList);}
}
相关文章:
![](https://img-blog.csdnimg.cn/direct/033ad989a145424bb12a5bc06a884bd9.png)
黑马头条-day10
文章目录 app端文章搜索1、文章搜索1.1 ElasticSearch环境搭建1.2 索引库创建①需求分析②ES导入数据场景分析③创建索引和映射 1.3 索引数据同步①app文章历史数据导入ES②文章实时数据导入ES 1.4 文章搜索多条件复合查询①关键词搜索②搜索接口定义 2、搜索历史记录2.1 需求说…...
![](https://img-blog.csdnimg.cn/direct/c2511c41283946369f4f7e8fe65c9378.png)
C++的stack容器->基本概念、常见接口
#include<iostream> using namespace std; #include <stack> //栈stack容器常用接口 void test01() { //创建栈容器 栈容器必须符合先进后出 stack<int> s; //向栈中添加元素,叫做 压栈 入栈 s.push(10); s.push(20); s…...
![](https://www.ngui.cc/images/no-images.jpg)
VUE中引入外部jquery.min.js文件
jquery官网:https://jquery.com/ cdn链接:https://code.jquery.com/jquery-3.7.1.js <template><div class"">测试jq<div id"jq">这是一个盒子</div></div> </template><script> import…...
![](https://www.ngui.cc/images/no-images.jpg)
MongoDB聚合运算符:$avg
$avg运算符返回给定数值的平均值 $avg可用于以下阶段: $addFields阶段(从MongoDB 3.4开始可用)$bucket阶段$bucketAuto阶段$group阶段包含$expr表达式的$match阶段$project阶段$replaceRoot阶段(从MongoDB 3.4开始可用)$replaceWith阶段(从MongoDB 4.2开始可用)$s…...
![](https://img-blog.csdnimg.cn/direct/b2f06f37636f4a1594c661d5b2e3e358.png)
Web 前端 UI 框架Bootstrap简介与基本使用
Bootstrap 是一个流行的前端 UI 框架,用于快速开发响应式和移动设备优先的网页。它由 Twitter 的设计师和工程师开发,现在由一群志愿者维护。Bootstrap 提供了一套丰富的 HTML、CSS 和 JavaScript 组件,可以帮助开发者轻松地构建和定制网页和…...
![](https://www.ngui.cc/images/no-images.jpg)
【Python笔记-设计模式】惰性评价模式
一、说明 将某些对象的创建或计算延迟到真正需要它们的时候,以减少不必要的资源消耗和提高性能。 惰性评价在Python中实现也成为生成器,一般通过yield关键字实现。 (一) 解决问题 在处理大量数据时,使用惰性加载可以避免一次性加载所有数…...
![](https://www.ngui.cc/images/no-images.jpg)
每日学习总结20240221
每日总结 20240221 花自飘零水自流。一种相思,两处闲愁。 —— 李清照「一剪梅红藕香残玉簟秋」 1. stat 在Linux中,stat 是一个用于显示文件或文件系统状态的命令行工具。它提供了关于文件的详细信息,包括文件类型、权限、大小、所有者、修…...
![](https://img-blog.csdnimg.cn/direct/8b4c5a091a4846cbb8dd23b96808a537.png)
学生成绩管理系统(C语言课设 )
这个学生成绩管理系统使用C语言编写,具有多项功能以方便管理学生信息和成绩。首先从文件中读取数据到系统中,并提供了多种功能(增删改查等)选项以满足不同的需求。 学生成绩管理系统功能: 显示学生信息增加学生信息删除学生信息…...
![](https://www.ngui.cc/images/no-images.jpg)
ChatGPT提示词(最新)
它能干什么? 包括但不限于: 类别描述学术论文它可以写各种类型的学术论文,包括科技论文、文学论文、社科论文等。它可以帮助你进行研究、分析、组织思路并编写出符合学术标准的论文。创意写作它可以写小说、故事、剧本、诗歌等创意性的文学作品&#…...
![](https://img-blog.csdnimg.cn/direct/169ed4985f5e4cba98e521bfdd6b4d48.png)
算法——模拟
1. 什么是模拟算法? 官方一点来说 模拟算法(Simulation Algorithm)是一种通过模拟现实或抽象系统的运行过程来研究、分析或解决问题的方法。它通常涉及创建一个模型,模拟系统中的各种事件和过程,以便观察系统的行为&a…...
![](https://img-blog.csdnimg.cn/direct/cf209748379c4f8296b4fa8a53b49950.png)
如何进行高性能架构的设计
一、前端优化 减少请求次数页面静态化边缘计算 增加缓存控制:请求头 减少图像请求次数:多张图片变成 一张。 减少脚本的请求次数:css和js压缩,将多个文件压缩成一个文件。 二、页面静态化 三、边缘计算 后端优化 从三个方面进…...
![](https://img-blog.csdnimg.cn/direct/1a8a11fd81ce4273a21a909afc8bbb34.png)
vivado FSM Components
Vivado合成功能 •同步有限状态机(FSM)组件的特定推理能力。 •内置FSM编码策略,以适应您的优化目标。 •FSM提取默认启用。 •使用-fsm_extraction off可禁用fsm提取。 FSM描述 Vivado综合支持Moore和Mealy中的有限状态机(…...
![](https://img-blog.csdnimg.cn/direct/3b6b40080aa2435cb0671436c0183343.png)
从零开始手写mmo游戏从框架到爆炸(十五)— 命令行客户端改造
导航:从零开始手写mmo游戏从框架到爆炸(零)—— 导航-CSDN博客 到现在,我们切实需要一个客户端来完整的进行英雄选择,选择地图,打怪等等功能。所以我们需要把之前极为简陋的客户端改造一下。 首先…...
![](https://img-blog.csdnimg.cn/direct/558ed1954a094a388881c140c154d7c8.png)
Elasticsearch:什么是 kNN?
kNN - K-nearest neighbor 定义 kNN(即 k 最近邻算法)是一种机器学习算法,它使用邻近度将一个数据点与其训练并记忆的一组数据进行比较以进行预测。 这种基于实例的学习为 kNN 提供了 “惰性学习(lazy learning)” 名…...
![](https://www.ngui.cc/images/no-images.jpg)
掌握网络未来:深入解析RSVP协议及其在确保服务质量中的关键作用
第一部分:RSVP简介 资源预留协议(RSVP)是一种网络协议,用于在网络中的各个节点之间预留资源,以支持数据流的服务质量(QoS)要求。RSVP特别适用于需要固定带宽和处理延迟的应用,如视频…...
![](https://img-blog.csdnimg.cn/direct/72ea17715cb445d2b7ff3dbf0288aa5d.png)
【Linux】一站式教会:Ubuntu(无UI界面)使用apache-jmeter进行压测
🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》 🛸学无止境,不骄不躁,知行合一 文章目录 前言一、Java…...
![](https://img-blog.csdnimg.cn/direct/4dceee2c47c2403489151f78b36d4594.png#pic_center)
Howler.js:音频处理的轻量级解决方案
文章目录 Howler.js:音频处理的轻量级解决方案引言一、Howler.js简介1.1 特性概览 二、Howler.js基本使用使用详解2.1 创建一个Howl对象2.2 控制音频播放2.3 监听音频事件 三、进阶功能3.1 音频Sprites3.2 3D音频定位 四、微前端场景下的Howler.js Howler.js&#x…...
![](https://img-blog.csdnimg.cn/9f3301b11fdc4ff79124aaa3e4bc2ec1.png)
【讨论】Web端测试和App端测试的不同,如何说得更有新意?
Web 端测试和 App 端测试是针对不同平台的上的应用进行测试,Web应用和App端的应用实现方式不同,测试时的侧重点也不一样。 Web端应用和App端应用的区别: 平台兼容性 安装方式 功能和性能 用户体验 更新和维护 测试侧重点有何不同 平台…...
![](https://img-blog.csdnimg.cn/direct/4bba0ab1eea245dd87795c8e137fff9a.png#pic_center)
运维SRE-18 自动化批量管理-ansible4
12.2handles handles触发器(条件),满足条件后再做什么事情应用场景:想表示:配置文件变化,再重启服务 配置handlers之前,每次运行剧本都会重启nfs,无论配置文件是否变化。 [rootm01 /server/ans/playbook]…...
![](https://www.ngui.cc/images/no-images.jpg)
编程笔记 Golang基础 008 基本语法规则
编程笔记 Golang基础 008 基本语法规则 Go语言的基本语法规则. Go语言的基本语法规则包括但不限于以下要点: 标识符: 标识符用于命名变量、常量、类型、函数、包等。标识符由字母(a-z,A-Z)、数字(0-9&#…...
![](https://img-blog.csdnimg.cn/direct/0d33e1f398b24d4e9e37fa7aa4d1dfd6.png#pic_center)
android input命令支持多指触摸成果展示-千里马framework实战开发
hi input命令扩展提示部分 generic_x86_64:/ # input -h Error: Unknown command: -h Usage: input [<source>] <command> [<arg>...]The source…...
![](https://img-blog.csdnimg.cn/direct/ba0b2adbcd7547439c33d644153e90ce.png)
Stable Diffusion 模型分享:Indigo Furry mix(人类与野兽的混合)
本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十...
![](https://img-blog.csdnimg.cn/direct/87320b3dd56a4dff8b2d48d9c4dc384c.png)
OpenAI Sora引领AI跳舞视频新浪潮:字节跳动发布创新舞蹈视频生成框架
OpenAI的Sora已经引起广泛关注,预计今年AI跳舞视频将在抖音平台上大放异彩。下面将为您详细介绍一款字节跳动发布的AI视频动画框架。 技术定位:这款框架采用先进的diffusion技术,专注于生成人类舞蹈视频。它不仅能够实现人体动作和表情的迁移…...
![](https://img-blog.csdnimg.cn/direct/468fb6de5e9d4190868dbb2d6298fbf7.png)
[深度学习] 卷积神经网络“卷“在哪里?
🌈 博客个人主页:Chris在Coding 🎥 本文所属专栏:[深度学习] ❤️ 热门学习专栏:[Linux学习] ⏰ 我们仍在旅途 目录 1.卷积的定义 2.卷积的"卷"在哪里 3.什么又是卷积神…...
![](https://www.ngui.cc/images/no-images.jpg)
企业网络安全自查:总结报告与改进指南
按照网络和数据安全监督检查工作的要求, 现将网络信息安全自查阶段有关情况总结如下: 一、自查工作的组织开展情况 我单位始终高度重视网络与信息安全自查工作, 成立专项管理组织机构,深入学习贯彻相关文件精神,严格…...
![](https://img-blog.csdnimg.cn/img_convert/4604e1c0d63f8abfafed46866a258bb9.webp?x-oss-process=image/format,png)
怎么理解ping?这是我听过最好的回答
晚上好,我是老杨。 Ping这几个字母,已经深入网工人的骨髓了吧? 把Ping用到工作里,肯定不少人在用,但对Ping的了解和理解是不是足够深,取决了你能在工作里用到什么程度,能让它帮你到什么地步。…...
![](https://www.ngui.cc/images/no-images.jpg)
用户请求到响应可能存在的五级缓存
用户请求到响应可能存在的五级缓存 当用户在浏览器中输入URL进行访问时,请求并不是直接达到服务器,而是会经历多级缓存,以提高网络效率。本文将详细介绍用户请求到响应可能会经历的五个缓存级别:浏览器缓存,代理缓存&…...
![](https://img-blog.csdnimg.cn/img_convert/72bdb6f027febca8165e3667c0c7a8c4.png)
云图极速版限时免费活动
产品介绍 云图极速版是针对拥有攻击面管理需求的用户打造的 SaaS 应用,致力于协助用户发现并管理互联网资产攻击面。 实战数据 (2023.11.6 - 2024.2.23) 云图极速版上线 3 个月以来,接入用户 3,563 家,扫描主体 19,961 个,累计发…...
![](https://img-blog.csdnimg.cn/direct/18c1caeade4d413fa6249ec4f760ab91.png)
vue3 vuex
目录 Vuex 是什么 什么是“状态管理模式”? 什么情况下我应该使用 Vuex? 使用方法: 提交载荷(Payload) 对象风格的提交方式 使用常量替代 Mutation 事件类型 Mutation 必须是同步函数 在组件中提交 Mutation …...
![](https://www.ngui.cc/images/no-images.jpg)
Java架构师之路三、网络通信:TCP/IP协议、HTTP协议、RESTful API、WebSocket、RPC等。
目录 TCP/IP协议: HTTP协议: RESTful API: WebSocket: RPC: UDP: HTTPS: 上篇:Java架构师之路二、数据库:SQL语言、关系型数据库、非关系型数据库、数据一致性、事…...
![](/images/no-images.jpg)
顺德外贸网站建设/网络广告的收费模式有哪些
simultaneousGesture 一个包含两个手势的手势,两个手势可以同时发生,而两个手势都不在另一个手势之前。 frozen struct SimultaneousGesture<First, Second> where First : Gesture, Second : Gesture使用教程 同时手势是容器事件处理程序…...
![](/images/no-images.jpg)
佛山门户网站建设/品牌宣传推广文案
layer.load()只在火狐浏览器中正常展示,其他浏览器中都不展示。最后发现是ajax设为同步导致的,当ajax为同步时,js会停止渲染导致load弹框失效,解决方法是将ajax设为异步...
![](https://images.cnblogs.com/cnblogs_com/tearer/yycxjmyqmmdjjbf3.gif)
建设银行潍坊支行网站/平台推广策略都有哪些
来源:http://www.cnblogs.com/tearer/archive/2010/09/01/1814655.html 为项目添加强名称方法:1.右键单击项目,打开属性窗口;2.在属性窗口里选择《签名》标签,选中为程序集签名的选项,在下拉列表里选择新建,如下图所示…...
![](https://img-blog.csdnimg.cn/20190525234922679.png)
盖世汽车是模仿美国哪个网站做的/seo网站推广优化
首先,对于近日围绕着“华为、美国、google、Github”等这些主题的报道,我个人是绝对挺华为的,但会更理性一些,从技术角度出发去解决根本问题,也就是任总在访谈中提到的那些。不得不说,任总真是个伟大的企业…...
![](/images/no-images.jpg)
中企动力邮箱登陆首页/成都优化官网公司
上周,Mike和我们分享了他在数据库设计方面的部分经验和SQL的一些注意点。 一、数据库设计 1.树形结构数据 :分为邻接模型和 物化路径模型 1.1树形数据,需要解决的问题是: 如何将数据高效地以树形的形式展现给用户&…...
![](/images/no-images.jpg)
做相册网站logo/网推怎么做
转载于:https://www.cnblogs.com/6DAN_HUST/archive/2013/06/02/3114323.html...