ElasticSearch集成SpringBoot与常见使用方法
一、导包

二、核对导入的ES版本
我的springboot自动导入的是7.6.2的版本,但我搭建的ES是7.7.0,为了避免出异常,需修改导入版本与ES服务版本一致

修改导入版本
查看springboot版本号使用的什么properties标签
- 打开pom文件->按住ctrl点击artifactId

在弹出的pom中按住Ctrl点击artifactId

在弹出的pom中找到elasticsearch版本标签

在项目的pom文件properties标签中添加需要导入的版本

这时回到刚才第一张图,看es就会变成了指定的版本了
三、写配置类
我是用的是RestHighLevelClient ,通过官方文档得知,它需要返回一个RestHighLevelClient 对象,并且使用完后及时关闭客户端

我的配置类
package com.rb.elasticsearch.elasticsearch.conf; import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class EsConf {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
//new HttpHost("localhost", 9200, "http"),//如果集群,传入多个地址即可
new HttpHost("192.168.100.112", 9200, "http")));//我的ES地址端口
return client;
}
}
//可以自己写一个自动装配类,将ip写入Yml文件
四、开始测试
索引操作
1.创建索引
注意:索引名字必须小写
返回值为:{"acknowledged":true,"fragment":false,"shardsAcknowledged":true}
这个返回值和elasticsearch-head创建索引返回的结果一样

