SpringBoot(JAVA)整合小程序支付和退款功能详解

个人建议支付和退款不要自己去封装请求,因为有很多坑!而且还不一定能弄成功!代码复制直接可用。
需要注意有可能在执行编译证书的时候可能会报一个长度异常,是因为jdk1.8对密匙长度有限制,用jdk大于1.8的版本就能正常编译。

官方文档不是很清晰,都是零零散散的,但有总比没有好。
微信小程序支付文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml
微信小程序退款文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_9.shtml

微信小程序支付

在进行对接微信支付之前,我们首先需要将以下几点准备好:

  • 申请APPID
  • 申请商户号
  • 小程序开通微信支付,绑定已经申请好的商户号。登录小程序后台(mp.weixin.qq.com)。点击左侧导航栏的微信支付,在页面中进行开通。(开通申请要求小程序已发布上线)

支付流程图:
在这里插入图片描述

微信小程序退款

当交易发生之后一年内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付金额退还给买家,微信支付将在收到退款请求并且验证成功之后,将支付款按原路退还至买家账号上。

(1)微信退款所需要的配置!,退款只需要证书即可。微信退款需要证书:资金发生变化需要证书。支付接口不需要。点击证书使用。按照步骤:下载证书
(2)使用API证书
apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件。
◆ 商户如果使用.NET环境开发,请确认Framework版本大于2.0,必须在操作系统上双击安装证书apiclient_cert.p12后才能被正常调用。
◆ API证书调用或安装需要使用到密码,该密码的值为微信商户号(mch_id)
(3)API证书安全
1.证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;
2.建议将证书文件名改为复杂且不容易猜测的文件名;
3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
证书相关API:

退款注意事项
1、交易时间超过一年的订单无法提交退款。
2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。申请退款总金额不能超过订单金额。 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。
3、请求频率限制:150qps,即每秒钟正常的申请退款请求次数不超过150次。
4、每个支付订单的部分退款次数不能超过50次。
5、如果同一个用户有多笔退款,建议分不同批次进行退款,避免并发退款导致退款失败。
6、申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过退款查询接口获取结果。
7、一个月之前的订单申请退款频率限制为:5000/min。
8、同一笔订单多次退款的请求需相隔1分钟。

导入依赖

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.11</version>
</dependency>

在application.yml添加对应配置

# 微信小程序支付配置信息
wx:
  # 微信小程序appid
  app-id: 
  # 小程序密钥
  app-secret: 
  # 商户号
  mch-id: 
  # 证书序列号
  mch-serial-no: 
  # api密钥
  api-key: 
  # 回调接口地址
  notify-url: 
  # 证书地址
  key-path: D:\pay\apiclient_key.pem

这里要说下回调地址和证书地址,回调地址是当创建订单后前端调用回调地址查看支付状态修改订单状态,但是要注意回调地址要放开token校验,证书地址是需要在微信API安全去下载一个证书,这个位置就是你证书所放的位置。如果需要退款回调地址就在添加一个参数即可

yml配置对应实体

@Component
@ConfigurationProperties(prefix = "wx")
@Data
@ToString
public class WxPayV3Bean {
    //小程序appid
    private String appId;
    //商户号
    private String mchId;
    //证书序列号
    private String mchSerialNo;
    //小程序秘钥
    private String appSecret;
    //api秘钥
    private String apiKey;
    //回调接口地址
    private String notifyUrl;
    //证书地址
    private String keyPath;
}

Util工具类

public class WXPayUtil {
    private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final Random RANDOM = new SecureRandom();
    public static String getSign(String signatureStr, String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
        //replace 根据实际情况,不一定都需要
        String replace = privateKey.replace("\\n", "\n");
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(replace);
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(merchantPrivateKey);
        sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
        return Base64Utils.encodeToString(sign.sign());
    }

    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
        }
        return new String(nonceChars);
    }
}

预支付实体类

字段根据实际需求而变化

@Data
@Accessors(chain = true)
public class WXPayOrderReqVO {
    @ApiModelProperty(value = "订单支付类型(商品订单;预约订单)",required = true)
    @NotBlank(message = "订单支付类型不能为空!")
    private String orderType;//附加数据,回调时可根据这个数据辨别订单类型或其他

