SpringBoot整合ES 实现简单项目(七)

news2024/11/8 19:29:50

一直在烂尾,对,说的就是你,楼.

上一章简单介绍了 SpringBoot 整合 ES (六), 如果没有看过,请观看上一章

这一章节老蝴蝶做一个简单的 ES 查询项目

一. pom.xml 添加依赖

        <!--引入MySql的驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--引入springboot与mybatis-plus整合的依赖。 去掉mybatis的依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--添加 druid-spring-boot-starter的依赖的依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.14</version>
        </dependency>
        <!--SpringBoot 的aop 模块-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--引入 spring-boot-starter-thymeleaf的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--添加一个webjar jquery-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--引入bootstrap-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--引入 spring-data-elasticsearch-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

二. application.yml 配置文件

server:
  port: 8081
  servlet:
    context-path: /ES
# 引入 数据库的相关配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.100.252:3306/springboot?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
  # 配置thymeleaf的相关信息
  thymeleaf:
    # 开启视图解析
    enabled: true
    #编码格式
    encoding: UTF-8
    #前缀配置
    prefix: classpath:/templates/
    # 后缀配置
    suffix: .html
    #是否使用缓存 开发环境时不设置缓存
    cache: false
    # 格式为 HTML 格式
    mode: HTML5
    # 配置类型
    servlet:
      content-type: text/html
#整合mybatis时使用的
mybatis-plus:
  # 配置 mapper文件的位置
  mapper-locations: classpath:mybatis/mapper/**/*.xml
  # 配置日志
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true #  配置别名设置
  global-config:
    db-config:
      logic-delete-field: flag   # 逻辑删除的字段
      logic-not-delete-value: 1  # 正常状态下,该字段的值
      logic-delete-value: 0      # 删除后,该字段的值
      table-underline: true # 驼峰方式转换
#分页插件
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql
elasticsearch:
  host: 127.0.0.1
  port: 9200

对应Sql 是:

# 临时指定字符集 防中文乱码
/*!40101 SET NAMES utf8 */;
CREATE TABLE `product`
(
    `id`       int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id编号',
    `title`    varchar(255)   DEFAULT NULL COMMENT '书名',
    `author`   varchar(255)   DEFAULT NULL COMMENT '作者',
    `category` varchar(255)   DEFAULT NULL COMMENT '类别',
    `price`    decimal(10, 2) DEFAULT NULL COMMENT '价格',
    `image`    varchar(255)   DEFAULT NULL COMMENT '图片地址',
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8 COMMENT ='图书产品';

三. 配置处理

三. 一 ES 配置

@Component
@ConfigurationProperties("elasticsearch")
@Data
public class EsConfig extends AbstractElasticsearchConfiguration {
	private String host;
	private Integer port;
	
	@Override
	public RestHighLevelClient elasticsearchClient() {
		RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(host, port));
		return new RestHighLevelClient(restClientBuilder);
	}
}

三.二 web 配置

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
	/**
	 * 配置静态的资源信息
	 *
	 * @param registry
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		//映射 static 目录
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
		//放置其他 业务页面资源
		registry.addResourceHandler("/**").addResourceLocations("classpath:/templates/");
	}
}

四. 实体配置

四.一 数据库实体 ProductDO

@Data
@TableName("product")
public class ProductDO {
	/**
	 * id编号
	 */
	@TableId(value = "id", type = IdType.AUTO)
	private Integer id;
	
	/**
	 * 书名
	 */
	@TableField
	private String title;
	
	/**
	 * 作者
	 */
	@TableField
	private String author;
	
	/**
	 * 类别
	 */
	@TableField
	private String category;
	
	/**
	 * 价格
	 */
	@TableField
	private BigDecimal price;
	
	/**
	 * 图片地址
	 */
	@TableField
	private String image;
}

四.二 ES 实体

