前期准备工作
1、MySQL数据库的准备(需要安装好MySQL5.7)
2、Elasticsearch7.x 的安装和启动
3、把数据导入到MySQL数据库,数据文件获取:
链接: https://pan.baidu.com/s/1O7kMYTmP1Lowx5RBZcUmaQ
提取码: cc8a
复制这段内容后打开百度网盘手机App,操作更方便哦
SpringBoot 环境的搭建(https://start.spring.io/)
- pom.xml导入需要的jar包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vincent</groupId> <artifactId>vincent-search</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>vincent-search</name> <description>vincent search</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <skipTests>true</skipTests> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.6.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.1.1</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.1.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source><!-- 源代码开发版本 --> <target>1.8</target><!-- java编译版本 --> <encoding>UTF8</encoding> <!-- 项目的编码 --> </configuration> </plugin> </plugins> </build> </project>
- application.yml的配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/nba?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
druid:
initial-size: 5 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
web-stat-filter:
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
stat-view-servlet: #访问监控网页的登录用户名和密码
login-username: druid
login-password: druid
server:
port: 8083
#mybatis:
# mapper-locations:
# - classpath:dao/*.xml
# - classpath*:com/**/mapper/*.xml
logging:
level:
root: info
com.vincent.search: debug
elasticsearch:
host: localhost
port: 9200
接口(需求)开发
- 将数据库数据导入到elasticsearch
- 通过姓名查找球员
- 通过国家或者球队查询球员
- 通过姓名字母查找球员
- 配置类
es配置类
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class EsConfig {
private String host;
private Integer port;
@Bean(destroyMethod = "close")
public RestHighLevelClient client() {
return new RestHighLevelClient(RestClient.builder(
new HttpHost(host, port, "http")
));
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
MyBatis配置类
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan({"com.vincent.search.dao"})
public class MyBatisConfig {
}
- 实体类
public class NBAPlayer {
private Integer id;
private String countryEn;
private String country;
private String code;
private String displayAffiliation;
private String displayName;
private Integer draft;
private String schoolType;
private String weight;
private Integer playYear;
private String jerseyNo;
private Long birthDay;
private String birthDayStr;
private String displayNameEn;
private String position;
private Double heightValue;
private String playerId;
private String teamCity;
private String teamCityEn;
private String teamName;
private String teamNameEn;
private String teamConference;
private String teamConferenceEn;
private Integer age;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getBirthDayStr() {
return birthDayStr;
}
public void setBirthDayStr(String birthDayStr) {
this.birthDayStr = birthDayStr;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDisplayAffiliation() {
return displayAffiliation;
}
public void setDisplayAffiliation(String displayAffiliation) {
this.displayAffiliation = displayAffiliation;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public Integer getDraft() {
return draft;
}
public void setDraft(Integer draft) {
this.draft = draft;
}
public String getSchoolType() {
return schoolType;
}
public void setSchoolType(String schoolType) {
this.schoolType = schoolType;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public Integer getPlayYear() {
return playYear;
}
public void setPlayYear(Integer playYear) {
this.playYear = playYear;
}
public String getCountryEn() {
return countryEn;
}
public void setCountryEn(String countryEn) {
this.countryEn = countryEn;
}
public String getTeamCityEn() {
return teamCityEn;
}
public void setTeamCityEn(String teamCityEn) {
this.teamCityEn = teamCityEn;
}
public String getTeamNameEn() {
return teamNameEn;
}
public void setTeamNameEn(String teamNameEn) {
this.teamNameEn = teamNameEn;
}
public String getTeamConference() {
return teamConference;
}
public void setTeamConference(String teamConference) {
this.teamConference = teamConference;
}
public String getTeamConferenceEn() {
return teamConferenceEn;
}
public void setTeamConferenceEn(String teamConferenceEn) {
this.teamConferenceEn = teamConferenceEn;
}
public String getJerseyNo() {
return jerseyNo;
}
public void setJerseyNo(String jerseyNo) {
this.jerseyNo = jerseyNo;
}
public Long getBirthDay() {
return birthDay;
}
public void setBirthDay(Long birthDay) {
this.birthDay = birthDay;
}
public String getDisplayNameEn() {
return displayNameEn;
}
public void setDisplayNameEn(String displayNameEn) {
this.displayNameEn = displayNameEn;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public Double getHeightValue() {
return heightValue;
}
public void setHeightValue(Double heightValue) {
this.heightValue = heightValue;
}
public String getPlayerId() {
return playerId;
}
public void setPlayerId(String playerId) {
this.playerId = playerId;
}
public String getTeamCity() {
return teamCity;
}
public void setTeamCity(String teamCity) {
this.teamCity = teamCity;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
- Dao类
import com.vincent.search.model.NBAPlayer;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface NBAPlayerDao {
@Select("select * from nba_player")
public List<NBAPlayer> selectAll();
}
- 接口定义类
import com.vincent.search.model.NBAPlayer;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface NBAPlayerService {
//新增数据
boolean addPlayer(NBAPlayer player,String id) throws IOException;
//根据id获取数据
Map<String,Object> getPlayer(String id) throws IOException;
//更新数据
boolean updatePlayer(NBAPlayer player,String id) throws IOException;
//根据id删除数据
boolean deletePlayer(String id) throws IOException;
//删除所有数据
boolean deleteAllPlayer() throws IOException;
//把mysql所有数据导入到es
boolean importAll() throws IOException;
List<NBAPlayer> searchMatch(String key, String value) throws IOException;
List<NBAPlayer> searchTerm(String key,String value) throws IOException;
List<NBAPlayer> searchMatchPrefix(String key,String value) throws IOException;
}
- 接口实现类
import com.alibaba.fastjson.JSONObject;
import com.vincent.search.dao.NBAPlayerDao;
import com.vincent.search.model.NBAPlayer;
import com.vincent.search.service.NBAPlayerService;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
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.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.naming.directory.SearchResult;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Service
public class NBAPlayerSerivceImpl implements NBAPlayerService {
@Resource
private RestHighLevelClient client;
@Resource
private NBAPlayerDao nbaPlayerDao;
private static final String NBA_INDEX = "nba_latest";
private static final int START_OFFSET = 0;
private static final int MAX_COUNT = 1000;
@Override
public boolean addPlayer(NBAPlayer player, String id) throws IOException {
IndexRequest request = new IndexRequest(NBA_INDEX).id(id).source(beanToMap(player));
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
return false;
}
@Override
public Map<String,Object> getPlayer(String id) throws IOException {
GetRequest getRequest = new GetRequest(NBA_INDEX,id);
GetResponse response = client.get(getRequest,RequestOptions.DEFAULT);
return response.getSource();
}
@Override
public boolean updatePlayer(NBAPlayer player,String id) throws IOException {
UpdateRequest request = new UpdateRequest(NBA_INDEX,id).doc(beanToMap(player));
UpdateResponse response = client.update(request,RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
return true;
}
@Override
public boolean deletePlayer(String id) throws IOException {
DeleteRequest request = new DeleteRequest(NBA_INDEX,id);
client.delete(request,RequestOptions.DEFAULT);
return true;
}
@Override
public boolean deleteAllPlayer() throws IOException {
DeleteByQueryRequest request = new DeleteByQueryRequest(NBA_INDEX);
BulkByScrollResponse response = client.deleteByQuery(request,RequestOptions.DEFAULT);
return true;
}
@Override
public boolean importAll() throws IOException {
List<NBAPlayer> list = nbaPlayerDao.selectAll();
for(NBAPlayer player: list){
addPlayer(player,String.valueOf(player.getId()));
}
return true;
}
@Override
public List<NBAPlayer> searchMatch(String key,String value) throws IOException {
SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery(key,value));
searchSourceBuilder.from(START_OFFSET);
searchSourceBuilder.size(MAX_COUNT);
searchRequest.source(searchSourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
SearchHit[] hits = response.getHits().getHits();
List<NBAPlayer> playerList = new LinkedList<>();
for(SearchHit hit: hits){
NBAPlayer player = JSONObject.parseObject(hit.getSourceAsString(),NBAPlayer.class);
playerList.add(player);
}
return playerList;
}
@Override
public List<NBAPlayer> searchTerm(String key,String value) throws IOException {
SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery(key,value));
searchSourceBuilder.from(START_OFFSET);
searchSourceBuilder.size(MAX_COUNT);
searchRequest.source(searchSourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
SearchHit[] hits = response.getHits().getHits();
List<NBAPlayer> playerList = new LinkedList<>();
for(SearchHit hit: hits){
NBAPlayer player = JSONObject.parseObject(hit.getSourceAsString(),NBAPlayer.class);
playerList.add(player);
}
return playerList;
}
@Override
public List<NBAPlayer> searchMatchPrefix(String key,String value) throws IOException {
SearchRequest searchRequest = new SearchRequest(NBA_INDEX);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.prefixQuery(key,value));
searchSourceBuilder.from(START_OFFSET);
searchSourceBuilder.size(MAX_COUNT);
searchRequest.source(searchSourceBuilder);
SearchResponse response = client.search(searchRequest,RequestOptions.DEFAULT);
System.out.println(JSONObject.toJSON(response));
SearchHit[] hits = response.getHits().getHits();
List<NBAPlayer> playerList = new LinkedList<>();
for(SearchHit hit: hits){
NBAPlayer player = JSONObject.parseObject(hit.getSourceAsString(),NBAPlayer.class);
playerList.add(player);
}
return playerList;
}
public static <T> Map<String, Object> beanToMap(T bean) {
Map<String, Object> map = new HashMap<>();
if (bean != null) {
BeanMap beanMap = BeanMap.create(bean);
for (Object key : beanMap.keySet()) {
if(beanMap.get(key) != null)
map.put(key + "", beanMap.get(key));
}
}
return map;
}
}
- controller 类
import com.vincent.search.model.NBAPlayer;
import com.vincent.search.service.NBAPlayerService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/nba")
public class NBASearchController {
@Autowired
private NBAPlayerService nbaPlayerService;
//将数据库数据导入到elasticsearch
@RequestMapping("/importAll")
public String importAll(){
try {
nbaPlayerService.importAll();
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}
//通过姓名查找球员
@RequestMapping("/searchMatch")
public List<NBAPlayer> searchMatch(@RequestParam(value = "displayNameEn", required = false) String displayNameEn) {
try {
return nbaPlayerService.searchMatch("displayNameEn",displayNameEn);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//通过国家或者球队查询球员
@RequestMapping("/searchTerm")
public List<NBAPlayer> searchTerm(@RequestParam(value = "country", required = false) String country,
@RequestParam(value = "teamName", required = false) String teamName) {
try {
if(StringUtils.isNoneBlank(country))
return nbaPlayerService.searchTerm("country",country);
else if(StringUtils.isNoneBlank(teamName))
return nbaPlayerService.searchTerm("teamName",teamName);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//通过姓名字母查找球员
@RequestMapping("/searchMatchPrefix")
public List<NBAPlayer> searchMatchPrefix(@RequestParam(value = "displayNameEn", required = false) String displayNameEn) {
try {
return nbaPlayerService.searchMatchPrefix("displayNameEn",displayNameEn);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}