使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

news2024/9/23 15:32:32

目录

使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

第一步:导入RestTemplate依赖,并配置RestTemplate让其加入到SpringIoC容器中

第二步:在yml文件定义股票的相关参数

第三步:向新浪网发送请求,获取国内大盘股票的JS格式数据

第四步:使用正则表达式解析JS数据格式,并把解析后的数据封装到entity对象中

第五步:使用mybatis把entities集合批量入库

 mapper

mapperXml文件

第六步:查看数据库是否插入成功


使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

基本流程:

使用RestTemplate向sina网发送请求,并获取返回的JS数据格式

var hq_str_sh000001="上证指数,3358.9338,3361.5177,3398.6161,3417.0085,3358.9338,0,0,381243178,510307202948,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2022-06-30,15:30:39,00,";
参数说明:
0:指数名称
1:开盘点
2:前收盘点
3:当前点
4:最高点
5:最低点
8:成交量
9:成交金额
30:当前日期
31:当前时间

获取到JS数据后,使用正则表达式解析JS数据,并把解析后的数据封装到entity对象中,在把entity对象插入到数据库中 

第一步:导入RestTemplate依赖,并配置RestTemplate让其加入到SpringIoC容器中

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
/**
 * 定义http客户端工具bean
 */
@Configuration
public class HttpClientConfig {
    /**
     * 定义http客户端工具bean
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

第二步:在yml文件定义股票的相关参数

# 配置股票相关的参数
stock:
  inner:   #A股
    - sh000001 # 上证ID
    - sz399001 #  深证ID
  outer: # 外盘
    - int_dji # 道琼斯
    - int_nasdaq # 纳斯达克
    - int_hangseng # 恒生
    - int_nikkei # 日经指数
    - b_FSSTI # 新加坡
  marketUrl: https://hq.sinajs.cn/list=
  blockUrl: http://vip.stock.finance.sina.com.cn/q/view/newSinaHy.php

在value object 包下写一个与yml文件相互映射的类

/**
 * 大盘编码信息
 */
@Data
@ConfigurationProperties(prefix = "stock")//映射yml文件中stock属性的值
//@Component//直接让其交给spring管理,TODO:我们不使用(不让它自己开启),我们让其他要使用该类的子模块来开启
public class StockInfoConfig {
    private List<String>inner;//国内大盘编码
    private List<String>outer;//国外大盘编码
    private String marketUrl;//大盘 外盘 个股的公共Url请求路径
    private String blockUrl;//板块采集url请求地址
}

开启这个与yml文件相互映射的类,并交给spring管理

@Configuration
//开启StockInfoConfig这个类,开始让这个类映射加载yml文件的属性,并交给spring管理
@EnableConfigurationProperties(StockInfoConfig.class)
public class CommonConfig {
    //配置雪花算法的工具类bean,交给spring管理
    @Bean
    public IdWorker idWorker(){
        /**
         * 参数一:机器ID
         * 参数二:机房ID
         */
        return new IdWorker(1L,2L);
    }
}

第三步:向新浪网发送请求,获取国内大盘股票的JS格式数据

@Service
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Override
    public void getInnerMarketInfo() {
        //TODO:1.从新浪网获取国内大盘的JS数据格式
        //设置请求路径
        //https://hq.sinajs.cn/list=sh000001,sz399001
        String url=stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());
        //join方法可以把集合内的数据装换成String数据类型,并使用,分隔
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        //必须填写,否则数据采集不到
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        //组装请求对象
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        //使用restTemplate发送请求数据
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        //获取响应码
        int statusCode= responseEntity.getStatusCodeValue();
        if(statusCode!=200){
            log.error("时间:{},采集数据出错,响应码状态为:{}", DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),statusCode);
            return;
        }
        //获取js响应数据
        String resData = responseEntity.getBody();
        log.info("时间:{},采集数据成功,数据为:{}",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),resData);
        /**
         * 结果:
         * 时间:2024-09-06 20:05:04,采集数据成功,数据为:
         * var hq_str_sh000001="上证指数,2791.7645,2788.3141,2765.8066,2804.0932,2765.6394,0,0,253645375,228570135027,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2024-09-06,15:30:39,00,";
         * var hq_str_sz399001="深证成指,8252.006,8249.659,8130.770,8260.690,8128.767,0.000,0.000,36378777179,314062276972.566,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,2024-09-06,15:00:03,00";
         */
    }
}

