SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进

news2024/11/24 12:53:29

目录

  • 引出
  • git代码仓库
  • 准备工作
    • 支付宝沙箱api
    • 内网穿透 [natapp.cn](https://natapp.cn/#download)
  • springboot整合—极简实现版
    • 1.导包+配置文件
    • 2.controller层代码
    • 3.进行支付流程
    • 4.支付成功回调
  • 依赖注入的改进
    • 1.整体结构
    • 2.pom.xml文件依赖
    • 3.配置文件
    • 4.配置类,依赖注入
    • 5.支付商品id,价格,名称
    • 6.controller层进行支付和回调
    • 7.主启动类
  • 总结

引出


1.springboot整合支付宝沙箱支付;
2.准备工作:沙箱api,内网穿透;
3.极简实现理解支付,异步回调等;
4.按照spring依赖注入的思想改造基础demo;

git代码仓库

https://gitee.com/pet365/springboot-alipay

准备工作

支付宝沙箱api

支付宝开放平台 (alipay.com)

在这里插入图片描述

支付参数

在这里插入图片描述

内网穿透 natapp.cn

natapp.cn官网

在这里插入图片描述

启动和配置

在这里插入图片描述

springboot整合—极简实现版

在这里插入图片描述

1.导包+配置文件

<!--        支付宝相关-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.34.0.ALL</version>
        </dependency>
server:
  port: 9090


# 日志需要配置一下 @Slf4j
logging:
  level:
    com.tianju.alipay: debug

2.controller层代码

订单ID,需要唯一;价格;物品名称(支付主题)

http://localhost:9090/api/ali/pay?orderId=202307302321&price=12.56&subject=iPhone

用户名:flrnht7304@sandbox.com

密码:111111

AliPayController.java文件

package com.tianju.alipay.controller;


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 支付宝的支付接口
 * 用户名:flrnht7304@sandbox.com
 * 密码:111111
 */

// http://localhost:9090/api/ali/pay?orderId=202307302321&price=12.56&subject=iPhone
@RestController
@RequestMapping("/api/ali")
@Slf4j // tips:如果用debug记得在application.yml文件中配置一下日志级别
public class AliPayController {


    String alipayPublicKey = "";

    @GetMapping("/pay")
    public void payOrder(String orderId, String price, String subject, HttpServletResponse httpResponse) throws AlipayApiException, IOException {
        // 1.准备需要的参数,私匙,支付公匙,appid,沙箱支付平台的url
        String privateKey = "";
        String alipayPublicKey = "";
        String appId = "9021000123613164";
        String serverUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";

        // 2.把需要配置的参数set进AlipayConfig类中
        com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig();
        alipayConfig.setServerUrl(serverUrl);
        alipayConfig.setAppId(appId);
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");

        // 3.创建支付宝的默认的客户端
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);

        // 4.准备支付的参数,包括需要支付的订单的id,价格,物品名称,
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
//        model.setOutTradeNo("2023073022083620");
        model.setOutTradeNo(orderId); // 需要支付的订单id,自定义的订单id,不能重复,唯一,已经支付的无法继续支付
        model.setTotalAmount(price); // 需要支付的钱 model.setTotalAmount("88.88");
        model.setSubject(subject); // 要支付的物品,比如 model.setSubject("Iphone6 16G");
        model.setProductCode("FAST_INSTANT_TRADE_PAY");

        // 5.创建支付的请求,把上面的准备支付的参数进行set
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setBizModel(model);

        /**
         * 设置支付宝异步回调,这个需要用内网穿透
         */
        request.setNotifyUrl("http://uw7ayu.natappfree.cc/api/ali/notify");

        /**
         * 设置支付宝支付成功返回的页面
         * 这里让支付成功直接回到static下的一个静态页面中
         */
        request.setReturnUrl("http://localhost:9090/aliPayReturn.html");

        // 6.调用ali客户端alipayClient,用客户端执行请求,获取响应,获取.getBody(),拿到form表单
        // 执行请求,拿到响应的结果,返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
            log.debug(">>>>>>getAliPayFrom");
            System.out.println("getAliPayFrom");
            System.out.println(form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        // 表单数据作为响应返回给前端,显示前端页面
        /**
         * <form name="punchout_form" method="post" action="https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=UTF8&method=alipay.trade.page.pay&sign=ZSYIysQXMlJK6q%2B%2BQVJVhKi3qtHBaXTMmh4%2Fi7Wcj1OuSr5Qs6X%2Fhq0jgDbR%2BFw6da3fO5Hov8iV8%2BPo07CVnIQDSL1X2WDZzSN3Srqid%2BLKP%2BnoME2Jv9AfhaPwYkbElg0x40pLspkCv7%2FeRs93ROkrvLUL0aTA%2B7wXrIe5FKkvptqfqjReMayVR1lKmiGw8SWToNJ0OQoDp4g6191vJIy9ld%2BQfRU6PLq9dUH3XIifNvCwOceMCqpOXNlJIAb8MC2FkXK%2FCwEij5mj%2BpqNEevMf0DRczuUklJe20FeXrx6bSsjEIly8Swt1j4UYZZJY817TRQp%2FG3XEOjnLfAH5g%3D%3D&version=1.0&app_id=9021000123613164&sign_type=RSA2&timestamp=2023-07-30+23%3A11%3A17&alipay_sdk=alipay-sdk-java-dynamicVersionNo&format=json">
         * <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;202307302206&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;,&quot;subject&quot;:&quot;iPhone&quot;,&quot;total_amount&quot;:&quot;12.56&quot;}">
         * <input type="submit" value="立即支付" style="display:none" >
         * </form>
         * <script>document.forms[0].submit();</script>
         */
        httpResponse.setContentType("text/html;charset=UTF-8"); // 设置头部
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    /**
     * 支付宝异步回调
     * request.setNotifyUrl("");
     * http://localhost:9090/api/ali/notify
     * 上面这个网址用内网穿透代理一下
     * http://jqdxgm.natappfree.cc/api/ali/notify
     * 此时支付宝就能回调到这个页面
     */
    @PostMapping("/notify")
    public void aliPayNotify(HttpServletRequest request) throws AlipayApiException {
        log.debug(">>>>>>>支付宝异步回调");
        Map<String, String[]> parameterMap = request.getParameterMap();
        // [gmt_create, charset, gmt_payment, notify_time, subject, sign, buyer_id, invoice_amount, version, notify_id,
        // fund_bill_list, notify_type, out_trade_no, total_amount, trade_status, trade_no, auth_app_id, receipt_amount,
        // point_amount, buyer_pay_amount, app_id, sign_type, seller_id]
        Set<String> keySet = parameterMap.keySet(); // 获取http请求里面的所有键

        /**
         * paramsMap如下:
         * {gmt_create=2023-07-31 15:54:11, charset=UTF8,
         * gmt_payment=2023-07-31 15:54:26,
         * notify_time=2023-07-31 15:54:27,
         * sign=fsCABNzc5hax4mwwMULluDiEAT70Kqj77uTMcCgSi82AU6tP5LGbXucEvP7CbvjXrYo5g3hrz5xRQAwddE7qU9Qyrg0v3EnearJBcW4It6N+VNBQ7yfY/W79eKRSKspLBKHRa21RILjyRrmQYG4Cw8R7twP7y0lDCOE8j3rV6ZyGfhiQ7EXp49d6HpgcIT1NjgJjQYSyJFdgyqkzFljKRfbhwPFAtubsmd8IcJCU7XI3YosSKnDhQaCA6ec4dmQiWtvcTbOLNR/r2Sou7rCnI7s1lc8pKeEsuacWTZW2FVR7hdHoLZ/expaRQIt+dNzA86lwQxu3SRCQ9wNTPICv1A==,
         * buyer_id=2088722005286475, invoice_amount=12.56, version=1.0, notify_id=2023073101222155427086470500776505,
         * fund_bill_list=[{"amount":"12.56","fundChannel":"ALIPAYACCOUNT"}],
         * notify_type=trade_status_sync,
         * subject=iPhone, // 物品名称
         * out_trade_no=202307311553, // 进行支付的订单id,唯一,商家自定义,即支付时传入的 String orderId
         * total_amount=12.56, // 总价格
         * trade_status=TRADE_SUCCESS, // 支付状态
         * trade_no=2023073122001486470500697216, auth_app_id=9021000123613164,
         * receipt_amount=12.56, point_amount=0.00,
         * buyer_pay_amount=12.56, app_id=9021000123613164, sign_type=RSA2, seller_id=2088721005318559}
         */
        Map<String,String> paramsMap = new HashMap<>(); // 专门用来放置请求里面的参数
        for(String key : keySet){
            paramsMap.put(key, request.getParameter(key));
        }
        System.out.println("*************");
        System.out.println(paramsMap);

        // 验证签名
        String sign = paramsMap.get("sign");
        String contentV1 = AlipaySignature.getSignCheckContentV1(paramsMap);
        boolean rsa256CheckSignature = AlipaySignature.rsa256CheckContent(contentV1, sign, alipayPublicKey, "UTF-8");
        if (rsa256CheckSignature && "TRADE_SUCCESS".equals(paramsMap.get("trade_status"))){
            // 签名验证成功 并且 支付宝回调的状态是成功状态 TRADE_SUCCESS
            log.info("在{},买家{}进行订单{}的付款,交易名称{},付款金额{}",
                    paramsMap.get("gmt_payment"),paramsMap.get("buyer_id"),paramsMap.get("out_trade_no"),paramsMap.get("subject"),paramsMap.get("total_amount"));

            // 支付成功,修改数据库中该订单的状态
            // 比如:流程,根据订单ID查询出一条数据,修改该条订单的数据,或者只有支付成功,才给数据库里面新增一条数据
        }
    }
}

3.进行支付流程

在这里插入图片描述

支付密码输入

在这里插入图片描述

支付成功

在这里插入图片描述

4.支付成功回调

设置异步回调

在这里插入图片描述

启动内网穿透

在这里插入图片描述

设置地址

在这里插入图片描述

异步回调流程解析

在这里插入图片描述

支付宝支付成功跳转

在这里插入图片描述

跳转成功

在这里插入图片描述

依赖注入的改进

在这里插入图片描述

1.整体结构

在这里插入图片描述

2.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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tianju.alipay</groupId>
    <artifactId>springboot-alipay</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--json工具-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.12</version>
        </dependency>


        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

        <!--        支付宝相关-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.34.0.ALL</version>
        </dependency>


    </dependencies>
</project>

3.配置文件

applicaiton.yml

server:
  port: 9090


# 日志需要配置一下 @Slf4j
logging:
  level:
    com.tianju.alipay: debug

alipay.properties

ali.privateKey = 
ali.alipayPublicKey = 
ali.appId = 9021000123613164
ali.serverUrl = https://openapi-sandbox.dl.alipaydev.com/gateway.do

ali.returnUrl = http://localhost:9090/aliPayReturn.html
ali.notifyUrl = http://uw7ayu.natappfree.cc/api/ali/notify

4.配置类,依赖注入

package com.tianju.alipay.config;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:config/alipay.properties")
@Getter
public class AlipayConfig {
    @Value("${ali.serverUrl}")
    private String serverUrl;
    @Value("${ali.appId}")

    private String appId;
    @Value("${ali.alipayPublicKey}")
    private String alipayPublicKey;

    @Value("${ali.privateKey}")
    private String privateKey;

    @Bean
    public AlipayClient alipayClient() throws AlipayApiException {
        // 2.把需要配置的参数set进AlipayConfig类中
        com.alipay.api.AlipayConfig alipayConfig = new com.alipay.api.AlipayConfig();
        alipayConfig.setServerUrl(serverUrl);
        alipayConfig.setAppId(appId);
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");
        return new DefaultAlipayClient(alipayConfig);
    }
}

5.支付商品id,价格,名称

package com.tianju.alipay.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Alipay {
    private String orderId; // 商家自定义的订单编号,唯一
    private String price; // 商品价格
    private String subject; // 支付主题
}

6.controller层进行支付和回调

package com.tianju.alipay.controller;


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.tianju.alipay.entity.Alipay;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 支付宝的支付接口
 * 用户名:flrnht7304@sandbox.com
 * 密码:111111
 */

// http://localhost:9090/api/ali/pay?orderId=202307302321&price=12.56&subject=iPhone
@RestController
@RequestMapping("/api/ali")
@Slf4j
public class AliPayController {

    @Autowired
    private AlipayClient alipayClient;

    @Value("${ali.alipayPublicKey}")
    private String alipayPublicKey;
    @Value("${ali.returnUrl}")
    private String returnUrl; // 支付成功返回的页面
    @Value("${ali.notifyUrl}")
    private String notifyUrl; // 支付宝支付成功异步回调的页面,需要内网穿透

    @GetMapping("/pay")
    public void payOrder(Alipay alipay, HttpServletResponse httpResponse) throws IOException {

        // 4.准备支付的参数,包括需要支付的订单的id,价格,物品名称,
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setOutTradeNo(alipay.getOrderId()); // 需要支付的订单id,自定义的订单id,不能重复,唯一,已经支付的无法继续支付
        model.setTotalAmount(alipay.getPrice()); // 需要支付的钱 model.setTotalAmount("88.88");
        model.setSubject(alipay.getSubject()); // 要支付的物品,比如 model.setSubject("Iphone6 16G");
        model.setProductCode("FAST_INSTANT_TRADE_PAY");

        // 5.创建支付的请求,把上面的准备支付的参数进行set
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setBizModel(model);

        /**
         * 设置支付宝异步回调,这个需要用内网穿透
         */
        request.setNotifyUrl(notifyUrl);

        /**
         * 设置支付宝支付成功返回的页面
         * 这里让支付成功直接回到static下的一个静态页面中
         */
        request.setReturnUrl(returnUrl);

        // 6.调用ali客户端alipayClient,用客户端执行请求,获取响应,获取.getBody(),拿到form表单
        // 执行请求,拿到响应的结果,返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
            log.debug(">>>>>>getAliPayFrom");
            System.out.println("getAliPayFrom");
            System.out.println(form);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        // 表单数据作为响应返回给前端,显示前端页面
        httpResponse.setContentType("text/html;charset=UTF-8"); // 设置头部
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }

    /**
     * 支付宝异步回调
     * request.setNotifyUrl("");
     * http://localhost:9090/api/ali/notify
     * 上面这个网址用内网穿透代理一下
     * http://jqdxgm.natappfree.cc/api/ali/notify
     * 此时支付宝就能回调到这个页面
     */
    @PostMapping("/notify")
    public void aliPayNotify(HttpServletRequest request) throws AlipayApiException {
        log.debug(">>>>>>>支付宝异步回调");
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> keySet = parameterMap.keySet(); // 获取http请求里面的所有键

        /**
         * paramsMap如下:
         * {gmt_create=2023-07-31 15:54:11, charset=UTF8,
         * gmt_payment=2023-07-31 15:54:26,
         * notify_time=2023-07-31 15:54:27,
         * sign=fsCABNzc5hax4mwwMULluDiEAT70Kqj77uTMcCgSi82AU6tP5LGbXucEvP7CbvjXrYo5g3hrz5xRQAwddE7qU9Qyrg0v3EnearJBcW4It6N+VNBQ7yfY/W79eKRSKspLBKHRa21RILjyRrmQYG4Cw8R7twP7y0lDCOE8j3rV6ZyGfhiQ7EXp49d6HpgcIT1NjgJjQYSyJFdgyqkzFljKRfbhwPFAtubsmd8IcJCU7XI3YosSKnDhQaCA6ec4dmQiWtvcTbOLNR/r2Sou7rCnI7s1lc8pKeEsuacWTZW2FVR7hdHoLZ/expaRQIt+dNzA86lwQxu3SRCQ9wNTPICv1A==,
         * buyer_id=2088722005286475, invoice_amount=12.56, version=1.0, notify_id=2023073101222155427086470500776505,
         * fund_bill_list=[{"amount":"12.56","fundChannel":"ALIPAYACCOUNT"}],
         * notify_type=trade_status_sync,
         * subject=iPhone, // 物品名称
         * out_trade_no=202307311553, // 进行支付的订单id,唯一,商家自定义,即支付时传入的 String orderId
         * total_amount=12.56, // 总价格
         * trade_status=TRADE_SUCCESS, // 支付状态
         * trade_no=2023073122001486470500697216, auth_app_id=9021000123613164,
         * receipt_amount=12.56, point_amount=0.00,
         * buyer_pay_amount=12.56, app_id=9021000123613164, sign_type=RSA2, seller_id=2088721005318559}
         */
        Map<String,String> paramsMap = new HashMap<>(); // 专门用来放置请求里面的参数
        for(String key : keySet){
            paramsMap.put(key, request.getParameter(key));
        }
        System.out.println("*************");
        System.out.println(paramsMap);

        // 验证签名
        String sign = paramsMap.get("sign");
        String contentV1 = AlipaySignature.getSignCheckContentV1(paramsMap);
        boolean rsa256CheckSignature = AlipaySignature.rsa256CheckContent(contentV1, sign, alipayPublicKey, "UTF-8");
        if (rsa256CheckSignature && "TRADE_SUCCESS".equals(paramsMap.get("trade_status"))){
            // 签名验证成功 并且 支付宝回调的状态是成功状态 TRADE_SUCCESS
            log.info("在{},买家{}进行订单{}的付款,交易名称{},付款金额{}",
                    paramsMap.get("gmt_payment"),paramsMap.get("buyer_id"),paramsMap.get("out_trade_no"),paramsMap.get("subject"),paramsMap.get("total_amount"));

            // 支付成功,修改数据库中该订单的状态
            // 比如:流程,根据订单ID查询出一条数据,修改该条订单的数据,或者只有支付成功,才给数据库里面新增一条数据
        }
    }
}

7.主启动类

package com.tianju.alipay;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AliPayApp {
    public static void main(String[] args) {
        SpringApplication.run(AliPayApp.class, args);

    }
}

总结

1.springboot整合支付宝沙箱支付;
2.准备工作:沙箱api,内网穿透;
3.极简实现理解支付,异步回调等;
4.按照spring依赖注入的思想改造基础demo;

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

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

相关文章

SQL注入之联合查询

文章目录 联合查询是什么&#xff1f;联合查询获取cms账号密码尝试登录 联合查询是什么&#xff1f; 适用数据库中的内容会回显到页面中来的情况。联合查询就是利用union select 语句&#xff0c;该语句会同时执行两条select 语句&#xff0c;实现跨库、跨表查询。 必要条件 两…

IDEA项目实践——会话跟踪、Web当中的jsp编程以及jsp开发模型和EL与JSTL以及过滤器介绍

系列文章目录 IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介 IDEWA项目实践——mybatis的一些基本原理以及案例 IDEA项目实践——动态SQL、关系映射、注解开发 IDEA项目实践——Spring框架简介&#xff0c;以及IOC注解 IDEA项目实践…

(一)idea连接GitHub的全部流程(注册GitHub、idea集成GitHub、增加合作伙伴、跨团队合作、分支操作)

&#xff08;二&#xff09;Git在公司中团队内合作和跨团队合作和分支操作的全部流程&#xff08;一篇就够&#xff09;https://blog.csdn.net/m0_65992672/article/details/132336481 4.1、简介 Git是一个免费的、开源的*分布式**版本控制**系统*&#xff0c;可以快速高效地…

UE Mesh Draw Pipeline 解析

为什么引入Mesh Draw Pipeline -------------作者:mx 常规渲染管线(老的渲染管线)的弊端 ①无法很好的进行排序以及剔除,以UE为例,使用位图 来表示物体可见性,无法快速找到最前面的物体,drawlist无法实现动态物体和静态物体的 draw sorting ②无法很好的进行合批。…

【javaweb】学习日记Day4 - Maven 依赖管理 Web入门

目录 一、Maven入门 - 管理和构建java项目的工具 1、IDEA如何构建Maven项目 2、Maven 坐标 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;主要组成 3、IDEA如何导入和删除项目 二、Maven - 依赖管理 1、依赖配置 2、依赖传递 &#xff08;1&#xff09;查…

使用Pytorch和OpenCV实现视频人脸替换

“DeepFaceLab”项目已经发布了很长时间了&#xff0c;作为研究的目的&#xff0c;本文将介绍他的原理&#xff0c;并使用Pytorch和OpenCV创建一个简化版本。 本文将分成3个部分&#xff0c;第一部分从两个视频中提取人脸并构建标准人脸数据集。第二部分使用数据集与神经网络一…

二级MySQL(四)——完整性约束

一种规则&#xff0c;限制存储的数据 保证数据库中数据的正确&#xff0c;有效和完整 分类&#xff1a; 非空——得有值——NOT NULL 唯一——唯一的&#xff0c;不重复——UNIQUE 主键——非空且唯一——PRIMARY KEY 默认——给出默认值——DEFAULT 检查——保证某个条件…

CentOS Stream 9中安装MySQL的详细步骤

文章目录 卸载MySQL在线安装离线安装忘记密码 卸载MySQL 安装前先卸载系统上旧版本的 MySQL&#xff08;没有则跳过此步骤&#xff09; 查看已安装的MySQLrpm -qa | grep mysql卸载查询到的所有安装包rpm -e PackageName # 可批量删除删除my.cnf 查看/etc/my.cnf文件是否还存…

【consul】

consul 一、什么是服务注册与发现1.11.2 二、 什么是consul2.1定义2.2特性2.2.1服务注册与发现&#xff1a;2.2.2健康检查&#xff1a;2.2.3Key/Value存储&#xff1a; 三、consul部署-datacenter &#xff1a;指定数据中心名称&#xff0c;默认是dc1。consul &#xff1a;指定…

Hive Cli / HiveServer2 中使用 dayofweek 函数引发的BUG!

文章目录 前言dayofweek 函数官方说明BUG 重现Spark SQL 中的使用总结 前言 使用的集群环境为&#xff1a; hive 3.1.2spark 3.0.2 dayofweek 函数官方说明 dayofweek(date) - Returns the day of the week for date/timestamp (1 Sunday, 2 Monday, …, 7 Saturday). …

线性代数的本质笔记(3B1B课程)

文章目录 前言向量矩阵行列式线性方程非方阵点积叉积 前言 最近在复习线代&#xff0c;李永乐的基础课我刷了一下&#xff0c;感觉讲的不够透彻&#xff0c;和我当年学线代的感觉一样&#xff0c;就是不够形象。 比如&#xff0c;行列式为什么那么重要&#xff0c;它的含义究…

SQL 语句继续学习之记录二

三&#xff0c; 聚合与排序 对表进行聚合查询&#xff0c;即使用聚合函数对表中的列进行合计值或者平均值等合计操作。 通常&#xff0c;聚合函数会对null以外的对象进行合计。但是只有count 函数例外&#xff0c;使用count(*) 可以查出包含null在内的全部数据行数。 使用dis…

Ed腾讯云下一代CDN -- EdgeOne加速MinIO对象存储

省流 使用MinIO作为EdgeOne的源站。 背景介绍 项目中需要一个兼容S3协议的对象存储服务&#xff0c;腾讯云的COS虽然也兼容S3协议&#xff0c;但是也只是支持简单的上传下载&#xff0c;对于上传的时候同时打标签这种需求&#xff0c;就不兼容S3了。所以决定自建一个对象存储…

【分享】华为设备登录安全配置案例

微思网络www.xmws.cn&#xff0c;2002年成立&#xff0c;专业IT认证培训21年&#xff0c;面向全国招生&#xff01; 微 信 号 咨 询&#xff1a; xmws-IT 华为HCIA试听课程&#xff1a;超级实用&#xff0c;华为VRP系统文件详解【视频教学】华为VRP系统文件详解 华为HCIA试听课…

IDEA快速设置Services窗口

现在微服务下面会有很多SpringBoot服务&#xff0c;Services窗口方便我们管理各个SpringBoot服务&#xff0c;但有时IDEA打开项目后无法的看到Services窗口&#xff0c;以下步骤可以解决&#xff01;

shell脚本免交互

一.Here Document免交互 1.免交互概述 使用I/O重定向的方式将命令列表提供给交互式程序 是一种标准输入&#xff0c;只能接收正确的指令或命令 2.格式&#xff1a; 命令 <<标记 ....... 内容 #标记之间是传入内容 ....... 标记 注意事项 标记可以使用任意的合法…

无类别域间路由(Classless Inter-Domain Routing, CIDR):理解IP网络和子网划分(传统的IP地址类ABCDE:分类网络)

文章目录 无类别域间路由&#xff08;CIDR&#xff09;&#xff1a;理解IP网络和子网划分引言传统的IP地址类关于“IP地址的浪费” IP地址与CIDRIP地址概述网络号与主机号CIDR记法&#xff08;网络 网络地址/子网掩码&#xff09;网络和广播地址 CIDR的优势减少路由表项缓解IP…

【AUTOSAR标准规范的下载和阅读方法】

AUTOSAR标准规范的下载和阅读方法 文章目录 AUTOSAR标准规范的下载和阅读方法下载方法 下载方法 我们可以去AUTOSAR的官网进行AUTOSAR标准规范的下载&#xff1a; 官网&#xff1a;https://www.autosar.org/ 步骤如下图&#xff1a; 比如&#xff0c;如果我们想下载Classic P…

【PHP面试题82】system和exec是用来做什么的?有什么区别

文章目录 &#x1f680;一、前言&#xff0c;PHP中system和exec命令的作用&#x1f680;二、system()函数&#x1f680;三、exec()函数&#x1f680;四、区别和应用场景&#x1f50e;4.1 使用system()函数的应用场景&#x1f50e;4.2 使用exec()函数的应用场景&#x1f50e;4.3…

视频云存储/安防监控EasyCVR视频汇聚平台分发rtsp流时,出现“用户已过期”提示该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…