SpringBoot 整合 ES 进行各种高级查询搜索

news2024/11/23 15:29:06

数据准备

因为本文都是数据的搜索,所以我们需要在我们的es服务器里先插入一些数据以供我们后面使用

esUserService

public interface EsUserService extends ElasticsearchRepository<User, Integer> {

}
@RestController
public class EsController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private EsUserService esUserService;
    @Autowired
    private RestHighLevelClient client;

    private String[] names = {"诸葛亮", "曹操", "李白", "韩信", "赵云", "小乔", "狄仁杰", "李四", "诸小明", "王五"};
    private String[] infos = {"我来自中国的一个小乡村,地处湖南省", "我来自中国的一个大城市,名叫上海,人们称作魔都"
            , "我来自杭州,这是一个浪漫的城市"};

    /**
     * 准备数据
     *
     * @return
     */
    @GetMapping("prepareDate")
    public Object saveUser() {
        //添加索引mapping索引会自动创建但mapping自只用默认的这会导致分词器不生效 所以这里我们手动导入mapping
        Random random = new Random();
        List<User> users = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            User user = new User();
            user.setId(i);
            user.setName(names[random.nextInt(9)]);
            user.setAge(random.nextInt(40) + i);
            user.setInfo(infos[random.nextInt(2)]);
            users.add(user);
        }
        Iterable<User> users1 = esUserService.saveAll(users);

        return users1;
    }
}

在这里插入图片描述
下面开始我们本文的重点

准备map转实体类

由于我们需要频繁的使用map转对象,所以给大家一个比较好用的map转对象方法

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Objects;

/**
 * 利用反射讲数据转化为Object
 *
 * @param <T>
 */
public class BeanHandler<T> {
    private Class<T> clazz;

    public BeanHandler(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 讲sql 查询结果 ResultSet转化为对象
     *
     * @param rs
     * @return
     * @throws Exception
     */
    public T handle(ResultSet rs) throws Exception {
        //结果集默认指向为第一个数据的前一个
        if (rs.next()) {
            //根据传入的字节码创建传入的指定对象
            T obj = clazz.newInstance();
            //获取指定字节码信息
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
            //获取所有属性描述器
            PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                //获取结果集中对应字段名的值
                Object o = rs.getObject(pd.getName());
                //执行当前方法并传入参数
                pd.getWriteMethod().invoke(obj, o);
            }
            return obj;
        }
        return null;
    }

    /**
     * 将map 利用反射转化为对象
     *
     * @param map
     * @return
     * @throws Exception
     */
    public T handle(Map<String, Object> map) throws Exception {
        //结果集默认指向为第一个数据的前一个
        //根据传入的字节码创建传入的指定对象
        T obj = clazz.newInstance();
        BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor pd : pds) {
            Object o = map.get(pd.getName());
            if (Objects.nonNull(o)) {
                // !!!这里需要对属性类型做强制类型转化,
                o = getPropertyTypeObject(pd, o);
                // 下面的方法相当于属性的 set方法
                pd.getWriteMethod().invoke(obj, o);
            }
        }
        return obj;
    }


    /**
     * 将对应的mapValue 强转为实体类对应的类型
     *
     * @param pd
     * @param o
     * @return
     */
    public Object getPropertyTypeObject(PropertyDescriptor pd, Object o) {
        //当前属性的类型
        String name = pd.getPropertyType().getName();
        name = name.substring(name.lastIndexOf(".") + 1);
        switch (name) {
            case "String":
                o = String.valueOf(o);
                break;
            case "Long":
                o = Long.valueOf(String.valueOf(o));
                break;
            case "Double":
                o = Double.valueOf(String.valueOf(o));
                break;
            case "Integer":
                o = Integer.valueOf(String.valueOf(o));
                break;
            case "BigDecimal":
                o = new BigDecimal(String.valueOf(o));
                break;
        }
        return o;
    }

}

单条件精确查询

@PostMapping("singleConditionPreciseQuery")
public Object singleConditionPreciseQuery(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchQuery("name", query));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	List<User> users = new ArrayList<>();
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

