001 定期同步mysql数据到es 删除数据库记录同时删除es记录 es全文搜索分词和高亮

本文主要是介绍001 定期同步mysql数据到es 删除数据库记录同时删除es记录 es全文搜索分词和高亮,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • ProductController.java
    • Product.java
    • ElasticsearchSyncListener.java
    • ProductElasticSearchMapper.java
    • ProductMapper.java
    • ProductDeletedEvent.java
    • ProductServiceImpl.java
    • SyncProductService.java
    • IProductService.java
    • ElasticSearchSpringDemoApplication.java
    • ServletInitializer.java
    • product.sql
    • 同步
    • ProductMapper.xml
    • application.yaml
    • pom.xml

ProductController.java


package com.example.controller;import com.example.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;/*** <p>*  前端控制器* </p>** @author dd* @since 2024-05-07**///测试:http://localhost:8080/es_demo/product/kw/纯棉四件套/page/1
@RestController
@RequestMapping("product")
public class ProductController {@Autowiredprivate IProductService productService;// 将mysql中的product数据保存到es中@GetMapping("saveProductToES")public String saveProductToES(){productService.saveProductFromDBToES();return "ok";}//在生产环境中,直接操作Elasticsearch通常需要更复杂的错误处理和事务管理逻辑,以确保数据的一致性和完整性。@GetMapping("delete/{productId}")public String deleteProduct(@PathVariable Integer productId){return productService.deleteProduct(productId);}// 搜索引擎:输入关键字//返回 商品信息 + 页码信息@GetMapping("kw/{kw}/page/{pageNum}")public Map<String, Object> getByKeyword(@PathVariable("kw") String keyword,@PathVariable("pageNum") Integer pageNum){if(pageNum == null)pageNum = 1;Map<String, Object> result = productService.getByNameAndInfo(keyword, keyword, pageNum);return result;}}

Product.java


package com.example.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;/*** <p>* * </p>** @author dd* @since 2024-05-07*///    @Field(index = false, store = true,
//            type = FieldType.Date,format = DateFormat.custom,
//            pattern = "yyyy-MM-dd HH:mm:ss")@Document(indexName = "myproduct")
public class Product implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "product_id",type = IdType.AUTO)@Idprivate Integer productId;@Field(type = FieldType.Keyword)private String productName;private BigDecimal productPrice;private String productImg;private Integer productCount;@Field( type = FieldType.Date,name = "update_time",format = {},pattern = "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd'T'HH:mm:ss'+08:00' || strict_date_opotional_time || epoch_millis")private LocalDateTime createTime;@Field( type = FieldType.Date,name = "update_time",format = {},pattern = "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd'T'HH:mm:ss'+08:00' || strict_date_opotional_time || epoch_millis")private LocalDateTime updateTime;@Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_max_word")private String productInfo;public Integer getProductId() {return productId;}public void setProductId(Integer productId) {this.productId = productId;}public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}public BigDecimal getProductPrice() {return productPrice;}public void setProductPrice(BigDecimal productPrice) {this.productPrice = productPrice;}public String getProductImg() {return productImg;}public void setProductImg(String productImg) {this.productImg = productImg;}public Integer getProductCount() {return productCount;}public void setProductCount(Integer productCount) {this.productCount = productCount;}public LocalDateTime getCreateTime() {return createTime;}public void setCreateTime(LocalDateTime createTime) {this.createTime = createTime;}public LocalDateTime getUpdateTime() {return updateTime;}public void setUpdateTime(LocalDateTime updateTime) {this.updateTime = updateTime;}public String getProductInfo() {return productInfo;}public void setProductInfo(String productInfo) {this.productInfo = productInfo;}@Overridepublic String toString() {return "Product{" +"productId=" + productId +", productName=" + productName +", productPrice=" + productPrice +", productImg=" + productImg +", productCount=" + productCount +", createTime=" + createTime +", updateTime=" + updateTime +", productInfo=" + productInfo +"}";}
}

ElasticsearchSyncListener.java