代码如下:
package com.rb.elasticsearch.elasticsearch;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
@SpringBootTest
class ElasticsearchApplicationTests {
@Autowired
RestHighLevelClient restHighLevelClient;
/**
* 创建索引
* @throws IOException
*/
@Test
void createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest("java_index");
CreateIndexResponse createIndexResponse =restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(createIndexResponse));//返回值
}
}
2.查看索引是否存在
/**
* 判断索引是否存在
* @throws IOException
*/
@Test
void checkIndex() throws IOException {
GetIndexRequest getIndexRequest=new GetIndexRequest("java_index");
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(exists);//返回值true:存在 false:不存在
}
3.删除索引
acknowledged=true表示删除成功
/**
* 判断索引是否存在
* @throws IOException
*/
@Test
void delIndex() throws IOException {
DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("java_index");
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(delete));//返回值{"acknowledged":true,"fragment":false}
}
文档操作
官方举例是手拼json串,但工作中很少这么用,大多数都是一个model,然后转成json串,所以先创建一个model
package com.rb.elasticsearch.model;
import lombok.Data;
@Data
public class Users {
String name;
String remark;
int age;
}
1.添加文档
单条添加
/**
* 添加文档
*/
@Test
void putDoc() throws IOException {
if(checkIndexIsExist()){//这个方法见下方“查看文档是否存在” 如果不判断是否存在,在没有创建索引的情况下,它会创建索引
IndexRequest indexRequest=new IndexRequest(Es.INDEX_NAME);
indexRequest.id("1");
Users users=new Users();
users.setAge(15);
users.setName("张三的名字叫张三");
users.setRemark("张三的备注");
indexRequest.source(JSON.toJSONString(users), XContentType.JSON);
IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(index));
}else{
System.out.println("索引不存在");
}
}
批量添加
/**
* 批量添加
* @throws IOException
*/
@Test
void bulkAddDoc() throws IOException {
if(checkIndexIsExist()){//如果不判断是否存在,在没有创建索引的情况下,它会创建索引
BulkRequest request=new BulkRequest();
for (int i = 0; i <5 ; i++) {//循环添加五个
int id = i+1;
IndexRequest indexRequest=new IndexRequest(Es.INDEX_NAME);
Users users=new Users();
users.setRemark("李"+i+"的备注");
users.setName("李"+i+"的名字叫李"+i);
users.setAge(i);
indexRequest.source(JSON.toJSONString(users),XContentType.JSON);
indexRequest.id(String.valueOf(id));
request.add(indexRequest);
}
BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(bulk));
}
}
2.查看文档是否存在
/**
* 查看文档是否存在
* @throws IOException
*/
@Test
void checkDocIsExist() throws IOException {
if(checkIndexIsExist()){
GetRequest getRequest=new GetRequest(Es.INDEX_NAME,"1");
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);//true 存在 false 不存在
}else{
System.out.println("索引不存在");
}
}
3.修改文档
注意:我的users对象中age是int,默认值是0,如果执行下面批量修改的时候,age不修改的话会默认是0,这样会将相关索引中age字段值全部修改为0,可以使用Integer
- 单一修改
/**
* 单一修改数据
* @throws IOException
*/
@Test
void updateDoc() throws IOException {
if(checkIndexIsExist()){
UpdateRequest updateRequest=new UpdateRequest(Es.INDEX_NAME,"1");
Users users=new Users();
users.setAge(99);//只修改年龄,其他不动
updateRequest.doc(JSON.toJSONString(users),XContentType.JSON);
restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
}
}
批量修改
/**
* 批量修改数据
* @throws IOException
*/
@Test
void buleUpdateDoc() throws IOException {
if(checkIndexIsExist()){
BulkRequest bulkRequest=new BulkRequest();
for (int i = 0; i <5 ; i++) {
int id =i+1;
UpdateRequest updateRequest=new UpdateRequest(Es.INDEX_NAME,String.valueOf(id));
Users users=new Users();
users.setRemark("批量修改的备注"+i);
updateRequest.doc(JSON.toJSONString(users),XContentType.JSON);
bulkRequest.add(updateRequest);
}
restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
}
}
4.删除文档
- 单独删除
/**
* 删除文档
* @throws IOException
*/
@Test
void delDoc() throws IOException {
if(checkIndexIsExist()){//只有索引已经创建的时候才可以继续
DeleteRequest deleteRequest=new DeleteRequest("java_index","1");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete);
}
}
- 批量删除
/**
* 批量删除
* @throws IOException
*/
@Test
void buleDelDoc() throws IOException {
if(checkIndexIsExist()){
BulkRequest bulkRequest=new BulkRequest();
for (int i = 0; i <5 ; i++) {
int id =i+1;
DeleteRequest deleteRequest=new DeleteRequest(Es.INDEX_NAME);
deleteRequest.id(String.valueOf(id));
bulkRequest.add(deleteRequest);
}
restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
}
}
五.文档常用查询
单一字段查询
根据id精准查询
/**
* 根据id查询
* @throws IOException
*/
@Test
void termSelectById() throws IOException {
if(checkIndexIsExist()){
GetRequest getRequest1 = new GetRequest(Es.INDEX_NAME, "1");
//也可使用下面的方式
//GetRequest getRequest=new GetRequest(Es.INDEX_NAME);
//getRequest.id("1");
GetResponse documentFields = restHighLevelClient.get(getRequest1, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(documentFields));
}
}
根据某字段精准查询
(select * from users where age=1)
/**
* 根据某字段精准查询
* @throws IOException
*/
@Test
void termSelectByField() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.termQuery("age",1));
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search));
}
}
根据某字段模糊查询
(select * from users where remark like '%0%')
/**
* 根据某个字段模糊查询
* @throws IOException
*/
@Test
void matchSelectByField() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("remark","0"));
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
多条件查询
多条件And查询
(select * from users where name like '%因为是match,会被分词%' and age=0)
/**
* 多条件查询
* @throws IOException
*/
@Test
void multipleFieldSelectByMust() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);//定义请求
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//构建查询条件器
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//选择返回值(满足查询条件的返回true,不满足是false)
boolQueryBuilder.must(QueryBuilders.matchQuery("name","李0的名字叫李0"));//查询条件一
boolQueryBuilder.must(QueryBuilders.termQuery("age","0"));//查询条件二
System.out.println(boolQueryBuilder.must());//输出构建好的查询条件一、二
searchSourceBuilder.query(boolQueryBuilder);//将条件完善的对象放入
searchRequest.source(searchSourceBuilder);//向查询请求中放入查询条件
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//执行查询
System.out.println(JSON.toJSONString(search.getHits().getHits()));//查看结果
}
}
这一步我认为有点绕,java代码逻辑和上一篇说的命令先后逻辑是一样的,我的研究方式为逆推法(自己这么起的名字)
第一步:restHighLevelClient.search先把这个敲出来,发现这个方法需要一个SearchRequest对象
第二步:new 一个 SearchRequest 这个对象,然后命令顺序下一步是“query”,我就找到了searchSourceBuilder.query()方法,重复第一步,发现query方法需要一个BoolQueryBuilder对象
第三步:new 一个 BoolQueryBuilder这个对象,然后重复第二步,观察命令顺序,这时会传入must\must_not等信息,我就在官方提供的QueryBuilders中找到了相应的方法boolQueryBuilder.must()
- 这时,我发现一个卡点,命令上会传入一个多条件数组,java中肯定会传入一个多条件的对象,但是没有在QueryBuilders找到入参为数组的, 愁坏我了,去官网翻了一下,看到了下图,意思是可多调用多次,然后我就调用了两次