范围查询

/**
 * 范围查询
 * 包括from、to
 *
 * @return
 */
@PostMapping("rangeSearch1")
public Object rangeSearch1(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").from(from).to(to));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 范围查询
 * 不包括from、to
 *
 * @return
 */
@PostMapping("rangeSearch2")
public Object rangeSearch2(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").from(from, false).to(to, false));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 范围查询
 * lt:小于,gt:大于
 *
 * @return
 */
@PostMapping("rangeSearch3")
public Object rangeSearch3(@RequestParam(value = "from") int from, @RequestParam(value = "to") int to) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.rangeQuery("age").lt(to).gt(from));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

在这里插入图片描述

模糊查询,支持通配符

/**
 * 模糊查询,支持通配符
 *
 * @return
 */
@PostMapping("vagueSearch")
public Object vagueSearch(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.wildcardQuery("name", query));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

/**
 * 不使用通配符的模糊查询,左右匹配
 *
 * @return
 */
@PostMapping("vagueSearch1")
public Object vagueSearch1(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.queryStringQuery(query).field("name"));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}
/**
 * 多字段模糊查询
 *
 * @return
 */
@PostMapping("vagueSearch2")
public Object vagueSearch2(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.multiMatchQuery(query, "name", "info"));

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

排序

/**
 * 排序
 *
 * @return
 */
@PostMapping("sortSearch")
public Object sortSearch(@RequestParam(value = "query") String query) throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.multiMatchQuery(query, "name", "info"))
			.sort("age", SortOrder.ASC);//按照年龄正序

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

精确统计筛选文档数

/**
 * 精确统计筛选文档数,查询性能有所降低
 *
 * @return
 */
@PostMapping("countSearch")
public Object countSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.trackTotalHits(true);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	return response;
}

设置源字段过滤返回

/**
 * 设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
 *  * @return
 */
@PostMapping("filterSearch")
public Object filterSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.fetchSource(new String[]{"name", "age"}, new String[]{"id", "info"});
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

在这里插入图片描述

通过上图的结果我们也可以看出:

  • 第一个参数结果集包括哪些字段
  • 第二个参数表示结果集不包括哪些字段

在这里插入图片描述

根据 id 精确匹配

/**
 * 根据Id精准查询
 *
 * @return
 */
@PostMapping("searchByIds")
public Object searchByIds(@RequestBody Map<String, Object> params) throws Exception {
	List<Integer> ids = (List<Integer>) params.get("ids");
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.termsQuery("_id", ids));
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

matchAllQuery 搜索全部

/**
 * matchAllQuery 搜索全部
 *
 * @return
 */
@PostMapping("martchAllQuery")
public Object martchAllQuery() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchAllQuery());
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

match 搜索匹配

/**
 * match 搜索匹配
 *
 * @return
 */
@PostMapping("martch")
public Object martch(@RequestBody Map<String, Object> params) throws Exception {
	List<String> querys = (List<String>) params.get("querys");
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.matchQuery("name", querys));
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

bool组合查询

/**
* match 搜索匹配
*
* @return
*/
@PostMapping("martch")
public Object martch(@RequestBody Map<String, Object> params) throws Exception {
List<String> querys = (List<String>) params.get("querys");
// 创建请求
SearchSourceBuilder builder = new SearchSourceBuilder()
		.query(QueryBuilders.matchQuery("name", querys));
//搜索
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
searchRequest.types("_doc");    /**
 * bool组合查询
 *
 * @return
 */
@PostMapping("boolSearch")
public Object boolSearch(@RequestBody Map<String, Object> params) throws Exception {
	List<String> queryNames = (List<String>) params.get("names");
	int maxAge = (int) params.get("maxAge");
	int minAge = (int) params.get("minAge");

	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.termsQuery("name", queryNames));
	boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(maxAge).gte(minAge));
	builder.query(boolQueryBuilder);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

