赞
踩
- 什么是SpringBoot
- 为什么要学习SpringBoot
- SpringBoot特点
Spring Boot使得创建独立的,基于生产级别的基于Spring的应用程序变得容易,您可以“运行”它们。
大多数Spring Boot应用程序需要最少的Spring配置。
SpringBoot其实就是构建Spring应用程序的“脚手架”,能够帮助我们快速的搭建一个Spring项目,并且尽可能减少XML的配置,做到“开箱即用”,让程序员只需要关注业务而不是配置!
1.复杂的配置
2.管理混乱
SpringBoot让这些就变得非常简单了
- 基于Spring快速开发Spring项目
- 开箱即用
- 提供可用于生产的功能,例如指标,运行状况检查和外部化配置
- 无需配置
- 约定大于配置
采用spring提供的初始化器创建:用SpringBoot搭建一个web工程
所有的SpringBoot工程,都必须继承一个父工程spring-boot-starter-parent,因为在该父工程中定了大量的依赖而且已经确定了版本!这样在我们当前工程中只要添加依赖而不用设置版本号!
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
在SpringBoot提供了各种自动配置,我们只要引入对应启动器即可,
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
默认情况下,maven工程的JDK版本1.5,而我们开始需要的是1.8
<properties>
<java.version>1.8</java.version>
</properties>
在maven打包时,能够自动将springboot依赖的所有jar包打包在一起!
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
该类是启动SpringBoot程序的入口!
- 注意:
今后创建所有类都应该放在启动类所在的包及其子包下
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication:说明当前是一个springboot应用程序
SpringApplication.run(Application.class, args):启动springboot程序
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "<h1>Hello World!</h1>";
}
}
直接运行main方法,就表示运行springboot应用程序!
- 监听的端口默认是8080
- SpringMVC映射的路径是:/
- /hello 映射的控制器是HelloCotroller中的hello方法
也可以直接启动jar包的方式运行SpringBoot程序:
java -jar SpringBoot程序.jar
在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>
- 1
- 2
- 3
- 4
- 5
- 6
- Spring1.0时代,jdk1.5刚刚出来,spring主要使用的是xml配置
- Spring2.0时代,推出了注解方式,因为注解还不是非常完善,所以注解+xml结合
- Spring3.0时代,注解非常完善,提出采用Java配置方式替代xml
- Spring4.0时代,随着SpringBoot大行其道,完全不采用xml方式,注解和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:注入基本类型和字符串类型的值
上面方式所面临的问题:
- @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项目中只需要添加对应的“启动器”就自动完成相关配置!
实现自动配置
@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()); }
- 1
- 2
- 3
- 4
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:起始扫描包的路径
启动SpringBoot程序
1.创建SpringApplication对象:准备环境,并准备初始化数据
2.调用run方法:启动springboot程序
<?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>
@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; }
定义接口
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 #连接池的类型,可以省略
添加分页启动类
<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;
}
添加依赖
<!--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"; } }
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显示数据
实现客户的增加、删除、修改、查询操作!
需要将客户数据同步到es中,因为查询动作是针对于es进行。修改、添加、删除动作是针对于数据库,操作之后需要将对应的数据同步到es中!
1。需要开发两个系统,客户模块、搜索模块
2。向客户模块进行搜索时,需要将请求转发给搜索模块实现搜索过程
3。数据的同步,在客户模块中对数据进行增、删、改的同时需要将对应的数据同步到ES中
添加依赖
<?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()); } }
定义搜索接口
@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" } } } ] } } }
添加增加索引的接口
@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; }
添加项目依赖
<?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; } }
控制层接口
@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("索引添加失败!"); } }
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:根据包所在的位置构造对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。