上一篇
在Java中实现页面搜索功能,通常结合前端传递关键词,后端通过Spring Boot框架接收请求,利用JPA或MyBatis操作数据库进行模糊查询(如SQL的LIKE语句),最后将匹配结果返回页面渲染展示,核心步骤包括参数接收、数据库查询和结果返回。
在Java中实现页面搜索功能,是Web开发中的核心需求之一,下面将分步骤详细讲解两种主流实现方案:基础SQL搜索和全文搜索引擎,并提供完整代码示例,方案选择需根据数据量、性能需求和系统复杂度决定。
基础SQL搜索(适合小型项目)
适用于数据量较小(<10万条)的场景,直接通过SQL的LIKE或全文索引实现。

前端页面(HTML)
<!-- search.html --> <form action="/search" method="GET"> <input type="text" name="keyword" placeholder="输入关键词"> <button type="submit">搜索</button> </form>
后端处理(Java Servlet + JDBC)
// SearchServlet.java
@WebServlet("/search")
public class SearchServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
String keyword = request.getParameter("keyword");
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
String sql = "SELECT * FROM articles WHERE title LIKE ? OR content LIKE ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, "%" + keyword + "%");
stmt.setString(2, "%" + keyword + "%");
ResultSet rs = stmt.executeQuery();
List<Article> results = new ArrayList<>();
while (rs.next()) {
results.add(new Article(rs.getString("title"), rs.getString("content")));
}
request.setAttribute("results", results);
request.getRequestDispatcher("/results.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
结果展示页面(JSP)
<!-- results.jsp -->
<c:forEach items="${results}" var="article">
<div class="result-item">
<h3>${article.title}</h3>
<p>${article.content}</p>
</div>
</c:forEach>
️ 性能优化技巧
- 添加数据库索引:对搜索字段(如
title)创建索引 - 分页查询:使用
LIMIT offset, size避免全量加载 - MySQL全文索引(示例):
ALTER TABLE articles ADD FULLTEXT(title, content); -- 创建全文索引 SELECT * FROM articles WHERE MATCH(title, content) AGAINST('关键词');
全文搜索引擎(适合中大型项目)
当数据量超过10万条或需要复杂搜索(分词、高亮、排序)时,推荐使用Elasticsearch或Solr,以下以Elasticsearch为例:
环境准备
<!-- Maven依赖 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.0</version>
</dependency>
建立索引与写入数据
// 创建Elasticsearch客户端
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 创建索引
CreateIndexRequest request = new CreateIndexRequest("articles");
client.indices().create(request, RequestOptions.DEFAULT);
// 添加文档
IndexRequest indexRequest = new IndexRequest("articles")
.id("1")
.source("title", "Java教程", "content", "学习Java编程基础");
client.index(indexRequest, RequestOptions.DEFAULT);
实现搜索功能
// 执行搜索
SearchRequest searchRequest = new SearchRequest("articles");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建多字段查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("title", keyword))
.should(QueryBuilders.matchQuery("content", keyword));
sourceBuilder.query(boolQuery);
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 解析结果
List<Article> results = new ArrayList<>();
for (SearchHit hit : response.getHits().getHits()) {
Map<String, Object> source = hit.getSourceAsMap();
results.add(new Article(
(String) source.get("title"),
(String) source.get("content")
));
}
高级功能扩展
- 中文分词:集成IK Analyzer插件
- 结果高亮:
HighlightBuilder highlightBuilder = new HighlightBuilder() .field("content") .preTags("<em>") .postTags("</em>"); sourceBuilder.highlighter(highlightBuilder); - 相关性排序:默认按
_score降序排列
关键注意事项
-
安全性

- 使用
PreparedStatement防止SQL注入 - Elasticsearch设置
xpack.security.enabled: true
- 使用
-
性能优化
- 数据库搜索:避免
SELECT *,只查询必要字段 - Elasticsearch:合理设置分片数(建议节点数×1.5)
- 数据库搜索:避免
-
用户体验
- 前端添加搜索建议(Autocomplete)
- 搜索结果分页(PageHelper或ES的
from/size)
方案对比
| 指标 | SQL搜索 | Elasticsearch |
|---|---|---|
| 数据规模 | < 10万条 | > 10万条 |
| 搜索速度 | 较慢(全表扫描) | 极快(倒排索引) |
| 分词能力 | 基础(依赖数据库) | 强大(支持中文分词插件) |
| 开发复杂度 | 简单 | 中等(需维护索引) |
| 典型应用场景 | 后台管理系统、博客 | 电商、日志分析、大型应用 |
引用说明
- Elasticsearch官方文档:https://www.elastic.co/guide
- MySQL全文索引:https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
- JDBC防注入规范:OWASP SQL Injection Prevention
根据项目需求选择方案:小型系统用SQL搜索快速落地,高并发场景首选Elasticsearch,实际开发中需结合缓存(如Redis)和异步索引更新进一步提升性能。