searchRequest.source(builder);
// 执行请求
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
// 执行请求
List<User> users = new ArrayList<>();
for (SearchHit searchHit : response.getHits().getHits()) {
	Map<String, Object> map = searchHit.getSourceAsMap();
	BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
	User user = beanHandler.handle(map);
	users.add(user);
}
// 解析查询结果
return users;
}

在这里插入图片描述

nested类型嵌套查询

有时候,我们需要查询一个对象内部类的值,发现通过平时的查询查询不到数据,这时DSL(Domain Specific language,即特定领域专用语言)出场了!

elasticsearch中的内部对象无法按预期工作,这里的问题是elasticsearch(lucene)使用的库没有内部对象的概念,因此内部对象被扁平化为一个简单的字段名称和值列表。

/**
 * nested类型嵌套查询
 *
 * @return
 */
@PostMapping("nestedSearch")
public Object nestedSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	//条件查询
	BoolQueryBuilder mainBool=new BoolQueryBuilder();
	mainBool.must(QueryBuilders.matchQuery("name", "赵六"));
	//nested类型嵌套查询
	BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.matchQuery("user.name", "A"));
	boolQueryBuilder.must(QueryBuilders.matchQuery("user.info", "浦东"));
	NestedQueryBuilder nested = QueryBuilders.nestedQuery("user",boolQueryBuilder, ScoreMode.None);
	mainBool.must(nested);
	builder.query(mainBool);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

多条件查询 + 排序 + 分页

/**
 * 多条件查询 + 排序 + 分页
 *
 * @return
 */