@Data
@Document(indexName = "product")
public class Product {
	@Id
	private Integer id;
	@Field(type = FieldType.Text, analyzer = "ik_max_word")
	private String title;
	@Field(type = FieldType.Text, analyzer = "ik_max_word")
	private String author;
	@Field(type = FieldType.Keyword)
	private String category;
	@Field(type = FieldType.Double)
	private Double price;
	@Field(type = FieldType.Keyword, index = false)
	private String image;
}

五. Mapper 和 Repository

五.一 数据库 Mapper

@Mapper
public interface ProductDOMapper extends BaseMapper<ProductDO> {

}

五.二 ES的 Repository

@Repository
public interface ProductRepository extends ElasticsearchRepository<Product, Integer> {

}

六. Service 处理

public interface ProductDOService extends IService<ProductDO> {


}
@Service
public class ProductDOServiceImpl extends ServiceImpl<ProductDOMapper, ProductDO> implements ProductDOService {

}

七. 请求接收对象

七.一 添加时对象

@Data
public class ProductRequestVO implements Serializable {
	/**
	 * 书名
	 */
	@Field
	private String title;
	
	/**
	 * 作者
	 */
	@Field
	private String author;
	
	/**
	 * 类别
	 */
	@Field
	private String category;
	
	/**
	 * 价格
	 */
	@Field
	private BigDecimal price;
}

七.二 查询时对象

@Data
public class ProductSearchRequestVO implements Serializable {
	private String keyword;
}

七.三 响应对象

@Data
public class ProductSearchResponseVO implements Serializable {
	private Integer id;
	private String title;
	private String author;
	private String category;
	private BigDecimal price;
	private String image;
	private String showTitle;
}

八. Business

八.一 接口

public interface IProductApplication {
	
	Map<String, Object> add(ProductRequestVO productRequestVO);
	
	Map<String, Object> esSearch(ProductSearchRequestVO productSearchRequestVO);
	
	Map<String, Object> dbSearch(ProductSearchRequestVO productSearchRequestVO);
}

八.二 实现类

八.二.一 依赖注入

@Service
@Slf4j
public class ProductApplicationImpl implements IProductApplication {
	@Resource
	private ProductDOService productDOService;
	@Resource
	private ProductRepository productRepository;
	@Resource
	private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
    
}

八.二.二 添加

@Override
	public Map<String, Object> add(ProductRequestVO productRequestVO) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		ProductDO productDO = new ProductDO();
		BeanUtils.copyProperties(productRequestVO, productDO);
		productDO.setImage("默认地址");
		productDOService.save(productDO);
		
		// 进行保存到 es里面
		Product product = new Product();
		BeanUtils.copyProperties(productDO, product);
		product.setPrice(productDO.getPrice().doubleValue());
		productRepository.save(product);
		
		log.info(">>> 保存成功");
		stopWatch.stop();
		
		//获取查询时间
		long totalTimeMillis = stopWatch.getTotalTimeMillis();
		
		Map<String, Object> result = new HashMap<>(2, 1.0f);
		result.put("totalTimeMillis", totalTimeMillis);
		return result;
	}

八.二.三 ES查询

