您现在的位置是:首页 >学无止境 >java-springboot网站首页学无止境
java-springboot
SpringBoot
一、了解SpringBoot
- 什么是SpringBoot
- 为什么要学习SpringBoot
- SpringBoot特点
1.1 什么是SpringBoot
Spring Boot使得创建独立的,基于生产级别的基于Spring的应用程序变得容易,您可以“运行”它们。
大多数Spring Boot应用程序需要最少的Spring配置。
SpringBoot其实就是构建Spring应用程序的“脚手架”,能够帮助我们快速的搭建一个Spring项目,并且尽可能减少XML的配置,做到“开箱即用”,让程序员只需要关注业务而不是配置!
1.2 为什么要学SpringBoot
1.复杂的配置
2.管理混乱
SpringBoot让这些就变得非常简单了
1.3 SpringBoot的特点
- 基于Spring快速开发Spring项目
- 开箱即用
- 提供可用于生产的功能,例如指标,运行状况检查和外部化配置
- 无需配置
- 约定大于配置
二、快速入门
采用spring提供的初始化器创建:用SpringBoot搭建一个web工程
2.1 创建maven工程
2.2 添加依赖
所有的SpringBoot工程,都必须继承一个父工程spring-boot-starter-parent,因为在该父工程中定了大量的依赖而且已经确定了版本!这样在我们当前工程中只要添加依赖而不用设置版本号!
2.2.1 添加父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
2.2.2 添加web启动器
在SpringBoot提供了各种自动配置,我们只要引入对应启动器即可,
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.2.3 管理JDK版本
默认情况下,maven工程的JDK版本1.5,而我们开始需要的是1.8
<properties>
<java.version>1.8</java.version>
</properties>
2.3.4 添加maven打包插件
在maven打包时,能够自动将springboot依赖的所有jar包打包在一起!
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.3 启动类
该类是启动SpringBoot程序的入口!
- 注意:
今后创建所有类都应该放在启动类所在的包及其子包下
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication:说明当前是一个springboot应用程序
SpringApplication.run(Application.class, args):启动springboot程序
2.4 编写Controller
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "<h1>Hello World!</h1>";
}
}
2.5 启动测试
直接运行main方法,就表示运行springboot应用程序!
- 监听的端口默认是8080
- SpringMVC映射的路径是:/
- /hello 映射的控制器是HelloCotroller中的hello方法
也可以直接启动jar包的方式运行SpringBoot程序:
java -jar SpringBoot程序.jar
三、Java配置
在SpringBoot中已经不推荐使用XML方式进行项目配置,那么现在我们想构造一个DataSource对象,如何进行?
之前:在xml文件中进行如何配置
<bean class="xxxxx.DataSource"> <property name="driverClassName" value=""> <property name="url" value=""> <property name="username" value=""> <property name="password" value=""> </bean>
3.1 Spring发展历史
- Spring1.0时代,jdk1.5刚刚出来,spring主要使用的是xml配置
- Spring2.0时代,推出了注解方式,因为注解还不是非常完善,所以注解+xml结合
- Spring3.0时代,注解非常完善,提出采用Java配置方式替代xml
- Spring4.0时代,随着SpringBoot大行其道,完全不采用xml方式,注解和Java配置方式来实现项目的管理
3.2 Java配置
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JavaConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
@Configuration:说明当前类是一个配置类,等价于之前的xml配置文件
@Bean:创建了一个Bean对象放在Spring容器中了,默认方法名就是对象名称, 等价于之前在xml文件中定义的bean标签
@PropertySource:读取外部配置文件
@Value:注入基本类型和字符串类型的值
3.3 SpringBoot的属性注入
上面方式所面临的问题:
- @Value这种注入方式不能注入复杂的数据类型
- 我依然还需要定义大量的properties配置文件
SpringBoot定义了另外一种预定,配置文件命名为application.yml或者application.properties,SpringBoot启动时自动加载该配置文件!
在application.yml文件中定义如下配置:
jdbc:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/dbname
username: root
password: 123456
person:
name: 张晓伟
age: 17
gender: 男
hobby: 女
hobbies:
- 美女
- 大美女
- 小美女
- 帅哥
address:
province: 上海
city: 上海
获取配置文件中的参数,并封装到对应对象中去
@Configuration
public class JavaConfig2 {
@Bean
@ConfigurationProperties(prefix = "jdbc")//自动从application.yml文件中根据该前缀获取对应的配置参数,并且注入到当前方法返回的对象属性中
public DataSource dataSource2(){
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
@Bean
@ConfigurationProperties(prefix = "person")
public Person person(){
Person p = new Person();
return p;
}
}
四、SpringBoot自动配置原理(面试题)
在SpringBoot项目中只需要添加对应的“启动器”就自动完成相关配置!
4.1 SpringBootApplication注解
实现自动配置
@SpringBootConfiguration:说明当前是一个配置类@Configuration
@EnableAutoConfiguration:实现自动配置
SpringFactoriesLoader
//读取该文件META-INF/spring.factories中的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的内容,并存入在一个List集合中
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList()); }
factoryClassName=org.springframework.boot.autoconfigure.EnableAutoConfiguration
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
SpringFactoriesLoader.loadSpringFactories:从META-INF/spring.factories这个文件中将所有的内容全部读取出来,并存储在一个Map集合中
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());//返回以org.springframework.boot.autoconfigure.EnableAutoConfiguration为key的所有内容,这些都是SpringBoot实现的一些自动配置类
}
总结:
@EnableAutoConfiguration在SpringBoot启动时将EnableAutoConfiguration为key的所有配置类(META-INF/spring.factories)读取出来,每个配置类生效是有各自的条件【需要添加对应的启动器】
@ComponentScan:起始扫描包的路径
4.2 SpringApplication.run方法
启动SpringBoot程序
1.创建SpringApplication对象:准备环境,并准备初始化数据
2.调用run方法:启动springboot程序
五、SpringBoot整合MyBatis
5.1 添加依赖
<?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.itluma</groupId>
<artifactId>day57-springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
</project>
5.2 准备实体类
@Data
public class Employees implements Serializable {
private Long employeeId;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private Date hireDate;
private String jobId;
private Long salary;
private Double comm;
private Long managerId;
private Long departmentId;
private String pic;
}
5.3 MyBatis的相关配置
定义接口
package com.itluam.springboot.mapper;
import com.itluam.springboot.entity.Employees;
import java.util.List;
/**
* @author 飞鸟
* @create 2020-08-25 11:59
*/
public interface EmployeesMapper {
List<Employees> list();
}
定义映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itluam.springboot.mapper.EmployeesMapper">
<select id="list" resultType="Employees">
select * from t_employees
</select>
</mapper>
在application.yml中定义相关配置
mybatis:
configuration:
map-underscore-to-camel-case: true #是否启动驼峰标识
mapper-locations: classpath:mapper/*.xml #定义mapper映射文件的位置
type-aliases-package: com.itluam.springboot.entity #定义别名包的位置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/companydb?serverTimezone=GMT
username: root
password: 123456
type: com.zaxxer.hikari.HikariDataSource #连接池的类型,可以省略
5.4 定义Mapper接口的扫描
5.5 分页实现
添加分页启动类
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
在需要分页位置通过PageHelper.startPage(page,size)启动分页
@RequestMapping("/list3")
public PageInfo<Employees> list3(Employees employees, @RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "10") Integer size) {
PageHelper.startPage(page,size);
List<Employees> list = employeesMapper.findByWhere(employees);
PageInfo<Employees> pages = new PageInfo<>(list);
return pages;
}
六、SpringBoot整合JSP(了解)
添加依赖
<!--JSP核心引擎依赖-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
创建JSP页面
配置视图解析器的前缀和后缀
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/companydb?serverTimezone=GMT
username: root
password: 123456
type: com.zaxxer.hikari.HikariDataSource #连接池的类型,可以省略
mvc:
view:
prefix: /WEB-INF/jsp/ #配置前缀
suffix: .jsp #配置后缀
在控制器中进行页面跳转
@Controller
public class EmployeesController {
@Autowired
private EmployeesMapper employeesMapper;
@RequestMapping("/employee/list")
public String show(Employees employees, Model model, @RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) {
PageHelper.startPage(page, size);
List<Employees> list = employeesMapper.list();
PageInfo<Employees> pageInfo = new PageInfo<>(list);
model.addAttribute("pageInfo", pageInfo);
return "list";
}
}
七、SpringBoot整合Thymeleaf模板引擎
freemarker/velocity/thymeleaf
提供了关于thymeleaf模板引擎的相关自动配置过程
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
关闭thymeleaf的缓存
spring:
thymeleaf:
cache: false #关闭thymeleaf的缓存
注意:
thymeleaf默认模板存在templates目录中,而且文件的后缀名为.html,但是该页面不是一个静态页面,而是一个符合Thymeleaf模板引擎规范的模板页面,在该页面中可以使用模板的语法!
在页面中展示数据!!!!!!!!!!!!!!!!!!!!!!!
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工中心</title>
</head>
<body>
<h1>展示员工列表</h1>
<div th:each="e : ${pageInfo.list}">
<span th:text="${e.employeeId}"></span> --[[${e.firstName}]]
</div>
</body>
</html>
thymeleaf的基本语法:
- 在html标签上引入命名空间:
xmlns:th="http://www.thymeleaf.org"
- th:each遍历
- th:text显示数据
八、SpringBoot综合案例
实现客户的增加、删除、修改、查询操作!
需要将客户数据同步到es中,因为查询动作是针对于es进行。修改、添加、删除动作是针对于数据库,操作之后需要将对应的数据同步到es中!
1。需要开发两个系统,客户模块、搜索模块
2。向客户模块进行搜索时,需要将请求转发给搜索模块实现搜索过程
3。数据的同步,在客户模块中对数据进行增、删、改的同时需要将对应的数据同步到ES中
8.1 搜索模块
8.1.1 生成索引及文档数据
添加依赖
<?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.itluma</groupId>
<artifactId>day58-search</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--es-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12-beta-3</version>
</dependency>
</dependencies>
</project>
创建启动类
@SpringBootApplication
public class SearchApplication {
public static void main(String[] args) {
SpringApplication.run(SearchApplication.class, args);
}
}
定义es的配置类
@Data
@Component
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticSearchProperties {
private String host;
private Integer port;
}
@Configuration
@EnableConfigurationProperties(ElasticSearchProperties.class)
public class SearchConfig {
@Autowired
private ElasticSearchProperties elasticSearchProperties;
@Bean
public RestHighLevelClient client(){
String host = elasticSearchProperties.getHost();
Integer port = elasticSearchProperties.getPort();
HttpHost httpHost = new HttpHost(host, port);
RestClientBuilder clientBuilder = RestClient.builder(httpHost);
RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
return client;
}
}
定义es的参数
elasticsearch:
host: 192.168.136.129
port: 9200
测试生成索引和文档
package com.itluma.es;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itluma.es.entity.Customer;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
/**
* @author 飞鸟
* @create 2020-08-26 10:42
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SearchApplication.class)
public class EsTest {
@Autowired
private RestHighLevelClient client;
String index = "openapi_customer";
String type = "customer";
@Test
public void createIndex() throws IOException {
//1. 准备关于索引的settings
Settings.Builder settings = Settings.builder()
.put("number_of_shards", 5)
.put("number_of_replicas", 1);
//2. 准备关于索引的结构mappings
XContentBuilder mappings = JsonXContent.contentBuilder()
.startObject()
.startObject("properties")
.startObject("id")
.field("type","integer")
.endObject()
.startObject("username")
.field("type","keyword")
.endObject()
.startObject("password")
.field("type","keyword")
.endObject()
.startObject("nickname")
.field("type","text")
.endObject()
.startObject("money")
.field("type","long")
.endObject()
.startObject("address")
.field("type","text")
.endObject()
.startObject("state")
.field("type","integer")
.endObject()
.endObject()
.endObject();
//3. 将settings和mappings封装到一个Request对象
CreateIndexRequest request = new CreateIndexRequest(index)
.settings(settings)
.mapping(type,mappings);
//4. 通过client对象去连接ES并执行创建索引
CreateIndexResponse resp = client.indices().create(request, RequestOptions.DEFAULT);
//5. 输出
System.out.println("resp:" + resp.toString());
}
@Test
public void bulkCreateDoc() throws IOException {
//1. 准备多个json数据
Customer c1 = new Customer();
c1.setId(1);
c1.setUsername("haier");
c1.setPassword("111111");
c1.setNickname("海尔集团");
c1.setMoney(2000000L);
c1.setAddress("青岛");
c1.setState(1);
Customer c2 = new Customer();
c2.setId(2);
c2.setUsername("lianxiang");
c2.setPassword("111111");
c2.setNickname("联想");
c2.setMoney(1000000L);
c2.setAddress("联想");
c2.setState(1);
Customer c3 = new Customer();
c3.setId(3);
c3.setUsername("google");
c3.setPassword("111111");
c3.setNickname("谷歌");
c3.setMoney(1092L);
c3.setAddress("没过");
c3.setState(1);
ObjectMapper mapper = new ObjectMapper();
String json1 = mapper.writeValueAsString(c1);
String json2 = mapper.writeValueAsString(c2);
String json3 = mapper.writeValueAsString(c3);
//2. 创建Request,将准备好的数据封装进去
BulkRequest request = new BulkRequest();
request.add(new IndexRequest(index,type,c1.getId().toString()).source(json1, XContentType.JSON));
request.add(new IndexRequest(index,type,c2.getId().toString()).source(json2,XContentType.JSON));
request.add(new IndexRequest(index,type,c3.getId().toString()).source(json3,XContentType.JSON));
//3. 用client执行
BulkResponse resp = client.bulk(request, RequestOptions.DEFAULT);
//4. 输出结果
System.out.println(resp.toString());
}
}
8.1.2 实现关键词搜索
定义搜索接口
@RestController
@RequestMapping("/search")
public class SearchController {
@Autowired
private CustomerService customerService;
@GetMapping("/table")
public String table(@RequestBody Map<String,Object> param){
//1.进行查询
String result = customerService.searchCustomerByQuery(param);
//2.返回结构
return result;
}
}
根据关键词进行es搜索
package com.itluma.es.service.impl;
import com.itluma.es.entity.Customer;
import com.itluma.es.service.CustomerService;
import com.itluma.es.utils.JSON;
import com.itluma.es.vo.LayUITable;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author 飞鸟
* @create 2020-08-26 11:22
*/
@Service
public class CustomerServiceImpl implements CustomerService {
private String index = "openapi_customer";
private String type = "customer";
@Autowired
private RestHighLevelClient client;
@Override
public String searchCustomerByQuery(Map<String, Object> param) throws IOException {
//1.创建SearchRequest
SearchRequest request = new SearchRequest(index);
request.types(type);
//2.设置查询条件QueryBuilder
SearchSourceBuilder builder = new SearchSourceBuilder();
Integer page = (Integer) param.get("page");
Integer limit = (Integer) param.get("limit");
builder.from((page - 1) * limit);//设置其实位置
builder.size(limit);//设置每一页的大小
String username = (String) param.get("username");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
if (!StringUtils.isEmpty(username)) {
boolQueryBuilder.must(QueryBuilders.termQuery("username", username));
}
Object obj = param.get("state");
if (obj != null) {
boolQueryBuilder.must(QueryBuilders.termQuery("state", obj));
}
builder.query(boolQueryBuilder);
request.source(builder);
//3.执行查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.封装对象
LayUITable<Customer> layUITable = new LayUITable<>();
SearchHit[] searchHits = response.getHits().getHits();
if(searchHits!=null && searchHits.length>0){
List<Customer> list = new ArrayList<>();
//将搜索的结果存放到List集合中
for(SearchHit hit : searchHits){
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
Customer c = new Customer();
try {
//将map集合中的元素封装到c对象实体中去,要求是map中的key要和c对象的属性名称一致
BeanUtils.populate(c, sourceAsMap);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
list.add(c);
}
layUITable.setData(list);//设置当前页的数据
layUITable.setCode(0);//设置状态码
layUITable.setMsg("查询成功");//设置提示消息
layUITable.setCount(response.getHits().getTotalHits());//设置总记录个数
}
//需要将layUITable转换成JSON
return JSON.toJSON(layUITable);
}
}
es搜索的restfull接口
GET /openapi_customer/customer/_search
{
"from": 0,
"size": 1,
"query": {
"bool": {
"must": [
{
"term": {
"username": {
"value": "lianxiang"
}
}
},
{
"term": {
"state": {
"value": "1"
}
}
}
]
}
}
}
8.1.3 增加索引
添加增加索引的接口
@PostMapping("/add")
public String add(@RequestBody Customer customer) throws IOException {
boolean result = customerService.saveCustomer(customer);
return result ? "yes" : "no";
}
在业务层实现索引的添加
@Override
public boolean saveCustomer(Customer customer) throws IOException {
//1.准备json数据
String json = JSON.toJSON(customer);
//2.创建IndexRequest对象
IndexRequest request = new IndexRequest(index, type, customer.getId() + "");
request.source(json, XContentType.JSON);
//3.执行添加
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
//4.返回
if ("CREATED".equalsIgnoreCase(response.getResult().toString())) {
return true;
}
return false;
}
8.2 客户模块
8.2.1 显示搜索内容
添加项目依赖
<?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.itluma</groupId>
<artifactId>day58-customer</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
添加静态页面
定义搜索接口
@RestController
@RequestMapping("/sys/customer")
public class CustomerController {
@Autowired
private CustomerService customerService;
@GetMapping("/table")
public String table(@RequestParam Map<String,Object> map) {
String result = customerService.findCustomerByQuery(map);
return result;
}
}
在客户模块中通过RestTemplate对象向搜索服务发请求
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private RestTemplate restTemplate;
@Override
public String findCustomerByQuery(Map<String, Object> param) {
//调用day58-search工程中的localhost:8080/search/table接口
//我们需要以json格式发送数据
String json = JSON.toJSON(param);
HttpHeaders headers = new HttpHeaders();
//设置内容格式
headers.setContentType(MediaType.parseMediaType("application/json;charset=utf-8"));
//设置消息体
HttpEntity<String> entity = new HttpEntity<>(json, headers);
String result = restTemplate.postForObject("http://localhost:8080/search/table",entity, String.class);
return result;
}
}
8.2.2 实现客户添加
控制层接口
@PostMapping("/add")
public ResultVo add(Customer customer) {
try {
customerService.add(customer);
return new ResultVo(true, "添加成功!", null);
} catch (Exception e) {
e.printStackTrace();
return new ResultVo(false, e.getMessage(), null);
}
}
实现业务层
@Override
@Transactional
public void add(Customer customer) {
//1.添加数据库
Integer count = customerMapper.save(customer);
if (count != 1) {
throw new RuntimeException("添加失败!");
}
//2.发送请求到搜索服务器,实现文档的添加
//http://localhost:8080/search/add
String json = JSON.toJSON(customer);
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity entity = new HttpEntity(json, header);
String result = restTemplate.postForObject("http://localhost:8080/search/add", entity, String.class);
if(result.equalsIgnoreCase("no")){
throw new RuntimeException("索引添加失败!");
}
}
8.3 Mapper启动器的使用
Mapper启动器是一个基于JDBC的通过反射的ORM框架,提供了一些通用的CRUD操作,而且不需要定义SQL的映射文件,直接采用注解实现SQL语句
1、添加启动器的依赖
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
2、定义接口
package com.itluma.client.mapper;
import com.itluma.client.pojo.Customer;
import tk.mybatis.mapper.common.BaseMapper;
/**
* @author 飞鸟
* @create 2020-11-17 10:36
*/
public interface CustomerMapper extends BaseMapper<Customer> {
}
3、在启动类上添加Mapper接口的扫描
注意:@MapperScan这个注解所引入的包
package com.itluma.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.spring.annotation.MapperScan;
/**
* @author 飞鸟
* @create 2020-11-16 15:19
*/
@SpringBootApplication
@MapperScan("com.itluma.client.mapper")
public class CustomerApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
}
面试题分享
@SpringBootApplication
- SpringBootConfiguration->Configuartion:当前是一个配置类
- EnableAutoConfiguration:创建自动配置的对象
- AutoConfiguartionPackage:获取当前类的包及其子包
- Register:实现包的注册过程
- AutoConfigurationImportSelector:将类路径下META-INF/spring.factories文件中的xxx.xxx.xxx.EanableAutoConfiguartion为key的配置类对象构造出来,每个对象的构造都有各自的生产条件
- ComponentScan:根据包所在的位置构造对象