- 这时,我发现一个卡点,命令上会传入一个多条件数组,java中肯定会传入一个多条件的对象,但是没有在QueryBuilders找到入参为数组的, 愁坏我了,去官网翻了一下,看到了下图,意思是可多调用多次,然后我就调用了两次
第四步:因为第三步不确定,但是BoolQueryBuilder这个类中却有返回一个数组的方法,调用看看
System.out.println(boolQueryBuilder.must());//输出构建好的查询条件一、二
结果和我想的一样,成功了
为了加深上面的印象,我将这块命令顺序同步标记了一下java代码的位置,更方便理解:
GET users/_doc/_search //后的_search就是 SearchRequest 定义请求
{
"query":{//searchSourceBuilder.query(boolQueryBuilder);//将条件完善的对象放入
"bool":{//BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//选择返回值(满足查询条件的返回true,不满足是false)
"must":[//boolQueryBuilder.must()
{
"term"://QueryBuilders.termQuery("age","0");每调用一次就多一个查询条件
{
"name":"张三的名字叫张三"
}
} ,
{
"match"://QueryBuilders.matchQuery("name","李0的名字叫李0")
{
"age":"15"
}
}
]
}
}
}
多条件OR查询
(select * from users where remark like '%1%' or age=0) 注:%1%里的1使用了match,会被分词
/**
* 多条件查询OR
* @throws IOException
*/
@Test
void multipleFieldSelectByShould() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.should(QueryBuilders.matchQuery("remark","1"));
boolQueryBuilder.should(QueryBuilders.termQuery("age","0"));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
多条件!=查询
(select * from users where age !=0 and age !=1)
/**
* 多条件查询!=
* @throws IOException
*/
@Test
void multipleFieldSelectByMustNot() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.mustNot(QueryBuilders.termQuery("age","1"));//QueryBuilders里面的查询方式可以随意换
boolQueryBuilder.mustNot(QueryBuilders.termQuery("age","0"));//QueryBuilders里面的查询方式可以随意换
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
范围查询
(select * from users where age >=0 and age <=2)
gt 大于
gte 大于等于
lt 小于
lte 小于等于!
/**
* 根据字段范围查询
* @throws IOException
*/
@Test
void multipleFieldSelectByRange() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//再此处还可以加上面的各种查询条件↓↓↓
//再此处还可以加上面的各种查询条件↑↑↑
boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(0));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").lte(2));
searchSourceBuilder.query(boolQueryBuilder);
searchRequest.source(searchSourceBuilder);
restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
自定义字段返回
/**
* 显示指定字段
* @throws IOException
*/
@Test
void returnField() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String[] includeFields = new String[] {"name", "age"};//要显示的哪些字段
String[] excludeFields = new String[] {""};//要排除的哪些字段
searchSourceBuilder.fetchSource(includeFields,excludeFields);
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
排序
select * from users where remark like '%的备注%' and remark like '%3%' order by _score desc , age desc
查询包含“的备注”、“3”的记录(传入参数会被分词),并且按照匹配度_score这个字段排序,数值越大的匹配度越高,然后按照年龄age降序排序
/**
* 排序
* @throws IOException
*/
@Test
void sort() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest = new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("remark","的备注 3"));
searchSourceBuilder.sort("_score",SortOrder.DESC);
searchSourceBuilder.sort("age",SortOrder.DESC);
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search));
}
}
高亮查询
public String test() throws IOException {
SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
//构建查询条件start
searchSourceBuilder.query(QueryBuilders.matchQuery("name","名 叫"));//模糊搜索
//searchSourceBuilder.query(QueryBuilders.termQuery("name.keyword","李0的名字叫李0"));//精准搜索
//构建查询条件end
//高亮start
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name");
//highlightBuilder.field("name.keyword");//与上方设置的name保持一致
highlightBuilder.preTags("<mytag style='color:red'>");//自定义标签&样式
highlightBuilder.postTags("</mytag>");//自定义标签&样式
searchSourceBuilder.highlighter(highlightBuilder);
//高亮end
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
List<Map<String, Object>> list=new ArrayList();
//高亮条件封装start
for (SearchHit hit : search.getHits().getHits()) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField remark = highlightFields.get("name");
// HighlightField remark = highlightFields.get("name.keyword");//与上方设置的name保持一致
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
if(remark!=null){
Text[] fragments = remark.fragments();
String desc="";
for (Text fragment : fragments) {
desc+=fragment;
}
//sourceAsMap.put("name.keyword",desc);
sourceAsMap.put("name",desc);
list.add(sourceAsMap);
}
}
//高亮条件封装end
return JSON.toJSONString(search);
}
结果如下:

获得指定索引下满足条件的总记录数据
/**
* 查询指定索引中总共有多少条数据
* @throws IOException
*/
@Test
void getTotalCount() throws IOException {
CountRequest countRequest = new CountRequest(Es.INDEX_NAME);
//可以自定义设置上面的一些查询条件start
//可以自定义设置上面的一些查询条件end
CountResponse count = restHighLevelClient.count(countRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(count));
}
分页查询
from:从第几条数据开始(>关系,非>=)
size:查询几条数据
/**
* 分页查询
* @throws IOException
*/
@Test
void pageSelect() throws IOException {
if(checkIndexIsExist()){
SearchRequest searchRequest=new SearchRequest(Es.INDEX_NAME);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置搜索条件
searchSourceBuilder.query(QueryBuilders.matchQuery("remark","的备注"));
searchSourceBuilder.from(2);//从索引第几个开始查找,索引从0 开始
searchSourceBuilder.size(2);//显示from至from+size的数据
//例如:查询id1~2的数据,from=0 ,size=2
// 查询id3-4的数据,from=2, size=2
searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}
}
六、集成好的项目
https://files-cdn.cnblogs.com/files/rb2010/elasticsearch.zip
ElasticSearch集成SpringBoot与常见使用方法的更多相关文章
- 京东云开发者|ElasticSearch降本增效常见的方法
Elasticsearch在db_ranking 的排名又(双叒叕)上升了一位,如图1-1所示;由此可见es在存储领域已经蔚然成风且占有非常重要的地位. 随着Elasticsearch越来越受欢迎,企 ...
- elasticsearch 集成springboot
和jpa类似,很简单,很强大. pom <dependencies> <dependency> <groupId>org.springframework.boot& ...
- Oracle之常见问题诊断方法
Oracle认证:常见问题诊断方法如下: 1.TNS-12154 Error 或ORA-12154 特征:SQL*NET没有找到连接串或别名 原因1:(1)没有找到TNSNAMES.ORA文件,该文件 ...
- 100m和1000m网线的常见制作方法
100m和1000m网线的常见制作方法 100m和1000m网线的常见制作方法: 5类线(100m)的制作: a: 绿白(3).绿(6).橙白(1).蓝(4).蓝白(5).橙(2).棕白(7).棕(8 ...
- OpenStack安装部署管理中常见问题解决方法
一.网络问题-network 更多网络原理机制可以参考<OpenStack云平台的网络模式及其工作机制>. 1.1.控制节点与网络控制器区别 OpenStack平台中有两种类型的物理节点, ...
- Web Deploy发布网站及常见问题解决方法(图文)
Web Deploy发布网站及常见问题解决方法(图文) Windows2008R2+IIs7.5 +Web Deploy 3.5 Web Deploy 3.5下载安装 http://www.iis.n ...
- Quartz总结(一):Quartz集成Spring的2个方法
零.引言 关于Spring集成Quartz有2种方法: 1. JobDetailBean. 2. MethodInvokeJobDetailFactoryBean. 以下从自身使用和理解以及掌握的知识 ...
- Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制
1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...
- 【异常处理】Springboot对Controller层方法进行统一异常处理
Controller层方法,进行统一异常处理 提供两种不同的方案,如下: 方案1:使用 @@ControllerAdvice (或@RestControllerAdvice), @ExceptionH ...
随机推荐
- vite搭建vue项目-集成别名@、router、vuex、scss就是这样简单
为什么要使用vite 当我们开始构建越来越大型的应用时, 需要处理的 JavaScript 代码量也呈指数级增长. 包含数千个模块的大型项目相当普遍. 这个时候我们会遇见性能瓶颈 使用 JavaScr ...
- Spring源码-IOC部分-Xml Bean解析注册过程【3】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
- CSP2019 Day2T3 树的重心
显然如果我们直接枚举断哪条边,剩下的两颗树的重心编号非常不好求,一个常见的想法是我们反过来,考虑每个节点有多少种情况作为树的重心,计算每个点对答案的贡献. 下面我们就需要大力分类讨论了.假设我们现在考 ...
- AESUtil_1
package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher; ...
- Maven系列--"maven-compiler-plugin"的使用
万分感谢大佬:Poorzerg 原文链接:https://my.oschina.net/poorzerg/blog/206856 maven是个项目管理工具,如果我们不告诉它我们的代码要使用什么样的j ...
- PHP的这些基础知识你应该熟知
PHP变量的值类型和引用类型 四种基本类型(int,float,string,boolean)以及复合类型(array)均为值类型,变量间的赋值传递的是值,相当于创建一个副本给新变量. 对象(obje ...
- UIFont
UIFont代表字体,常见创建方法有以下几个:+ (UIFont *)systemFontOfSize:(CGFloat)fontSize; 系统默认字体+ (UIFont *)boldSystemF ...
- shell脚本三剑客之sed
shell脚本之sed命令 1.概述 2.工作流程 3.命令格式 4.具体操作 1.概述: 1.sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流 2.sed编辑器 ...
- GRC: 个人信息保护法, 个人隐私, 企业风险合规治理
声明 个人原创, 转载需注明来源 https://www.cnblogs.com/milton/p/15885344.html 个人信息保护的历史和现状 个人信息保护的立法可追溯至德国黑森州1970年 ...
- 痞子衡嵌入式:揭秘i.MXRT1060,1010上串行NOR Flash冗余程序启动设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1060,1010上串行NOR Flash冗余程序启动设计. 工业产品设计里经常会有冗余程序/备份程序设计的需求,因为在工业 ...