第四步:使用正则表达式解析JS数据格式,并把解析后的数据封装到entity对象中

entity类对象(直接与数据库字段值进行交互)

/**
 * 国内大盘数据详情表
 * @TableName stock_market_index_info
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StockMarketIndexInfo implements Serializable {
    /**
     * 主键字段(无业务意义)
     */
    private Long id;

    /**
     * 大盘编码
     */
    private String marketCode;

    /**
     * 指数名称
     */
    private String marketName;

    /**
     * 前收盘点数
     */
    private BigDecimal preClosePoint;

    /**
     * 开盘点数
     */
    private BigDecimal openPoint;

    /**
     * 当前点数
     */
    private BigDecimal curPoint;

    /**
     * 最低点数
     */
    private BigDecimal minPoint;

    /**
     * 最高点数
     */
    private BigDecimal maxPoint;

    /**
     * 成交量(手)
     */
    private Long tradeAmount;

    /**
     * 成交金额(元)
     */
    private BigDecimal tradeVolume;

    /**
     * 当前时间
     */
    private Date curTime;

    private static final long serialVersionUID = 1L;
}
@Service
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Override
    public void getInnerMarketInfo() {
        //TODO:1.从新浪网获取国内大盘的JS数据格式
        //设置请求路径
        //https://hq.sinajs.cn/list=sh000001,sz399001
        String url=stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());
        //join方法可以把集合内的数据装换成String数据类型,并使用,分隔
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        //必须填写,否则数据采集不到
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        //组装请求对象
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        //使用restTemplate发送请求数据
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        //获取响应码
        int statusCode= responseEntity.getStatusCodeValue();
        if(statusCode!=200){
            log.error("时间:{},采集数据出错,响应码状态为:{}", DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),statusCode);
            return;
        }
        //获取js响应数据
        String resData = responseEntity.getBody();
        log.info("时间:{},采集数据成功,数据为:{}",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),resData);
        /**
         * 结果:
         * 时间:2024-09-06 20:05:04,采集数据成功,数据为:
         * var hq_str_sh000001="上证指数,2791.7645,2788.3141,2765.8066,2804.0932,2765.6394,0,0,253645375,228570135027,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2024-09-06,15:30:39,00,";
         * var hq_str_sz399001="深证成指,8252.006,8249.659,8130.770,8260.690,8128.767,0.000,0.000,36378777179,314062276972.566,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,2024-09-06,15:00:03,00";
         */

        //2.TODO:使用正则解析JS数据
        //定义正则表达式
        String regex="hq_str_(.+)=\"(.+)\";";
        //表达式编译
        Pattern pattern = Pattern.compile(regex);
        //匹配字符串
        Matcher matcher = pattern.matcher(resData);
        List<StockMarketIndexInfo>entities=new ArrayList<>();
        while (matcher.find()){//有多行数据(以 ; 结尾),要使用while循环
            //如果使用的是group(0),则获取匹配的全部数据
            //获取大盘的编码
            String marketCode = matcher.group(1);//获取第一个括号匹配的数据
            //获取大盘的其他信息
            String otherInfo=matcher.group(2);//获取第二个括号匹配的数据
            //分割其他信息成String数据
            String[] splitArr = otherInfo.split(",");
            //大盘名称
            String marketName=splitArr[0];
            //获取当前大盘的开盘点数
            BigDecimal openPoint=new BigDecimal(splitArr[1]);//直接把String类型的数据变成BigDecimal数据类型
            //前收盘点
            BigDecimal preClosePoint=new BigDecimal(splitArr[2]);
            //获取大盘的当前点数
            BigDecimal curPoint=new BigDecimal(splitArr[3]);
            //获取大盘最高点
            BigDecimal maxPoint=new BigDecimal(splitArr[4]);
            //获取大盘的最低点
            BigDecimal minPoint=new BigDecimal(splitArr[5]);
            //获取成交量
            Long tradeAmt=Long.valueOf(splitArr[8]);
            //获取成交金额
            BigDecimal tradeVol=new BigDecimal(splitArr[9]);
            //获取交易时间
            DateTime dateTime = DateTime.parse(splitArr[30] + " " + splitArr[31], DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
            Date date = dateTime.withSecondOfMinute(0).withMillisOfSecond(0).toDate();

            //TODO:3.把获取的数据封装成entity对象,用来插入数据库
            StockMarketIndexInfo entity = StockMarketIndexInfo.builder()
                    .id(idWorker.nextId())//使用雪花算法生成一个Long类型的id
                    .marketCode(marketCode)
                    .marketName(marketName)
                    .openPoint(openPoint)
                    .preClosePoint(preClosePoint)
                    .curPoint(curPoint)
                    .maxPoint(maxPoint)
                    .minPoint(minPoint)
                    .tradeAmount(tradeAmt)
                    .tradeVolume(tradeVol)
                    .curTime(date).build();
            entities.add(entity);
        }
        log.info("当前时间:{},获取的数据为:{}",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-ss HH:mm:ss")),entities);
        /**
         * 当前时间:2024-09-14 20:52:14,获取的数据为:
         * [
         * StockMarketIndexInfo(id=1832039060873678848, marketCode=sh000001, marketName=上证指数, preClosePoint=2788.3141, openPoint=2791.7645, curPoint=2765.8066, minPoint=2765.6394, maxPoint=2804.0932, tradeAmount=253645375, tradeVolume=228570135027, curTime=Fri Sep 06 15:30:00 CST 2024),
         * StockMarketIndexInfo(id=1832039103492001792, marketCode=sz399001, marketName=深证成指, preClosePoint=8249.659, openPoint=8252.006, curPoint=8130.770, minPoint=8128.767, maxPoint=8260.690, tradeAmount=36378777179, tradeVolume=314062276972.566, curTime=Fri Sep 06 15:00:00 CST 2024)
         * ]
     
    }
}

第五步:使用mybatis把entities集合批量入库

import com.hhh.stock.mapper.StockMarketIndexInfoMapper;
import com.hhh.stock.pojo.entity.StockMarketIndexInfo;
import com.hhh.stock.pojo.vo.StockInfoConfig;
import com.hhh.stock.service.StockTimerTaskService;
import com.hhh.stock.utils.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j
public class StockTimerTaskServiceImpl implements StockTimerTaskService {
    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    @Override
    public void getInnerMarketInfo() {
        //TODO:1.从新浪网获取国内大盘的JS数据格式
        //设置请求路径
        //https://hq.sinajs.cn/list=sh000001,sz399001
        String url=stockInfoConfig.getMarketUrl()+String.join(",",stockInfoConfig.getInner());
        //join方法可以把集合内的数据装换成String数据类型,并使用,分隔
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        //必须填写,否则数据采集不到
        headers.add("Referer","https://finance.sina.com.cn/stock/");
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
        //组装请求对象
        HttpEntity<Object> httpEntity = new HttpEntity<>(headers);
        //使用restTemplate发送请求数据
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
        //获取响应码
        int statusCode= responseEntity.getStatusCodeValue();
        if(statusCode!=200){
            log.error("时间:{},采集数据出错,响应码状态为:{}", DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),statusCode);
            return;
        }
        //获取js响应数据
        String resData = responseEntity.getBody();
        log.info("时间:{},采集数据成功,数据为:{}",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),resData);
        /**
         * 结果:
         * 时间:2024-09-06 20:05:04,采集数据成功,数据为:
         * var hq_str_sh000001="上证指数,2791.7645,2788.3141,2765.8066,2804.0932,2765.6394,0,0,253645375,228570135027,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2024-09-06,15:30:39,00,";
         * var hq_str_sz399001="深证成指,8252.006,8249.659,8130.770,8260.690,8128.767,0.000,0.000,36378777179,314062276972.566,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,0,0.000,2024-09-06,15:00:03,00";
         */

        //2.TODO:使用正则解析JS数据
        //定义正则表达式
        String regex="hq_str_(.+)=\"(.+)\";";
        //表达式编译
        Pattern pattern = Pattern.compile(regex);
        //匹配字符串
        Matcher matcher = pattern.matcher(resData);
        List<StockMarketIndexInfo>entities=new ArrayList<>();
        while (matcher.find()){//有多行数据(以 ; 结尾),要使用while循环
            //如果使用的是group(0),则获取匹配的全部数据
            //获取大盘的编码
            String marketCode = matcher.group(1);//获取第一个括号匹配的数据
            //获取大盘的其他信息
            String otherInfo=matcher.group(2);//获取第二个括号匹配的数据
            //分割其他信息成String数据
            String[] splitArr = otherInfo.split(",");
            //大盘名称
            String marketName=splitArr[0];
            //获取当前大盘的开盘点数
            BigDecimal openPoint=new BigDecimal(splitArr[1]);//直接把String类型的数据变成BigDecimal数据类型
            //前收盘点
            BigDecimal preClosePoint=new BigDecimal(splitArr[2]);
            //获取大盘的当前点数
            BigDecimal curPoint=new BigDecimal(splitArr[3]);
            //获取大盘最高点
            BigDecimal maxPoint=new BigDecimal(splitArr[4]);
            //获取大盘的最低点
            BigDecimal minPoint=new BigDecimal(splitArr[5]);
            //获取成交量
            Long tradeAmt=Long.valueOf(splitArr[8]);
            //获取成交金额
            BigDecimal tradeVol=new BigDecimal(splitArr[9]);
            //获取交易时间
            DateTime dateTime = DateTime.parse(splitArr[30] + " " + splitArr[31], DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"));
            Date date = dateTime.withSecondOfMinute(0).withMillisOfSecond(0).toDate();

            //TODO:3.把获取的数据封装成entity对象,用来插入数据库
            StockMarketIndexInfo entity = StockMarketIndexInfo.builder()
                    .id(idWorker.nextId())//使用雪花算法生成一个Long类型的id
                    .marketCode(marketCode)
                    .marketName(marketName)
                    .openPoint(openPoint)
                    .preClosePoint(preClosePoint)
                    .curPoint(curPoint)
                    .maxPoint(maxPoint)
                    .minPoint(minPoint)
                    .tradeAmount(tradeAmt)
                    .tradeVolume(tradeVol)
                    .curTime(date).build();
            entities.add(entity);
        }
        log.info("当前时间:{},获取的数据为:{}",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-ss HH:mm:ss")),entities);
        /**
         * 当前时间:2024-09-14 20:52:14,获取的数据为:
         * [
         * StockMarketIndexInfo(id=1832039060873678848, marketCode=sh000001, marketName=上证指数, preClosePoint=2788.3141, openPoint=2791.7645, curPoint=2765.8066, minPoint=2765.6394, maxPoint=2804.0932, tradeAmount=253645375, tradeVolume=228570135027, curTime=Fri Sep 06 15:30:00 CST 2024),
         * StockMarketIndexInfo(id=1832039103492001792, marketCode=sz399001, marketName=深证成指, preClosePoint=8249.659, openPoint=8252.006, curPoint=8130.770, minPoint=8128.767, maxPoint=8260.690, tradeAmount=36378777179, tradeVolume=314062276972.566, curTime=Fri Sep 06 15:00:00 CST 2024)
         * ]
         */
        //TODO:4.使用mybatis把entities集合批量入库
        int count=stockMarketIndexInfoMapper.insertBatch(entities);
        if(count>0){
            log.info("当前时间:{},{}数据插入成功",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),entities);
        }else{
            log.error("当前时间:{},{}数据插入失败",DateTime.now().toString(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")),entities);
        }
    }
}

 mapper

    /**
     * 批量插入数据到数据库
     * @return
     */
    int insertBatch(@Param("entities") List<StockMarketIndexInfo>entities);

mapperXml文件

<insert id="insertBatch">
        insert into stock_market_index_info
        ( id,market_code,market_name
        ,pre_close_point,open_point,cur_point
        ,min_point,max_point,trade_amount
        ,trade_volume,cur_time)
        values
            <foreach collection="entities" item="entity" separator=",">
                (#{entity.id,jdbcType=BIGINT},#{entity.marketCode,jdbcType=CHAR},#{entity.marketName,jdbcType=VARCHAR}
                ,#{entity.preClosePoint,jdbcType=DECIMAL},#{entity.openPoint,jdbcType=DECIMAL},#{entity.curPoint,jdbcType=DECIMAL}
                ,#{entity.minPoint,jdbcType=DECIMAL},#{entity.maxPoint,jdbcType=DECIMAL},#{entity.tradeAmount,jdbcType=BIGINT}
                ,#{entity.tradeVolume,jdbcType=DECIMAL},#{entity.curTime,jdbcType=TIMESTAMP})
            </foreach>
    </insert>

第六步:查看数据库是否插入成功

 注意:在这个表中把cur_time 和market_code设置为联合唯一键,让同一时间内的国内大盘股票不可重复,即一个国内大盘股票在同一时间的数据只能有一个

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

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

相关文章

FP7195:非同步升压恒流LED区动IC

前言&#xff1a;LED驱动芯片是什么&#xff1f; LED驱动芯片是一种能够将电源的电压和电流转换为适合LED&#xff08;发光二极管&#xff09;使用的电压和电流的芯片。这种芯片的主要作用是控制LED的亮度和电流&#xff0c;从而保证LED的正常工作和长寿命。简单来说&#xff…

【C++二分查找】1802. 有界数组中指定下标处的最大值

本文涉及的基础知识点 C二分查找 LeetCode 1802. 有界数组中指定下标处的最大值 给你三个正整数 n、index 和 maxSum 。你需要构造一个同时满足下述所有条件的数组 nums&#xff08;下标 从 0 开始 计数&#xff09;&#xff1a; nums.length n nums[i] 是 正整数 &#xf…

Vue组件:使用$emit()方法监听子组件事件

1、监听自定义事件 父组件通过使用 Prop 为子组件传递数据&#xff0c;但如果子组件要把数据传递回去&#xff0c;就需要使用自定义事件来实现。父组件可以通过 v-on 指令&#xff08;简写形式“”&#xff09;监听子组件实例的自定义事件&#xff0c;而子组件可以通过调用内建…

Ollama Qwen2 支持 Function Calling

默认 Ollama 中的 Qwen2 模型不支持 Function Calling&#xff0c;使用默认 Qwen2&#xff0c;Ollama 会报错。本文将根据官方模板对 ChatTemplate 进行改进&#xff0c;使得Qwen2 支持 Tools&#xff0c;支持函数调用。 Ollama 会检查对话模板中是否存在 Tools&#xff0c;如…

wlanapi.dll丢失怎么办?有没有什么靠谱的修复wlanapi.dll方法

在遇到各种系统文件错误当中&#xff0c;其中之一就是“wlanapi.dll文件丢失”的问题。这种问题通常发生在Windows操作系统上&#xff0c;特别是当系统试图执行与无线网络相关的任务时。wlanapi.dll是一个重要的系统文件&#xff0c;它负责处理Windows无线网络服务的许多功能。…

一种非接触式智能垃圾桶设计(论文+源码+实物)

1系统方案设计 通过对需求展开分析&#xff0c;本设计非接触式智能垃圾桶采用STM32F103单片机作为控制器&#xff0c;通过红外传感器实现垃圾桶的满溢检测&#xff0c;通过三个SG90舵机分别控制可回收、不可回收、其他垃圾桶盖的开关&#xff0c;并通过WiFi通信模块将数据信息…

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK 工具1、w64devkit2、ndk3、cmake 编译1、准备工作2、开始编译 集成1、替换文件2、使用 工具 1、w64devkit w64devkit 解压出来给个环境变量 验证一下 2、ndk 通过android studio安装 ndk\27.1.1229…

PaddleOCR基础入门

1、下载paddle源码 https://github.com/PaddlePaddle/PaddleOCR2、新建conda虚拟环境 conda create --name paddleocr_env python3.103、激活conda虚拟环境 conda activate paddleocr_env4、解压paddleOCR并进入ocr目录&#xff0c;运行安装所需库&#xff1a; pip install…

包拯断案 | 数据库从库GTID在变化 为何没有数据写入@还故障一个真相

提问&#xff1a;作为DBA运维的你是否遇到过这些烦恼 1、数据库从库复制链路如何正确配置表过滤信息&#xff1f; 2、数据库从库的GTID在变化&#xff0c;实际却没有数据写入&#xff0c;究竟是什么原因&#xff1f; 心中有章&#xff0c;遇事不慌 作为DBA的你&#xff0c;…

KCP实现原理探析

KCP 是一个轻量级的、高效的、面向 UDP 的传输协议库&#xff0c;专为需要低延迟和高可靠性的实时应用设计。本文针对 KCP 的主要机制和实现与原理进行分析。 1. 术语 术语 全称 说明 TCP Transmission Control Protocol 传输控制协议 RTT Round Trip Time 往返时延 …

SQL Server导入导出

SQL Server导入导出 导出导入 这里已经安装好了SQL Server&#xff0c;也已经创建了数据库和表。现在想导出来给别人使用&#xff0c;所以需要导入导出功能。环境&#xff1a;SQL Server 2012 SP4 如果没有安装&#xff0c;可以查看安装教程&#xff1a; Microsoft SQL Server …

远程控制不止向日葵,这四款工具千万别错过!

不管是什么职业&#xff0c;总有些朋友会需要远程控制电脑&#xff0c;无论是从家里连接到办公室的机器&#xff0c;还是在出差时需要紧急访问我的开发环境。今天&#xff0c;我想和大家分享一下我使用过的几款远程控制软件它们在实际使用中的表现如何。 一、向日葵 网址&…

Arcgis字段计算器:随机生成规定范围内的数字

选择字段计算器在显示的字段计算器对话框内&#xff0c;解析程序选择Python&#xff0c;勾选上显示代码块&#xff0c; 半部分输入&#xff1a; import random; 可修改下半部分输入&#xff1a; random.randrange(3, 28) 表示生成3-28之间的随机数 字段计算器设置点击确定…

【springboot】使用缓存

目录 1. 添加依赖 2. 配置缓存 3. 使用EnableCaching注解开启缓存 4. 使用注解 1. 配置缓存名称 2. 配置缓存的键 3. 移除缓存 5. 运行结果 1. 添加依赖 <!-- springboot缓存--><dependency><groupId>org.springframework.boot</groupId>…

前端发送邮件至指定邮箱的方式方法有哪些?

前端发送邮件的教程指南&#xff1f;前端静态页面怎么发送邮件&#xff1f; 无论是用户反馈、订阅通知还是其他形式的通信&#xff0c;前端发送邮件的功能都显得尤为重要。AokSend将详细介绍几种常见的前端发送邮件的方法&#xff0c;帮助开发者更好地实现这一功能。 前端发送…

防患于未然,智能监控新视角:EasyCVR视频平台在高校安全防控中的关键角色

有网民发视频称&#xff0c;某大学食堂内发生争执打斗事件。一男一女两名学生疑似因座位问题发生争执&#xff0c;女子被打倒在地。此事引发网友关注。高校食堂作为师生日常用餐的聚集地&#xff0c;人员密集且流动性大&#xff0c;极易因排队、价格、口味等问题引发争执&#…

17、信贷业务管理|为什么说贷款用途是贷款反复发生风险的重要根源?

国家金融监管总局&#xff1a;小额贷款公司应当与借款人明确约定贷款用途&#xff01; 8月23日&#xff0c;为规范小额贷款公司行为&#xff0c;加强监督管理&#xff0c;促进小额贷款公司稳健经营、健康发展&#xff0c;国家金融监督管理总局研究制定了《小额贷款公司监督管理…

pointer-events,添加水印的一个小小点

场景&#xff1a;平平无奇一个水印图&#xff0c;这类功能实现&#xff1a;就是覆盖在整个可视div后&#xff0c;又加了一个div&#xff08;使用定位canvas画一个水印图充当背景&#xff09;&#xff0c;可时我好奇的是&#xff0c;我使用控制台&#xff0c;选择对应的元素时&a…

国产隔离放大器:增强信号完整性和系统安全性的指南

隔离放大器是电子领域的关键组件&#xff0c;特别是在信号完整性和电气隔离至关重要的应用中。这些放大器隔离输入和输出信号&#xff0c;使它们能够在没有直接电气连接的情况下跨不同系统传输数据。这确保了电路一部分的高压尖峰或噪声不会影响另一部分&#xff0c;从而保护了…

全系统各类型工程水土保持方案编制实践技术

内容涵盖八大专题&#xff1a;点型项目、市政工程、线型工程、矿山工程、水利工程、取土场/弃渣场、补报项目、水土保持监测验收 课程一&#xff1a;点型水土保持方案编制方法及案例分析实践 课程二&#xff1a;市政工程水土保持方案编制方法及案例分析实践课程三&#xff1a;…