@Override
	public Map<String, Object> esSearch(ProductSearchRequestVO productSearchRequestVO) {
		// 进行查询,包括高亮显示。
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.preTags("<font color='red'>");
		highlightBuilder.postTags("</font>");
		highlightBuilder.field("title");
		
		
		FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("title", Optional.ofNullable(productSearchRequestVO.getKeyword()).orElse(""));
		fuzzyQueryBuilder.fuzziness(Fuzziness.ONE);
		NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(fuzzyQueryBuilder, null, null, highlightBuilder, null);
		
		SearchHits<Product> search = elasticsearchRestTemplate.search(nativeSearchQuery, Product.class);
		
		//{title=[Java <font color='red'>入门</font>到放弃4]}
		
		List<ProductSearchResponseVO> result = new ArrayList<>();
		// 获取查询的结果
		search.getSearchHits().forEach(
				n -> {
					
					Product content = n.getContent();
					ProductSearchResponseVO single = new ProductSearchResponseVO();
					BeanUtils.copyProperties(content, single);
					single.setPrice(BigDecimal.valueOf(content.getPrice()));
					List<String> hightFields = n.getHighlightField("title");
					if (!CollectionUtils.isEmpty(hightFields)) {
						single.setShowTitle(hightFields.get(0));
					}
					result.add(single);
				}
		);
		stopWatch.stop();
		long totalTimeMillis = stopWatch.getTotalTimeMillis();
		Map<String, Object> resultMap = new HashMap<>(2, 1.0f);
		resultMap.put("totalTimeMillis", totalTimeMillis);
		resultMap.put("data", result);
		return resultMap;
	}

八.二.四 数据库查询

@Override
	public Map<String, Object> dbSearch(ProductSearchRequestVO productSearchRequestVO) {
		
		// 进行查询,包括高亮显示。
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		List<ProductDO> list = productDOService.lambdaQuery()
				.like(StringUtils.hasText(productSearchRequestVO.getKeyword()), ProductDO::getTitle, productSearchRequestVO.getKeyword())
				.list();
		
		List<ProductSearchResponseVO> result = list.stream().map(
				n -> {
					ProductSearchResponseVO single = new ProductSearchResponseVO();
					BeanUtils.copyProperties(n, single);
					single.setPrice(n.getPrice());
					single.setShowTitle(n.getTitle());
					return single;
				}
		).collect(Collectors.toList());
		stopWatch.stop();
		long totalTimeMillis = stopWatch.getTotalTimeMillis();
		Map<String, Object> resultMap = new HashMap<>(2, 1.0f);
		resultMap.put("totalTimeMillis", totalTimeMillis);
		resultMap.put("data", result);
		return resultMap;
	}

九. Controller 处理

@RestController
@RequestMapping("/product")
public class ProductController {
	@Resource
	private IProductApplication iProductApplication;
	
	@RequestMapping("/add")
	public Map<String, Object> add(@RequestBody ProductRequestVO productRequestVO) {
		return iProductApplication.add(productRequestVO);
	}
	
	@RequestMapping("/esSearch")
	public Map<String, Object> esSearch(@RequestBody ProductSearchRequestVO productSearchRequestVO) {
		return iProductApplication.esSearch(productSearchRequestVO);
	}
	
	@RequestMapping("/dbSearch")
	public Map<String, Object> dbSearch(@RequestBody ProductSearchRequestVO productSearchRequestVO) {
		return iProductApplication.dbSearch(productSearchRequestVO);
	}
}

十. 前端页面处理

十.一 前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图书管理</title>

    <link rel="StyleSheet" href="webjars/bootstrap/3.4.1/css/bootstrap.css" type="text/css">
</head>
<body class="page-bg">
<div class="mar-hor">
    <div style="margin-top: 20px;" class="col-sm-offset-2">
        <h2>ElasticSearch 使用</h2>
    </div>
    <div id="custom-toolbar">
        <form class="form-horizontal" role="form">
            <div class="form-group">
                <label class="col-sm-2 control-label">书名:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="title"></input>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">作者:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="author"></input>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">类别:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="category" value="IT" disabled></input>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">价格:</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="price" value="40.0" disabled></input>
                </div>
            </div>
            <button id="add" type="button" class="btn btn-unified col-sm-offset-4">
                增加图书
            </button>
        </form>
    </div>
    <div>
        <h3 class="col-sm-offset-2">Title 书名查询</h3>
        <form class="form-horizontal" role="form">
            <div class="form-group">
                <label class="col-sm-2 control-label">书名关键字搜索:</label>
                <div class="col-sm-4">
                    <input type="text" class="form-control" id="keyword"></input>
                </div>
            </div>
            <br/>
            <div class="col-sm-offset-4">
                <button id="esSearch" type="button" class="btn btn-unified">
                    ES查询
                </button>
                <button id="dbSearch" type="button" class="btn btn-unified">
                    数据库查询
                </button>
            </div>
        </form>
        <div>

        </div>
    </div>
    <div style="margin-top:40px;" class="col-sm-offset-2">
        <label class="col-sm-2 control-label">花费时间:</label>
        <div class="col-sm-4">
            <input type="text" class="form-control" id="totalTimeMillis"></input>
        </div>
        <br/>
        <br/>
        <br/>
        <div class="col-sm-offset-1" style="margin-top: 30px;">
            <br/>
            <br/>
            <div id="result" class="form-control">

            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src="webjars/jquery/3.5.1/jquery.js"></script>