    @ApiModelProperty(value = "订单定金金额(单位:分)",required = true)
    @NotNull(message = "订单定金金额不能为空!")
//    @DecimalFormat(precision = 2)
    private Integer amount;

    @ApiModelProperty(value = "商品描述",required = true)
    @NotBlank(message = "商品描述不能为空!")
    private String description;

    @ApiModelProperty(value = "openId",required = true)
    @NotBlank(message = "openId不能为空!")
    private String openId;
}

controller

Result 是自定义返回类,修改成自己的。

@Api
@RestController
@Slf4j
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private WxPayService wxPayService;
    /**
     * 微信预支付
     *
     * @param req
     * @param request
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "微信预支付", notes = "微信预支付")
    @PostMapping("/createOrder")
    public Result createOrder(@RequestBody @Validated WXPayOrderReqVO req, HttpServletRequest request) throws Exception {
        log.info("传入参数:" + JSONObject.toJSONString(req));
        return wxPayService.createOrder(req, request);
    }

    /**
     * 微信支付回调
     *
     * @param request
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "微信支付回调", notes = "微信支付回调")
    @PostMapping("/payNotify")
    public Result payNotify(HttpServletRequest request) throws Exception {
        log.info("-----------------------微信支付回调通知-----------------------");
        //注意:回调接口需要暴露到公网上,且要放开token验证
        return wxPayService.payNotify(request);
    }

    /**
     * 退款
     *
     * @param
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "退款", notes = "退款")
    @PostMapping("/refund")
    public Result refund(@RequestParam("orderId") String orderId) {
        if (orderId == null || "".equals(orderId)) {
            return Result.error("参数为空");
        }
        return wxPayService.refund(orderId, "退款");
    }

    /**
     * 微信退款回调
     *
     * @return 
     */
    @ApiOperation(value = "微信退款回调", notes = "微信退款回调")
    @PostMapping("/refund/payNotify")
    public Result refundPayNotify(HttpServletRequest request) throws Exception {
    	//注意:回调接口需要暴露到公网上,且要放开token验证
        return wxPayService.refundNotify(request);
    }
}

service

public interface WxPayService {
    Result createOrder(WXPayOrderReqVO req, HttpServletRequest request) throws Exception;
    Result payNotify(HttpServletRequest request) throws Exception;
    Result refund(String orderId, String refundReason);
    Result refundNotify(HttpServletRequest request);
}

serviceImpl