package com.example.listener;import com.example.service.impl.ProductDeletedEvent;
import com.example.mapper.ProductElasticSearchMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class ElasticsearchSyncListener {@Autowiredprivate ProductElasticSearchMapper productElasticSearchMapper;@EventListenerpublic void handleProductDeletedEvent(ProductDeletedEvent event) {Integer productId = event.getProductId();// 删除Elasticsearch中的记录productElasticSearchMapper.deleteById(productId);}
}

ProductElasticSearchMapper.java


package com.example.mapper;import com.example.entity.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;import java.util.List;@Repository //父接口已经 实现对象在es中的基础CRUD操作
public interface ProductElasticSearchMapper extends ElasticsearchRepository<Product,Integer> {//方法名必须是:findBy + pojo类属性名(首字母大写)public List<Product> findByProductName(String productName);public List<Product> findByProductInfo(String productInfo);}

ProductMapper.java


package com.example.mapper;import com.example.entity.Product;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;import java.util.List;/*** <p>*  Mapper 接口* </p>** @author dd* @since 2024-05-07*/public interface ProductMapper extends BaseMapper<Product> {}

ProductDeletedEvent.java


package com.example.service.impl;import org.springframework.context.ApplicationEvent;//定义一个事件类来表示删除操作
public class ProductDeletedEvent extends ApplicationEvent {private final Integer productId;public ProductDeletedEvent(Object source, Integer productId) {super(source);this.productId = productId;}public Integer getProductId() {return productId;}
}

ProductServiceImpl.java

package com.example.service.impl;import com.example.entity.Product;
import com.example.mapper.ProductElasticSearchMapper;
import com.example.mapper.ProductMapper;
import com.example.service.IProductService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;//空值检查:
//在处理高亮字段时,已经对highlightFields.get("productName")和highlightFields.get("productInfo")进行了空值检查,确保Product类的getProductName和getProductInfo方法也能处理可能的空值情况。
//
//字段名匹配:
//确保在Elasticsearch中定义的字段名(如productName和productInfo)与在Java代码中使用的字段名相匹配。
//
//性能考虑:
//如果productMapper.selectList(null)返回大量的产品数据,并且一次性将它们全部保存到Elasticsearch中,这可能会导致性能问题。考虑分批保存或使用Elasticsearch的批量API来提高性能。
//
//查询字符串分析:
//使用了queryStringQuery,这可能会对输入的productName进行分词查询。如果希望精确匹配整个字段值,而不是基于分词,可能需要使用termQuery或matchPhraseQuery。但是,由于处理的是全文搜索场景,queryStringQuery通常是合适的。//安全性:
//如果productName或productInfo参数来自不受信任的源(如用户输入),请确保对它们进行适当的验证和清理,以防止SQL注入或Elasticsearch注入攻击。不过,由于是在应用层进行Elasticsearch查询,而不是直接拼接查询字符串,因此SQL注入的风险较低。但仍然需要注意Elasticsearch注入的风险。//返回类型:
//返回了一个包含分页信息和搜索结果的Map。确保前端或调用此服务的客户端知道如何解析这个Map。考虑定义一个DTO(数据传输对象)来封装返回的数据,以提供更明确的契约。/*** <p>*  服务实现类* </p>** @author dd* @since 2024-05-07*/
@Service
public class ProductServiceImpl  implements IProductService {@Autowiredprivate ProductMapper productMapper;@Autowiredprivate ProductElasticSearchMapper productElasticSearchMapper;@Autowiredprivate ElasticsearchRestTemplate restTemplate;@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;// 把mysql中的数据查询出来,保存商品数据到es中//当前代码逻辑中的saveProductFromDBToES方法设计为一个全量同步操作,它会从MySQL数据库中查询所有产品记录,并将它们全部保存到Elasticsearch中。因此,当从数据库中删除一条记录时,该方法不会意识到有记录被删除,因为它仅仅是再次执行了全量查询和保存操作。////为了解决这个问题,可以采取以下几种策略之一:////增量同步:设计一个机制来跟踪数据库中的更改(如使用数据库的binlog日志),并仅同步自上次同步以来发生的更改。这通常比较复杂,但可以实现实时或近实时的数据同步。////定期全量同步:可以定期(如每小时、每天)运行saveProductFromDBToES方法来进行全量同步。这种方法比较简单,但可能会导致数据在一定时间窗口内不同步。////删除操作同步:在应用程序中添加逻辑,以便在数据库记录被删除时,也在Elasticsearch中删除相应的文档。这通常需要在数据库删除操作的地方添加额外的代码或使用触发器。////使用监听器或事件驱动:如果使用的是支持事件驱动或变更数据捕获(CDC)的数据库或框架,可以配置监听器来捕获数据库更改事件,并据此更新Elasticsearch中的数据。@Overridepublic boolean saveProductFromDBToES() {//1. select  product  from mysqlList<Product> productList =    productMapper.selectList(null);//2.  save to esIterable<Product> products = productElasticSearchMapper.saveAll(productList);return true;}@Overridepublic String deleteProduct(Integer productId) {// 这里有一个方法来删除数据库中的记录int rows = productMapper.deleteById(productId);if(rows>0){// 发布删除事件applicationEventPublisher.publishEvent(new ProductDeletedEvent(this, productId));return "删除成功";}return "删除失败";}//创建一个事件监听器来监听ProductDeletedEvent并执行删除Elasticsearch中的记录的操作//ElasticsearchSyncListener类是一个Spring组件,它使用@EventListener注解来标记handleProductDeletedEvent方法作为事件监听器。当ProductDeletedEvent事件被发布时,这个方法将被调用,并执行删除Elasticsearch中相应记录的操作。////请注意,需要确保ApplicationEventPublisher和ProductElasticSearchMapper都被正确地注入到相应的类中。此外,可能还需要配置Spring的事件支持,但通常情况下,在Spring Boot应用程序中,事件支持是默认启用的。////最后,当调用ProductService的deleteProduct方法时,它将删除数据库中的记录并发布一个ProductDeletedEvent事件。这个事件将被ElasticsearchSyncListener监听并处理,从而删除Elasticsearch中的相应记录。// 实现接口方法,基于Elasticsearch的全文搜索,包括分词和高亮功能@Overridepublic Map<String,Object> getByNameAndInfo(String productName, String productInfo, Integer pageNum) {//设置分页信息,每页显示3条记录,pageNum-1是因为页码通常从1开始,而数组索引从0开始PageRequest page = PageRequest.of(pageNum - 1, 3);//创建一个布尔查询构建器,用于组合多个查询条件BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();//如果productName不为空,则创建一个基于productName的查询,并将其添加到布尔查询中if(productName !=null){QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(productName);boolQueryBuilder.must(queryBuilder);}else{//如果productName为空且productInfo不为空,则创建一个基于productInfo的匹配查询,并将其添加到布尔查询中if(productInfo !=null)boolQueryBuilder.must(new MatchQueryBuilder("productInfo",productInfo));}//根据商品价格降序排序SortBuilder sortBuilder = SortBuilders.fieldSort("productPrice").order(SortOrder.DESC);//FieldSortBuilder priceSort = SortBuilders.fieldSort("productPrice"); // 按产品价格排序(需要指定升序或降序)//构建高亮查询,设置高亮字段和高亮标签NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder();NativeSearchQuery query=builder.withQuery(boolQueryBuilder).withPageable(page).withSort(sortBuilder).withHighlightFields(new HighlightBuilder.Field("productInfo"),new HighlightBuilder.Field("productName")).withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).build();// 执行查询,获取搜索结果SearchHits<Product> search = restTemplate.search(query, Product.class);List<Product> productList= new ArrayList<>();//遍历搜索结果,处理高亮信息,并将处理后的产品添加到列表中for(SearchHit<Product> searchHit:search){//获取高亮字段信息Map<String ,List<String>> highlightFields = searchHit.getHighlightFields();//将高亮的内容填充到content中//处理产品名称和产品信息的高亮信息,并将其设置回产品对象中String highLightProName = highlightFields.get("productName") ==null ?searchHit.getContent().getProductName() :highlightFields.get("productName").get(0);String highLightProInfo = highlightFields.get("productInfo") ==null ?searchHit.getContent().getProductInfo() :highlightFields.get("productInfo").get(0);searchHit.getContent().setProductName(highLightProName );searchHit.getContent().setProductInfo(highLightProInfo);//将处理后的产品添加到列表中productList.add(searchHit.getContent());}//创建SearchPage对象,用于获取分页信息(假设SearchHitSupport是有效的)SearchPage<Product> searchPage= SearchHitSupport.searchPageFor(search,query.getPageable());//总记录数long totalElements=searchPage.getTotalElements();//总页数int totalPages=searchPage.getTotalPages();//当前页数int currentPageForDisplay=searchPage.getPageable().getPageNumber() + 1;// 通常前端期望页码从1开始System.out.println(currentPageForDisplay);//创建一个Map对象,用于返回查询结果和分页信息Map<String,Object> map=new HashMap<>();map.put("totalElements",totalElements);  // 总记录数map.put("totalPages",totalPages);  //总页数map.put("currentPage",currentPageForDisplay);  // 当前页码map.put("productList",productList);  // 商品数据信息//返回查询结果和分页信息的Map对象return map;}}

SyncProductService.java


package com.example.service.impl;import com.example.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;@Service
public class SyncProductService {@Autowiredprivate IProductService productService;@Scheduled(fixedRate = 2000) // 单位是毫秒public void syncProductsFromDBToES() {productService.saveProductFromDBToES();}
}

IProductService.java

package com.example.service;import com.example.entity.Product;
import com.baomidou.mybatisplus.extension.service.IService;import java.util.Map;/*** <p>*  服务类* </p>** @author dd* @since 2024-05-07*/
public interface IProductService  {public boolean saveProductFromDBToES();public String deleteProduct(Integer productId);// 搜索引擎中的关键字// 返回满足条件的商品的数据+分页信息public Map<String,Object> getByNameAndInfo(String productName, String productInfo, Integer pageNum);}

ElasticSearchSpringDemoApplication.java

package com.example;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
@MapperScan("com.example.mapper")
@EnableScheduling
public class ElasticSearchSpringDemoApplication {public static void main(String[] args) {SpringApplication.run(ElasticSearchSpringDemoApplication.class, args);}}

ServletInitializer.java

package com.example;import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {return application.sources(ElasticSearchSpringDemoApplication.class);}}

product.sql


/*Navicat Premium Data TransferSource Server         : rootWindowsSource Server Type    : MySQLSource Server Version : 80036Source Host           : localhost:3306Source Schema         : cloud_product_dbTarget Server Type    : MySQLTarget Server Version : 80036File Encoding         : 65001Date: 07/05/2024 18:49:44
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for product
-- ----------------------------
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product`  (`product_id` int(0) NOT NULL AUTO_INCREMENT,`product_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`product_price` decimal(10, 2) NULL DEFAULT NULL,`product_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`product_count` int(0) NULL DEFAULT NULL,`create_time` datetime(0) NULL DEFAULT NULL,`update_time` datetime(0) NULL DEFAULT NULL,`product_info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`product_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of product
-- ----------------------------SET FOREIGN_KEY_CHECKS = 1;

同步


增量同步:设计一个机制来跟踪数据库中的更改(如使用数据库的binlog日志),并仅同步自上次同步以来发生的更改。这通常比较复杂,但可以实现实时或近实时的数据同步。定期全量同步:可以定期(如每小时、每天)运行saveProductFromDBToES方法来进行全量同步。这种方法比较简单,但可能会导致数据在一定时间窗口内不同步。删除操作同步:在应用程序中添加逻辑,以便在数据库记录被删除时,也在Elasticsearch中删除相应的文档。这通常需要在数据库删除操作的地方添加额外的代码或使用触发器。使用监听器或事件驱动:如果使用的是支持事件驱动或变更数据捕获(CDC)的数据库或框架,可以配置监听器来捕获数据库更改事件,并据此更新Elasticsearch中的数据。

ProductMapper.xml


<?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.example.mapper.ProductMapper"></mapper>

application.yaml


# ???
server:servlet:context-path: /es_demospring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/cloud_product_db?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456elasticsearch:uris: localhost:9200connection-timeout: 5ssocket-timeout: 30s

pom.xml


<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>elasticSearchSpringDemo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging><name>elasticSearchSpringDemo</name><description>elasticSearchSpringDemo</description><properties><java.version>1.8</java.version></properties><dependencies><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generate --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency><dependency><groupId>org.apache.lucene</groupId><artifactId>lucene-core</artifactId><version>8.11.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

这篇关于001 定期同步mysql数据到es 删除数据库记录同时删除es记录 es全文搜索分词和高亮的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/968870

相关文章

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义