package com.search.service;
import java.util.Map;
public interface SearchService {
// 通过
Map<String, Object> getDataByKeyword(String keyword, int pageSize, int pageNum);
}
package com.search.dao;
import com.search.entity.Data;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface DataDao {
// 通过 limit & offset 获取一些Data
List<Data> getSomeDatas(@Param("limit") int limit, @Param("offset") int offset);
List<Data> getDataBySplit(@Param("sql")String sql, @Param("pageSize")int pageSize, @Param("offset")int offset);
}
package com.search.dao;
import com.search.entity.Segment;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface SegmentDao {
// 查看所有分词
List<Segment> getAllSeg();
// 通过word获取一个Segment
Segment getOneSeg(String word);
}
package com.search.service.impl;
import com.huaban.analysis.jieba.JiebaSegmenter;
import com.huaban.analysis.jieba.SegToken;
import com.search.dao.DataDao;
import com.search.dao.SegmentDao;
import com.search.entity.Data;
import com.search.service.SearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class SearchServiceImpl implements SearchService {
@Autowired
private DataDao dataDao;
@Autowired
private SegmentDao segmentDao;
// 搜索业务
@Override
public Map<String, Object> getDataByKeyword(String keyword, int pageSize, int pageNum) {
int offset = pageSize * (pageNum - 1);
StringBuilder sb = new StringBuilder();
// 对输入的关键字进行分词
JiebaSegmenter segmenter = new JiebaSegmenter();
List<SegToken> segTokens = segmenter.process(keyword, JiebaSegmenter.SegMode.SEARCH);
boolean flag = true;
for (int i = 0; i < segTokens.size(); i++) {
// 获取关键词的 segment
if (segmentDao.getOneSeg(segTokens.get(i).word) == null) continue;
// segment 为空 跳过
if ("".equals(segTokens.get(i).word.trim())) continue;
// 获取segId
int segId = segmentDao.getOneSeg(segTokens.get(i).word).getId();
// 通过segId找到去哪张表查找(哪张data_segment_relation表,在建立的时候使用的,这里的100算是魔数了,不规范~)
int idx = segId % 100;
// 组合出一个sql语句:用于取各个关键词查出来的data_segment,union的方式去重
if (flag) {
sb.append("select * from data_seg_relation_").append(idx).append(" where seg_id = ").append(segId).append('\n');
flag = false;
} else {
sb.append("union").append('\n');
sb.append("select * from data_seg_relation_").append(idx).append(" where seg_id = ").append(segId).append('\n');
}
}
String sql = sb.toString();
if ("".equals(sql)) return null;
// 通过sql去获取所有的Data,详细见DataMapper.xml
// offset 是第几页搜索结果的意思
List<Data> datas = dataDao.getDataBySplit(sql, pageSize, offset);
Map<String, Object> mp = new HashMap<>();
// 返回搜索结果
mp.put("result", datas);
return mp;
}
}
-
SearchServiceImpl类继承SearchService类,可以使用它里面getDataByKeyword方法,表示通过关键字得到数据(Map中的KEY为keyword,value为要得到的数据)
-
将DataDao和SegmentDao自动装配进spring容器中
-
重写要使用的getDataByKeyword方法,offset表示截止的页数总共有多少个data,再构造一个其中没有字符且初始容量为 16 个字符的字符串构建器。
-
对输入的关键字进行分词,设置一个标识位,遍历分段器,进行获取关键词的 segment,获取segId,组合出一个sql语句:用于取各个关键词查出来的data_segment,union的方式去重
-
将组合而成的字符串转换为SQL语句,如果为"",返回null,找到截止到第几页的data,将它加入到map中进行返回