@Slf4j
@Service
public class WxPayServiceImpl implements WxPayService {
	//注入支付对应配置
    @Autowired
    private WxPayV3Bean wxPayV3Bean;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private MachineOrderMapper orderMapper;
    private static byte[] certData;
     /**
     * 预支付接口
     * @param req
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result createOrder(WXPayOrderReqVO req, HttpServletRequest request) throws Exception {
        Map<String, Object> params = new HashMap<>();
        synchronized (this) {
            SysUser user = userMapper.getUserByOpenId(req.getOpenId());
            if (user == null || StringUtil.isEmpty(user.getOpenid())) {
                return Result.error("无效用户");
            }
            //生成商户订单号
            String tradeNo = getTradeNo();
            // 使用自动更新平台证书的RSA配置,配置微信支付的自动证书管理功能
            Config config =
                    new RSAAutoCertificateConfig.Builder()
                            .merchantId(wxPayV3Bean.getMchId())
                            .privateKeyFromPath(wxPayV3Bean.getKeyPath())
                            .merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
                            .apiV3Key(wxPayV3Bean.getApiKey())
                            .build();
            // 构建service,用于处理JSAPI支付相关的操作
            JsapiService service = new JsapiService.Builder().config(config).build();
            // 创建预支付订单的请求对象
            PrepayRequest prepayRequest = new PrepayRequest();
            Amount amount = new Amount();
            amount.setTotal(req.getAmount());
            prepayRequest.setAmount(amount);
            prepayRequest.setAppid(wxPayV3Bean.getAppId());
            prepayRequest.setMchid(wxPayV3Bean.getMchId());
            prepayRequest.setNotifyUrl(wxPayV3Bean.getNotifyUrl());
            prepayRequest.setDescription(req.getDescription());
            prepayRequest.setOutTradeNo(tradeNo);
            prepayRequest.setAttach(req.getOrderType());
            Payer payer = new Payer();
            payer.setOpenid(user.getOpenid());
            prepayRequest.setPayer(payer);
            // 调用下单方法,得到应答
            PrepayResponse response = service.prepay(prepayRequest);
            log.info("调用下单方法请求返回:" + response);
            Long timeStamp = System.currentTimeMillis() / 1000;
            params.put("timeStamp", timeStamp);
            String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
            params.put("nonceStr", substring);
            String signatureStr = Stream.of(wxPayV3Bean.getAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
                    .collect(Collectors.joining("\n", "", "\n"));
            String sign = WXPayUtil.getSign(signatureStr, wxPayV3Bean.getKeyPath());
            params.put("paySign", sign);
            params.put("package", "prepay_id=" + response.getPrepayId());
            params.put("tradeNo", tradeNo);
            //保存订单信息
            try {
                MachineOrder order = new MachineOrder();
                //自己的业务代码
                orderMapper.insert(order);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Result.OK(params);
    }

  	/**
     * 支付回调
     *
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result payNotify(HttpServletRequest request) throws Exception {
        //读取请求体的信息
        ServletInputStream inputStream = request.getInputStream();
        StringBuffer stringBuffer = new StringBuffer();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s;
        //读取回调请求体
        while ((s = bufferedReader.readLine()) != null) {
            stringBuffer.append(s);
        }
        String s1 = stringBuffer.toString();
        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
        String nonce = request.getHeader(WECHAT_PAY_NONCE);
        String signType = request.getHeader("Wechatpay-Signature-Type");
        String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
        String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
        // 构造一个RSAAutoCertificateConfig
        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                .merchantId(wxPayV3Bean.getMchId())
                .privateKeyFromPath(wxPayV3Bean.getKeyPath())
                .merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
                .apiV3Key(wxPayV3Bean.getApiKey())
                .build();
        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serialNo)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
                .signType(signType)
                .body(s1)
                .build();
        Transaction parse = parser.parse(requestParam, Transaction.class);
        log.info("支付回调信息:" + JSONObject.toJSONString(parse));
        try {
            /**
             *  SUCCESS:支付成功
             *  REFUND:转入退款
             *  NOTPAY:未支付
             *  CLOSED:已关闭
             *  REVOKED:已撤销(付款码支付)
             *  USERPAYING:用户支付中(付款码支付)
             *  PAYERROR:支付失败(其他原因,如银行返回失败)
             */
             //修改订单状态方法
			updateAccountDetail(parse);
			