<script type="text/javascript" src="webjars/bootstrap/3.4.1/js/bootstrap.js"></script>
<script type="text/javascript" src="index.js"></script>

</body>
</html>

十.二 前端js

const CONTENT_PATH = "/ES/product/";
//新增员工
$("#add").click(function () {
    var title = $("#title").val();
    var author = $("#author").val();
    var category = $("#category").val();
    var price = $("#price").val();
    $.ajax({
        async: false,
        type: "post",
        url: CONTENT_PATH + "add",
        data: JSON.stringify({
            title: title,
            author: author,
            category: category,
            price: price
        }),
        dataType: "json",
        contentType: "application/json;charset=utf-8",
        success: function (data) {
            alert("新增商品成功!");
        }
    });
});

//es 查询
$("#esSearch").click(function () {
    $("#result").empty();
    $.ajax({
        async: false,
        type: "post",
        url: CONTENT_PATH + "esSearch",
        data: JSON.stringify({
            keyword: $("#keyword").val()
        }),
        dataType: "json",
        contentType: "application/json;charset=utf-8",
        success: function (data) {
            //获取信息
            $("#totalTimeMillis").val(data.totalTimeMillis);
            //获取信息.
            let dataList = data.data;
            for (let i = 0; i < dataList.length; i++) {
                $("#result").append(
                    "<div>"
                    + "书名:" + dataList[i].showTitle + "&nbsp;&nbsp;&nbsp;"
                    + "作者名:" + dataList[i].author + "&nbsp;&nbsp;&nbsp;"
                    + "类别:" + dataList[i].category + "&nbsp;&nbsp;&nbsp;"
                    + "价格:" + dataList[i].price + "<br/>"
                    + "</div>"
                )
            }
        }
    });
});

//es 查询
$("#dbSearch").click(function () {
    $("#result").empty();
    $.ajax({
        async: false,
        type: "post",
        url: CONTENT_PATH + "dbSearch",
        data: JSON.stringify({
            keyword: $("#keyword").val()
        }),
        dataType: "json",
        contentType: "application/json;charset=utf-8",
        success: function (data) {
            //获取信息
            $("#totalTimeMillis").val(data.totalTimeMillis);
            //获取信息.
            let dataList = data.data;
            for (let i = 0; i < dataList.length; i++) {
                $("#result").append(
                    "<div>"
                    + "书名:" + dataList[i].showTitle + "&nbsp;&nbsp;&nbsp;"
                    + "作者名:" + dataList[i].author + "&nbsp;&nbsp;&nbsp;"
                    + "类别:" + dataList[i].category + "&nbsp;&nbsp;&nbsp;"
                    + "价格:" + dataList[i].price + "<br/>"
                    + "</div>"
                )
            }
        }
    });
});

十一. 测试验证

输入网址: http://localhost:8081/ES/

image-20230410193905997

通过一首 进行查询

ES 查询

image-20230410193941546

数据库查询

image-20230410193956978

一个简单的 ES 项目就算是完成了.


本章节的代码放置在 github 上:


https://github.com/yuejianli/springboot/tree/develop/SpringBoot_ES2


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小林coding——图解MySQL

文章目录基础篇执行一条select语句&#xff0c;期间发生了什么&#xff1f;MySQL一行记录是怎么存储的&#xff1f;索引篇索引常见面试题什么是索引&#xff1f;索引的分类&#xff1f;小结从数据页的角度看B树为什么MySQL采用B树作为索引&#xff1f;MySQL单表不要超过2000W行…

ElasticSearch分片与Lucene Index

在ES中一个索引有一个或者多个分片构成&#xff0c;在创建索引的时候可以设置主分片和副本分片的数量&#xff0c;当主分片确定之后就不可以再修改了(因为路由需要基于这个数量来分发请求)&#xff0c;而副本分片数量随时可以修改 PUT /myIndex {"settings" : {&quo…

使用ensp软件模拟DNS服务器实验

DNS服务器介绍&#xff1a; DNS服务器&#xff08;Domain Name Server&#xff0c;域名服务器&#xff09;是进行域名和与之相对应的IP地址进行转换的服务器。它起到将人类易于记忆的域名映射到相应的机器可识别的IP地址的作用。 DNS服务器中保存了一张域名和与之相对应的IP地…

Flutter 中 Provider 基本使用

前言&#xff1a; Provider.of<XXX>(context).数据 Provider.of<XXX>(context).方法 ChangeNotifier&#xff1a;这个是真正数据&#xff08;状态&#xff09;存放的地方。我们自己创建的provider 是混入ChangeNotifier 的。 一 安装 在pub.dev 上搜索provider …

2.技巧※(0x3f:从周赛中学算法 2022下)

来自0x3f【从周赛中学算法 - 2022 年周赛题目总结&#xff08;下篇&#xff09;】&#xff1a;https://leetcode.cn/circle/discuss/WR1MJP/ 技巧指一些比较套路的算法&#xff0c;包括双指针、滑动窗口、二分&#xff08;主要指二分答案&#xff09;、前缀和、差分、前后缀分解…

TypeScript由浅到深(下篇)

目录 七、TypeScript泛型编程 泛型实现类型参数化: 泛型接口和泛型类的使用: 泛型约束: 映射类型: TypeScript条件类型&#xff08;Conditional Types&#xff09;: 在条件类型中推断&#xff08;inter&#xff09;: 分发条件类型&#xff08;Distributive Conditional …

【Java基础】day15

day15 一、为什么需要使用多线程&#xff1f; 1、资源利用率提升&#xff0c;程序处理效率提高 2、软件运行效率提升 3、使用线程可以把占据时间长的程序中的任务放到后台去处理 4、充分利用 CPU 资源&#xff0c;多核 CPU 的情况下会更高效 二、Spring Boot 的启动流程&…

搭建个人网站没有公网IP地址可以吗?

搭建网站不一定需要公网IP地址&#xff0c;甚至都不需要云服务器或虚拟主机。可以先在本地个人电脑中搭建一个网站&#xff1b;然后网站需要为公网上的其他访客提供访问&#xff1b;所以&#xff0c;需要内网穿透&#xff0c;映射公网域名进行访问。但是完全没必要&#xff0c;…

一文了解Gralde

&#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目前在某公司实习&#x1f…

python黑马程序员(单例模式工厂模式)笔记

一、单例模式 1、设计模式就是一种编程套路 使用特定的套路得到特定的效果 2、什么时单例设计模式 单例模式就是对一个类&#xff0c;只获取其唯一的类实例对象&#xff0c;持续复用它 节省内存 节省创建对象的开销 非单例模式效果&#xff1a; # 演示单例模式的效果 # 非…

chatgpt相关关键字

听了一堂chatgpt的课程&#xff0c;真假参半&#xff0c;但积累了一些关键词。不知道这些关键字会在什么时候起到作用&#xff0c;先记录下来作为灵感积累 1 自然进化的过程&#xff0c;是人选择工具&#xff0c;也是工具选择人 2 Copliot-自动编程&#xff0c;感觉适用于独立新…