@PostMapping("multiConditionSearch")
public Object multiConditionSearch() throws Exception {
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder();
	//条件搜索
	BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
	boolQueryBuilder.must(QueryBuilders.matchQuery
	("name", "张").operator(Operator.AND);//需要 满足所有字段);
	boolQueryBuilder.must(QueryBuilders.rangeQuery("age").lte(30).gte(20));
	builder.query(boolQueryBuilder);
	//结果集合分页
	builder.from(0).size(2);

	//排序
	builder.sort("age",SortOrder.ASC);
	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 执行请求
	List<User> users = new ArrayList<>();
	for (SearchHit searchHit : response.getHits().getHits()) {
		Map<String, Object> map = searchHit.getSourceAsMap();
		BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
		User user = beanHandler.handle(map);
		users.add(user);
	}
	// 解析查询结果
	return users;
}

聚合查询

/**
 * 求和
 *
 * @return
 */
@PostMapping("sumSearch")
public Object sumSearch() throws Exception {
	Map<String, Object> result = new HashMap<>();
	// 创建请求
	SearchSourceBuilder builder = new SearchSourceBuilder()
			.query(QueryBuilders.termsQuery("_id", new int[]{1, 2, 3}));
	//条件搜索
	//结果集合分页
	builder.from(0).size(2);
	builder.query(QueryBuilders.matchAllQuery());
	//聚合查询
	AggregationBuilder aggregation = AggregationBuilders.sum("sum_age").field("age");
	builder.aggregation(aggregation);

	//搜索
	SearchRequest searchRequest = new SearchRequest();
	searchRequest.indices("user");
	searchRequest.types("_doc");
	searchRequest.source(builder);
	// 执行请求
	SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
	// 解析查询结果
	return response;
}

在这里插入图片描述
在这里插入图片描述

值得我们注意的是在进行聚合操作的fild上,如果我们该字段设置成key或者text,则会出现以下错误

在这里插入图片描述
原因是:

文本字段未针对需要每个文档字段数据(如聚合和排序)的操作进行优化,因此默认情况下禁用这些操作。

我们需要改用关键字字段。或者,在设置了text或者key的字段上设置fielddata=true,以便通过取消反转索引来加载字段数据。请注意,这可能会占用大量内存

参考文章并稍作修改,https://blog.csdn.net/zhiyikeji/article/details/128939901

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

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

相关文章

HUSTOJ中添加初赛练习系统

文章目录 0. 基于hustoj二开的初赛练习系统&#xff0c;QQ4705852261. 主界面2. 练习界面3. 模拟考试界面4. 查看试卷回放5. 后台操作界面6. 后台试题分类-列表7.后台试题-列表8. 后台试题-添加9. 后台试卷结构-设置 0. 基于hustoj二开的初赛练习系统&#xff0c;QQ470585226 …

Requests请求库的使用

Request请求库 爬虫运行原理Requests请求库安装环境 Requests库的使用状态码网页内容 爬虫运行原理 首先回顾一下爬虫运作的基本原理&#xff08;下面是比较正式的书面语&#xff09;&#xff1a; 爬虫是一种自动化程序&#xff0c;用于从互联网上获取信息&#xff0c; 发起请…

蓝牙耳机啥牌子好?发烧友力荐五大超高性价比蓝牙耳机

预算有限的情况下&#xff0c;性价比是我们在购物时的主要衡量维度&#xff0c;挑选蓝牙耳机时也不例外&#xff0c;那么你知道哪些蓝牙耳机性价比最高吗&#xff1f;不懂的话可以看看老烧我整理的超高性价比蓝牙耳机推荐&#xff0c;了解蓝牙耳机啥牌子好。 一、JEET Air 2 蓝…

数据结构总结4:树、二叉树

后续会有补充 树 树是一种非线性的数据结构&#xff0c;是由n(n>0)个有限结点组成一个具有层次关系的集合。 1.有一个特殊的结点&#xff0c;称为根结点&#xff0c;根节点没有前驱结点 2.树是递归定义的 满足树的条件&#xff1a; 1.子树不相交 2.除了根结点外&#xff0…

白盒测试:如何进行代码级别的测试?

01、什么是白盒测试 白盒测试也称结构测试&#xff0c;透明盒测试。主要用于单元测试阶段&#xff0c;代码和逻辑的测试&#xff0c;重点复杂的测试&#xff0c;是一种测试用例设计方法&#xff0c;不同于黑盒测试&#xff0c;白盒测试是可以看到内部代码如何运作的&#xff0…

PDF.js实现按需加载pdf文件-包含前后端开发源码和详细开发教程

PDF.js实现按需加载pdf文件 说明前言前端项目分片加载的效果前端项目结构项目运行与访问 后端项目项目结构核心代码实现注意事项 项目源码 说明 本文主要是介绍pdf.js的前后端项目的实现&#xff0c;包含可直接运行的源码。由于本人偏向于后端开发&#xff0c;因此前端的vue方…

学习C这么久了,main函数的这三个参数你见过吗?

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;引例1&#x1f427;引例2 &#x1f426;认识环境变量&#x1f514;环境变量的概念&#x1f514;常见的环境变量&#x1f514;和环境变量相关的指令 &#x1f426;main函数的第三个参数&#x1f514;如何通过代…

Django SQL注入漏洞复现 (CVE-2022-28347)

漏洞简介 在Django 2.2 的 2.2.28 之前版本、3.2 的 3.2.13 之前版本和 4.0 的 4.0.4 之前版本中的 QuerySet.deexplain() 中发现了SQL注入问题。这是通过传递一个精心编制的字典&#xff08;带有字典扩展&#xff09;作为**options参数来实现的&#xff0c;并将注入负载放置在…

这个插件厉害!Tapdata 格式的 api 也可以导入了

Tapdata 是干嘛的&#xff0c;大家都知道的吧&#xff1f;我简单介绍一下 Tapdata 是自带 ETL 的实时数据服务平台&#xff0c;通过把企业核心数据实时集中到中央化数据平台的方式并通过 API 或者反向同步方式&#xff0c;为下游的交互式应用、微服务或交互式分析提供新鲜实时的…

js逆向-阿里系某688参数sign分析

声明 本文仅供学习参考&#xff0c;如有侵权可私信本人删除&#xff0c;请勿用于其他途径&#xff0c;违者后果自负&#xff01; 如果觉得文章对你有所帮助&#xff0c;可以给博主点击关注和收藏哦&#xff01; 前言 目标网站&#xff1a;aHR0cHM6Ly93d3cuMTY4OC5jb20v 接…

html访问图片资源403问题

问题&#xff1a;图片403 页面不渲染 单独打开图片链接在浏览器却能正常查看 解决办法&#xff1a; 1.数据库中全局下载该字段链接&#xff0c;将图片存到制定文件夹&#xff0c;在系统内调用 2.检查页面head中的是否有此句“<metaname“referrer” content“no-referre…

网络模型及网络编程

名词解释 OSI&#xff08;Open System Interconnect&#xff09;&#xff0c;即开放式系统互联。 一般都叫OSI参考模型&#xff0c;是ISO&#xff08;国际标准化组织&#xff09;组织在1985年研究的网络互连模型。TCP(Transmission Control Protocol)&#xff0c;传送控制协议…

从永远到永远-ElasticSearch

ElasticSearch 1.概述2.入门1.官方地址2.RESTful3.倒排索引4.http请求操作1.索引操作2.document操作1.基本操作2.多条件查询3.区间查询4.完全匹配5.高亮显示6.聚合查询7.映射关系 5.JAVA API1.index操作2.doc操作1.基础操作2.批量操作3.复杂查询 1.概述 结构化数据、非结构化数…

C/C++函数指针和回调函数

一、函数指针 在讲回调函数之前&#xff0c;我们需要了解函数指针。 我们都知道&#xff0c;C语言的灵魂是指针&#xff0c;我们经常使用整型指针&#xff0c;字符串指针&#xff0c;结构体指针等 int *p1; char *p2; STRUCT *p3; //STRUCT为我们定义的结构体但是好像我们一…

springboot+jsp学生平时作业评价系统idea

课程信息管理功能需求主要是对课程信息的管理,包括课程信息的录入、维护、删除&#xff0c;教师可以根据授课计划设定授课进度。学生信息管理功能需求&#xff0c;主要是对学生的基本信息进行管理&#xff0c;教师可以录入学生信息&#xff0c;并可以对学生信息进行维护和删除。…

linux 串口改为固定

在/etc/udev/rules.d 目录下新建定义规则的文件 1. 文件名要按规范写否则改动无效2. 规则文件必须以.rules 结尾3. 规则文件名称必须遵循 xx-name.rules 格式&#xff08;xx 为数字或字母&#xff0c;name 为规则名称&#xff09;&#xff0c;例如 99-serial-ports.rules。4. 规…

PDM入门指南:一文带你了解PDM的基本知识

上一期&#xff0c;我们聊过PLM&#xff1b;这一期&#xff0c;我们接着聊聊PDM。在介绍之前&#xff0c;先回答之前客户提出的问题&#xff1a;上线PLM/PDM后&#xff0c;还需要e企拆图吗&#xff1f;可能需要&#xff0c;原因放在最后&#xff0c;有需要的朋友可直接跳到最后…

Java经典面试题—— 对比 Hashtable、HashMap、TreeMap 有什么不同?

典型回答 Hashtable、HashMap、TreeMap都是最常见的一些Map实现&#xff0c;是以键值对的形式存储和操作数据的容器类型。 Hashtable是早期Java类库提供的一个哈希表实现&#xff0c;本身是同步的&#xff0c;不支持null键和值&#xff0c;由于同步导致的性能开销&#xff0c…

IP 子网划分详解

文章目录 1 概述1.1 划分目的1.2 划分原则1.3 子网掩码 2 IP 子网划分示例3 网工软考真题3.1 判断网络号和主机号3.2 计算可容纳的主机数 1 概述 IP 子网划分&#xff1a;实际上就是设计 子网掩码 的过程。原因&#xff1a;由于在五类的IP地址中&#xff0c;网络号与主机号的的…

【dfs解决分组问题-两道例题——供佬学会!】(A元素是放在已经存在的组别中,还是再创建一个更好?--小孩子才做选择,dfs直接两种情况都试试)

问题关键就是&#xff1a; 一个点&#xff0c;可能 新开一个组 比 放到已经存在的组 更划算 因为后面的数据&#xff0c;我们遍历之前的点时&#xff0c;并不知道 所以我们应该针对每个点&#xff0c;都应该做出一个选择就是 新开一个元组或者放到之前的元组中&#xff0c;都尝…