             // 这里可以根据状态做不同的处理,我这里只处理支付成功
			if ("SUCCESS".equals(parse.getTradeState())) {
				//你的业务代码
                log.info("该订单:" + parse.getOutTradeNo() + "已经进行回调,不可重复回调");
                return Result.ok();
            }            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok();
    }
   	/**
     * 微信小程序退款
     * 
     * @param orderId 订单id
     * @param refundReason 退款原因
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result refund(String orderId, String refundReason) {
        synchronized (this) {
            MachineOrder order = orderMapper.selectById(orderId);
            if (order == null) {
                return Result.error("无订单信息");
            }
            try {
                // 使用自动更新平台证书的RSA配置
                // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
                Config config =
                        new RSAAutoCertificateConfig.Builder()
                                .merchantId(wxPayV3Bean.getMchId())
                                //使用 SDK 不需要计算请求签名和验证应答签名
                                // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
                                .privateKeyFromPath(wxPayV3Bean.getKeyPath())
                                .merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
                                .apiV3Key(wxPayV3Bean.getApiKey())
                                .build();
                // 构建退款service
                RefundService service = new RefundService.Builder().config(config).build();
                //构建退款请求
                CreateRequest request = new CreateRequest();                
                // request.setXxx(val)设置所需参数,具体参数可见Request定义
                //构建订单金额信息
                AmountReq amountReq = new AmountReq();
                //退款金额
                amountReq.setRefund(Long.valueOf((int) (order.getPaymentMoney() * 100)));
                //原订单金额
                amountReq.setTotal(Long.valueOf((int) (order.getPaymentMoney() * 100)));
                //货币类型(默认人民币)
                amountReq.setCurrency("CNY");
                request.setAmount(amountReq);
                request.setOutTradeNo(order.getOrderNum());
                request.setReason("退款");
                //商户退款单号
                request.setOutRefundNo(String.valueOf(order.getOrderNum()));
                //退款通知回调地址,开设可不设,我是没有设置的
                //如果要设置就在配置加上对应的参数和参数值即可
				// request.setNotifyUrl(wxPayV3Bean.getRefundNotify());
                
                // 调用微信sdk退款接口
                Refund refund = service.create(request);
                log.info("请求退款返回:" + refund);
                //接收退款返回参数
				//  Status status = refund.getStatus();
                if (Status.SUCCESS.equals(refund.getStatus().SUCCESS)) {
                    //说明退款成功,开始接下来的业务操作                    
                    //你的业务代码,根据请求返回状态修改对应订单状态
                    return Result.ok("退款成功");
                }
                if (Status.PROCESSING.equals(refund.getStatus().PROCESSING)) {
                   //你的业务代码,根据请求返回状态修改对应订单状态
                    return Result.OK("退款中");
                }
                if (Status.ABNORMAL.equals(refund.getStatus().ABNORMAL)) {
                   //你的业务代码,根据请求返回状态修改对应订单状态
                    return Result.error("退款异常");
                }
                if (Status.CLOSED.equals(refund.getStatus().CLOSED)) {
                   //你的业务代码,根据请求返回状态修改对应订单状态
                    return Result.error("退款关闭");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Result.error("退款失败");
    }

/**
     * 退款回调
     * @param request
     * @return
     */
    @Override
    public Result refundNotify(HttpServletRequest request) {
        try {
            //读取请求体的信息
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String s1 = stringBuffer.toString();
            String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
            String nonce = request.getHeader(WECHAT_PAY_NONCE);
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
            // 如果已经初始化了 RSAAutoCertificateConfig,可直接使用
            // 没有的话,则构造一个
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(wxPayV3Bean.getMchId())
                    .privateKeyFromPath(wxPayV3Bean.getKeyPath())
                    .merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
                    .apiV3Key(wxPayV3Bean.getApiKey())
                    .build();
            // 初始化 NotificationParser
            NotificationParser parser = new NotificationParser(config);
            RequestParam requestParam = new RequestParam.Builder()
                    .serialNumber(serialNo)
                    .nonce(nonce)
                    .signature(signature)
                    .timestamp(timestamp)
                    // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
                    .signType(signType)
                    .body(s1)
                    .build();
            RefundNotification parse = parser.parse(requestParam, RefundNotification.class);
            System.out.println("parse = " + parse);
            //parse.getRefundStatus().equals("SUCCESS");说明退款成功
            
            //这里和上面退款返回差不多的处理,可以抽成一个公共的方法
            if (Status.SUCCESS.equals(parse.getRefundStatus().SUCCESS)) {
               //你的业务代码,根据请求返回状态修改对应订单状态
                return Result.ok("退款成功");
            }
            if (Status.PROCESSING.equals(parse.getRefundStatus().PROCESSING)) {
                //你的业务代码,根据请求返回状态修改对应订单状态
                return Result.OK("退款中");
            }
            if (Status.ABNORMAL.equals(parse.getRefundStatus().ABNORMAL)) {
                //你的业务代码,根据请求返回状态修改对应订单状态
                return Result.error("退款异常");
            }
            if (Status.CLOSED.equals(parse.getRefundStatus().CLOSED)) {
                //你的业务代码,根据请求返回状态修改对应订单状态
                return Result.error("退款关闭");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.error("回调失败");
    }

	 /**
     * 修改订单状态
     *
     */
	public void updateAccountDetail(Transaction parse) {
		//根据自己业务修改
        Map<String, Object> map = new HashMap<>();
        map.put("order_num", parse.getOutTradeNo().toString());
        map.put("transactionId", parse.getTransactionId().toString());
        map.put("tradeState", parse.getTradeState().toString());
        log.info("更新订单数据:" + JSONObject.toJSONString(map));
        orderMapper.updateOrderStatus(map);
    }
    
    /**
     * 时间+id为订单号
     *
     * @param
     * @return
     */
    public String getTradeNo() {
        String idStr = WXPayUtil.generateNonceStr();
//        long timestamp = DateUtils.getCurrentTimestamp();
//        //序列号是为了保证生成的订单号的唯一性
        AtomicInteger sequence = new AtomicInteger(0);
        int nextSequence = sequence.getAndIncrement();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(String.valueOf(nextSequence).getBytes());
            BigInteger no = new BigInteger(1, messageDigest);
            String encrypted = no.toString(10); // 将十六进制转为十进制表示的字符串
            // 如果加密结果长度超过20位,则截取前20位
            if (encrypted.length() > 20) {
                encrypted = encrypted.substring(0, 20);
            }
//            String tradeNo = timestamp + idStr;
            return idStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • 23
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Java整合MyBatis和SpringBoot是现在Web应用开发中非常常见的一种方式,这种方式可以快速的搭建出一个基本的Web应用框架,同时也可以很方便的进行数据库操作。下面我们来详细的介绍一下Java整合MyBatis和SpringBoot的具体实现。 一、搭建SpringBoot项目 1.1 创建项目 在Eclipse或者IntelliJ IDEA中创建一个SpringBoot项目,选择maven方式,选择Web、MySQL、MyBatis等相关依赖。 1.2 配置文件 在src/main/resources目录下创建application.properties文件,添加如下配置: ``` # 数据库连接配置 spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # MyBatis配置 mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.example.demo.entity ``` 二、创建实体类 创建一个实体类,比如User.java,代码如下: ``` package com.example.demo.entity; public class User { private Integer id; private String username; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ``` 三、创建Mapper接口 创建一个Mapper接口,比如UserMapper.java,代码如下: ``` package com.example.demo.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import com.example.demo.entity.User; @Mapper public interface UserMapper { List<User> findAll(); User findById(Integer id); void insert(User user); void update(User user); void delete(Integer id); } ``` 四、创建Mapper.xml文件 在src/main/resources/mapper目录下创建UserMapper.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.demo.mapper.UserMapper"> <resultMap id="BaseResultMap" type="com.example.demo.entity.User"> <id column="id" property="id" /> <result column="username" property="username" /> <result column="password" property="password" /> </resultMap> <select id="findAll" resultMap="BaseResultMap"> SELECT * FROM user </select> <select id="findById" parameterType="java.lang.Integer" resultMap="BaseResultMap"> SELECT * FROM user WHERE id = #{id} </select> <insert id="insert" parameterType="com.example.demo.entity.User"> INSERT INTO user (username, password) VALUES (#{username}, #{password}) </insert> <update id="update" parameterType="com.example.demo.entity.User"> UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id} </update> <delete id="delete" parameterType="java.lang.Integer"> DELETE FROM user WHERE id = #{id} </delete> </mapper> ``` 五、创建Service 创建一个Service,比如UserService.java,代码如下: ``` package com.example.demo.service; import java.util.List; import com.example.demo.entity.User; public interface UserService { List<User> findAll(); User findById(Integer id); void save(User user); void update(User user); void delete(Integer id); } ``` 创建一个ServiceImpl,比如UserServiceImpl.java,代码如下: ``` package com.example.demo.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> findAll() { return userMapper.findAll(); } @Override public User findById(Integer id) { return userMapper.findById(id); } @Override public void save(User user) { userMapper.insert(user); } @Override public void update(User user) { userMapper.update(user); } @Override public void delete(Integer id) { userMapper.delete(id); } } ``` 六、创建Controller 创建一个Controller,比如UserController.java,代码如下: ``` package com.example.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.example.demo.entity.User; import com.example.demo.service.UserService; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/", method = RequestMethod.GET) public List<User> findAll() { return userService.findAll(); } @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User findById(@PathVariable Integer id) { return userService.findById(id); } @RequestMapping(value = "/", method = RequestMethod.POST) public void save(@RequestBody User user) { userService.save(user); } @RequestMapping(value = "/", method = RequestMethod.PUT) public void update(@RequestBody User user) { userService.update(user); } @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) public void delete(@PathVariable Integer id) { userService.delete(id); } } ``` 七、启动项目 在Eclipse或者IntelliJ IDEA中启动SpringBoot项目,启动成功后就可以通过http://localhost:8080/users/访问到我们创建的接口了。 以上就是Java整合MyBatis和SpringBoot的具体实现,希望对大家有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值