安卓 Windows 通过ts链接获取m3u8视频地址进行视频下载

目录 环境&#xff1a; 解决思路及过程&#xff1a; .TS——> .m3u8 1.利用安卓视频缓存机制合成视频 1.1 找到鲨鱼浏览器目录 1.2 进入Android/data/com.zhijianzhuoyue.sharkbrowser/cashe 缓存目录 1.3 显示隐藏文件 1.4 进入可以看到两个随机生成的视频文件夹&…

傅盛“追风”GPT,猎户星空春天来了?

GPT的横空出世&#xff0c;让冷清已久的商用服务机器人市场&#xff0c;又有了“新故事”。 从技术底层逻辑而言&#xff0c;服务机器人受到这类新技术的影响会更为明显。因为抛开硬件&#xff0c;服务机器人的内核其实就是AI&#xff0c;GPT大模型的出现显然成了现阶段该产业进…

coreldraw2023安装教程及新功能讲解

coreldraw是一款非常好用的设计软件&#xff0c;功能非常强大&#xff0c;它可应用于商标设计、标志制作、模型绘制、插图描画、排版及分色输出等领域&#xff0c;因此受到了不少设计师的青睐&#xff0c; CorelDRAW2023新功能有哪些&#xff1f;CorelDRAW2023最新版本更新怎么…

SpringBoot-核心技术篇

技术掌握导图 六个大标题↓ 配置文件web开发数据访问单元测试指标指控原理解析 配置文件 1.文件类型 1.1、properties 同以前的properties用法 1.2、yaml 1.2.1、简介 YAML是 “YAML Aint Markup Language”&#xff08;YAML不是一种标记语言&#xff09;的递归缩写。在…

JumpServer部署与应用实践

JumpServer部署与介绍 文章目录JumpServer部署与介绍前言堡垒机功能特点主要主件一、在线安装二、环境访问三、堡垒机的应用&#xff08;重点&#xff09;3.1用户与用户组的创建3.2资产管理3.3账号管理3.4权限管理四、应用实践前言 Jumpserver 是一款使用 Python, Django 开发…

Su+ELK实现网络监测(1)——Suricata安装与配置

Suricata安装配置文档一、环境准备1. 基础环境安装2. 安装基础组件二、Luajit部署1. LuaJIT的安装2. 需要更新动态库三、suricata部署1. 安装相关依赖2. 下载、编译并安装suricata3. 执行4. 安装其他组件5. 修改配置文件6. 启动测试7. 安装suricata-update8. 更新规则集9. 启动…

Java多线程:线程组

线程组 可以把线程归属到某一个线程组中&#xff0c;线程组中可以有线程对象&#xff0c;也可以有线程组&#xff0c;组中还可以有线程&#xff0c;这样的组织结构有点类似于树的形式&#xff0c;如图所示&#xff1a; 线程组的作用是&#xff1a;可以批量管理线程或线程组对象…

从4k到42k,软件测试工程师的涨薪史,给我看哭了

清明节一过&#xff0c;盲猜大家已经无心上班&#xff0c;在数着日子准备过五一&#xff0c;但一想到银行卡里的余额……瞬间心情就不美丽了。 最近&#xff0c;2023年高校毕业生就业调查显示&#xff0c;本科毕业月平均起薪为5825元。调查一出&#xff0c;便有很多同学表示自己…

命令行打jar包

命令行打jar包前言jar --helpcvfmMANIFEST.MF压入class文件前言 每一个java开发者运行第一个java项目时都知道项目通常被打成jar包&#xff0c;这些jar包是由IDE工具打的&#xff0c;知其然不知其所以然。 jar --help 用help命令打印jar支持的所有参数&#xff0c;不做过多解…