mybatis day3动态SQL

MyBatis是一款强大的持久层框架,提供了丰富的功能来简化数据库操作。其中之一就是动态SQL,它可以根据不同的条件生成不同的SQL语句,让我们能够更灵活地构建和执行数据库操作。

动态SQL在实际开发中非常有用,特别是当需要根据不同的查询条件来拼接SQL语句时。MyBatis提供了多种方式来实现动态SQL,包括使用if、choose、when、otherwise、foreach等标签。下面我们将逐一介绍这些标签的用法和示例。

下面是此文章用到的表

供货商表:

/*
 Navicat Premium Data Transfer

 Source Server         : MySql
 Source Server Type    : MySQL
 Source Server Version : 80013 (8.0.13)
 Source Host           : localhost:3306
 Source Schema         : yyds

 Target Server Type    : MySQL
 Target Server Version : 80013 (8.0.13)
 File Encoding         : 65001

 Date: 11/08/2023 16:01:17
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_supplier
-- ----------------------------
DROP TABLE IF EXISTS `t_supplier`;
CREATE TABLE `t_supplier`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '供货商ID(主键)',
  `supCode` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '供货商编码',
  `supName` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '供货商名称',
  `supDesc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '供货商描述',
  `supContact` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '联系人',
  `supPhone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '联系电话',
  `supAddress` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '地址',
  `supFax` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '传真',
  `createdUserId` bigint(20) NOT NULL COMMENT '创建人ID',
  `createdTime` date NOT NULL COMMENT '创建时间',
  `updateUserId` bigint(20) NOT NULL COMMENT '修改人ID',
  `updatedTime` date NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;

 入库记录表:

/*
 Navicat Premium Data Transfer

 Source Server         : MySql
 Source Server Type    : MySQL
 Source Server Version : 80013 (8.0.13)
 Source Host           : localhost:3306
 Source Schema         : yyds

 Target Server Type    : MySQL
 Target Server Version : 80013 (8.0.13)
 File Encoding         : 65001

 Date: 11/08/2023 16:01:28
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_storagerecord
-- ----------------------------
DROP TABLE IF EXISTS `t_storagerecord`;
CREATE TABLE `t_storagerecord`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '入库记录ID(主键)',
  `srCode` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '入库记录编码',
  `goodsName` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品名称',
  `goodsDesc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品描述',
  `goodsUnit` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品单位',
  `goodsCount` decimal(20, 2) NOT NULL COMMENT '入库数量',
  `totalAmount` decimal(20, 2) NOT NULL COMMENT '商品总额',
  `payStatus` int(11) NOT NULL COMMENT '支付状态(未支付——1 ,已支付——2)',
  `supplierId` bigint(20) NOT NULL COMMENT '供货商ID(取自供货商表) - 供货商ID',
  `createdUserId` bigint(20) NOT NULL COMMENT '创建人ID',
  `createdTime` date NOT NULL COMMENT '创建时间',
  `updatedUserId` bigint(20) NOT NULL COMMENT '修改人ID',
  `updatedTime` date NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;

偷点小懒😊我就直接将要用到的字段分别封装成不同的实体类了

1、if标签

相当于Java中的if语句

语法为:

<if  test = "条件判断,返回true或false" >
	SQL语句
</if>

需求:根据供货商ID、支付状态、商品名称(模糊查询)为条件查询入库记录表中的入库记录ID、入库记录编号、商品名称、供货商ID、供货商名称、商品总额、支付状态和创建时间

 接口中的方法:


    List<First> selectBySupplierIdAndPayStatusAndGoodsName(@Param("supplierId") Integer supplierId, @Param("payStatus") Integer payStatus, @Param("goodsName") String goodsName);

 mapper映射文件:

<select id="selectBySupplierIdAndPayStatusAndGoodsName" resultType="pojo.First">
        select sg.id,
        sg.srCode,
        sg.goodsName,
        sg.supplierId,
        sl.supName,
        sg.totalAmount,
        sg.payStatus,
        sg.createdTime
        from t_storagerecord sg
        left join t_supplier sl on sg.supplierId = sl.id
        where 1=1
        <if test="supplierId != null">
            and supplierId = #{supplierId}
        </if>
        <if test="payStatus != null">
            and payStatus = #{payStatus}
        </if>
        <if test="goodsName != null and goodsName != ''">
            and goodsName like "%"#{goodsName}"%"
        </if>
    </select>

测试:

 @Test
    public void First() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<First> Firsts= mapper.selectBySupplierIdAndPayStatusAndGoodsName(null, null, "k");
        sz1s.forEach(first-> System.out.println(first));
    }

 测试的结果为

因为我测试类中前两个参数为null所有它不会将这两个条件加进去,所有执行的sql语句为

select sg.id, sg.srCode, sg.goodsName, sg.supplierId, sl.supName, sg.totalAmount, sg.payStatus, sg.createdTime from t_storagerecord sg left join t_supplier sl on sg.supplierId = sl.id where 1=1 and goodsName like "%"?"%"

 将数据库中商品名称中包含k的记录查询出来

2、where标签

在MyBatis中,<where>标签用于在SQL语句中动态生成WHERE子句。它可以根据条件判断动态添加查询条件,并且会自动处理条件之间的逻辑关系。

使用where标签之后可以将上面语句中where条件省略

语法:

<where>
	<if test="条件判断">
		SQL语句
	</if>
	…
</where>

需求:以供货商编码(模糊查询)、供货商名称(模糊查询)为条件查询供货商表中的供货商ID、供货商编码、供货商名称、联系人、传真和创建时间字段  用if\where标签实体类:

接口中的方法:

 List<Second> selectBySupCodeAndSupName(@Param("supCode") String supCode, @Param("supName") String supName);

mapper映射文件:

<select id="selectBySupCodeAndSupName" resultType="pojo.Second">
        select id, supCode, supName, supContact, supPhone, supFax, createdTime
        from t_supplier
        <where>
            <if test="supCode != null and supCode != ''">
                and supCode like "%"#{supCode}"%"
            </if>
            <if test="supName != null and supName != ''">
                and supName like "%"#{supName}"%"
            </if>
        </where>
    </select>

测试:

 @Test
    public void Second() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<Second> seconds= mapper.selectBySupCodeAndSupName("1", "");
        seconds.forEach(second-> System.out.println(second));
    }

因为我在测试类中第二个参数给他的值为空 ,所有

执行的sql语句为:

select id, supCode, supName, supContact, supPhone, supFax, createdTime from t_supplier WHERE supCode like "%"?"%"

将数据库中供货商编码 中包含1的记录查出来

3、choose(when、otherwise)标签

是一个组合标签,通常与when、otherwise标签配合使用 类似于Java中switch语句

choose相当于switch、when相当于case\otherwise相当于default

语法为:

<choose>
	<when test="条件判断,返回true或false">
	</when>
	<when test="条件判断,返回true或false">
	</when>
	...
	<otherwise>
	</otherwise>
</choose>

需求:以供货商编码(模糊查询)、供货商名称(模糊查询)、联系人(模糊查询)创建时间为条件查询供货商id、供货商编码、供货商名称、联系人、联系电话、传真、创建时间。

供货商名称、供货商编码、联系人姓名中任意一个参数不为空时,以该非空的参数作为匹配条件进行查询,其余参数忽略 如果三个参数都为空,则使用创建时间作为匹配条件进行查询

 实体类还是上面那个Second

接口中的方法:

List<Second> selectBySupNameOrSupCodeOrSupContactOrCreatedTime(@Param("supName") String supName, @Param("supCode") String supCode, @Param("supContact") String supContact, @Param("createdTime") LocalDate createdTime);

映射文件:

<select id="selectBySupNameOrSupCodeOrSupContactOrCreatedTime" resultType="pojo.Second">
        select id, supCode, supName, supContact, supPhone, supFax, createdTime
        from t_supplier
        <where>
            <choose>
                <when test="supName != null and supName != ''">
                    and supName like "%"#{supName}"%"
                </when>
                <when test="supCode != null and supCode != ''">
                    and supCode like "%"#{supCode}"%"
                </when>
                <when test="supContact != null and supContact != ''">
                    and supContact like "%"#{supContact}"%"
                </when>
                <otherwise>
                    and createdTime = #{createdTime}
                </otherwise>
            </choose>
        </where>
    </select>

测试类:

 @Test
    public void ChooseFirst() {
        String dateString = "2006-01-27";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.parse(dateString, formatter);
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<Second> seconds= mapper.selectBySupNameOrSupCodeOrSupContactOrCreatedTime("", "1", "", localDate);
        sz23s.forEach(second-> System.out.println(second));
    }

测试sql为:

select id, supCode, supName, supContact, supPhone, supFax, createdTime from t_supplier WHERE supCode like "%"?"%"

查询数据库中供货商编码中包含1的记录

4、foreach标签

循环数组或集合,动态生成sql,通常用于in条件,通常用于批量添加和删除和查询,比如这样的SQL:

//批量删除
delete from 表名 where id in(1,2,3);
//批量新增
insert into 表名(表中的字段)values
  (值1),
  (值2),
  (值3)
//条件查询
select * from 表名 where 条件 in("","","")

语法为:

<foreach collection = "参数名称"   
               item = "元素别名" 
               open = "("
               separator = "," 
               close = ")" 
               index = "当前元素位置下标" >
	#{元素别名}
</foreach>

参数:

  1. collection:指定要遍历的集合或数组的参数名。可以是一个参数,也可以是一个Ognl表达式,用来指定要遍历的集合或数组。

  2. item:指定在遍历过程中每个元素的别名。可以在<foreach>标签内使用这个别名来引用每个元素。

  3. index:指定在遍历过程中每个元素的索引位置。可以在<foreach>标签内使用这个索引来引用每个元素的位置。

  4. open:指定遍历过程中在结果字符串的开头添加的字符串。可以用来添加一些前缀。

  5. close:指定遍历过程中在结果字符串的结尾添加的字符串。可以用来添加一些后缀。

  6. separator:指定遍历过程中每个元素之间的分隔符。可以用来指定元素之间的连接符。

需求:

第一个练习同时查询多个供货商关联的入库单列表数据 要求分别以数组、List集合为参数

第二个练习跟上面的要求差不多,参数为Map集合,和入库编码(模糊查询)

接口中的方法:

//数组方式
List<Thrid> selectAllByArray(@Param("supplierIds") Integer[] supplierIds);
//集合方式
List<Fourth> selectAllByList(@Param("supplierIds") List<Integer> supplierIds);
//Map
 List<Fifth> selectAllByMap(@Param("supplierIds") List<Integer> supplierIds, @Param("srCode") Map<String, String> srCode);

映射文件:

<select id="selectAllByArray" resultType="pojo.Thrid">
        select sg.id,
               sg.srCode,
               sg.goodsName,
               sg.goodsDesc,
               sg.goodsUnit,
               sg.goodsCount,
               sg.totalAmount,
               sg.payStatus,
               sg.supplierId,
               sg.createdUserId,
               sg.createdTime,
               sg.updatedUserId,
               sg.updatedTime
        from t_storagerecord sg,
             t_supplier sl
        where sg.supplierId = sl.id
          and sg.supplierId in
        <foreach collection="supplierIds" item="supplierId" open="(" separator="," close=")">
            #{supplierId}
        </foreach>
    </select>
    <select id="selectAllByList" resultType="pojo.Fourth">
        select sg.id,
               sg.srCode,
               sg.goodsName,
               sg.goodsDesc,
               sg.goodsUnit,
               sg.goodsCount,
               sg.totalAmount,
               sg.payStatus,
               sg.supplierId,
               sg.createdUserId,
               sg.createdTime,
               sg.updatedUserId,
               sg.updatedTime
        from t_storagerecord sg,
             t_supplier sl
        where sg.supplierId = sl.id
          and sg.supplierId in
        <foreach collection="supplierIds" item="supplierId" open="(" separator="," close=")">
            #{supplierId}
        </foreach>
    </select>
    <select id="selectAllByMap" resultType="pojo.Fifth">
        select sg.id,
        sg.srCode,
        sg.goodsName,
        sg.goodsDesc,
        sg.goodsUnit,
        sg.goodsCount,
        sg.totalAmount,
        sg.payStatus,
        sg.supplierId,
        sg.createdUserId,
        sg.createdTime,
        sg.updatedUserId,
        sg.updatedTime
        from t_storagerecord sg,
        t_supplier sl
        where sg.supplierId = sl.id
        and sg.supplierId in
        <foreach collection="supplierIds" item="supplierId" open="(" separator="," close=")">
            #{supplierId}
        </foreach>
        <!--判断了 srCode 参数是否不为 null 且 srCode Map 的大小大于 0。如果满足条件,将会拼接一个模糊查询的条件语句。-->
        <if test="srCode != null and srCode.size() > 0">
            and srCode like "%"#{srCode.srCode}"%"  <!-- srCode.get("srCode")-->
        </if>
    </select>

测试类:

 @Test
    public void Array() {
        Integer[] id = {1, 2};
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<Third> arrays= mapper.selectAllByArray(id);
        arrays.forEach(array-> System.out.println(array));
    }

    @Test
    public void List() {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<Fourth> lists= mapper.selectAllByList(integerList);
        sz45s.forEach(list-> System.out.println(list));
    }

    @Test
    public void Map() {
        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        Map<String,String> map = new HashMap<>();
        map.put("srCode","1");
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        List<Fifth> fifths= mapper.selectAllByMap(integerList, map);
        sz45s.forEach(fifth-> System.out.println(fifth));
    }

测试的sql分别为:

//数组和集合执行的
select sg.id, sg.srCode, sg.goodsName, sg.goodsDesc, sg.goodsUnit, sg.goodsCount, sg.totalAmount, sg.payStatus, sg.supplierId, sg.createdUserId, sg.createdTime, sg.updatedUserId, sg.updatedTime from t_storagerecord sg, t_supplier sl where sg.supplierId = sl.id and sg.supplierId in ( ? , ? )

//Map执行的
select sg.id, sg.srCode, sg.goodsName, sg.goodsDesc, sg.goodsUnit, sg.goodsCount, sg.totalAmount, sg.payStatus, sg.supplierId, sg.createdUserId, sg.createdTime, sg.updatedUserId, sg.updatedTime from t_storagerecord sg, t_supplier sl where sg.supplierId = sl.id and sg.supplierId in ( ? , ? ) and srCode like "%"?"%"

数组和集合查询供货商ID为(1,2)的数据

Map查询供货商ID为(1,2)并且入库编码中含1的数据

5、set标签

简化SQL语句中set子句处理 智能忽略更新语句尾部多出来的逗号

语法:

<set>
	<if test="条件判断">
		SQL语句
	</if>
	…
</set>

需求:更新供货商表中id为1的供货商名称 供货商描述 联系电话 其余字段的值保持不变

接口中的方法:

Integer update(Sixth sixth);

映射文件:

<update id="update" parameterType="pojo.Sixth">
        update t_supplier
        <set>
            <if test="supName != null">supName = #{supName},</if>
            <if test="supDesc != null">supDesc = #{supDesc},</if>
            <if test="supPhone != null">supPhone = #{supPhone},</if>
        </set>
        where id = #{id}
    </update>

测试类:

  @Test
    public void Set() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        Sixth sixth= new Sixth(2,"杨俊豪","不晓得是什么东西","13838389438");
        Integer update = mapper.update(sz6);
        System.out.println(update);
        sqlSession.commit(); //增删改一定要记得调用commit(提交)!!!
    }

因为我测试类中参数是全部填写了的所有就将三个值全部修改了

6、trim标签

动态地为SQL语句添加前后缀 智能忽略标签前后多余的and、or或逗号等字符

语法:

<trim prefix = "前缀" 
	  suffix = "后缀" 
	  prefixOverrides = "忽略前缀" 
	  suffixOverrides = "忽略后缀" >
	…
</trim>
  • prefix:指定在SQL语句片段的开头添加的字符串。
  • prefixOverrides:指定需要移除的SQL语句片段的前缀字符串。
  • suffix:指定在SQL语句片段的结尾添加的字符串。
  • suffixOverrides:指定需要移除的SQL语句片段的后缀字符串。

需求:跟上面set标签中的需求一样,只不过是用trim修改下

Integer updateByTrim(Sixth sixth);

映射文件:

<update id="updateByTrim" parameterType="Sixth">
        update t_supplier
            <trim prefix="SET" suffixOverrides="," suffix="where id = #{id}">
                <if test="supName != null">
                    supName = #{supName},
                </if>
                <if test="supDesc != null">
                    supDesc = #{supDesc},
                </if>
                <if test="supPhone != null">
                    supPhone = #{supPhone},
                </if>
            </trim>
    </update>

测试类:

 @Test
    public void Trim() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        Sixth sixth = new sixth(2,"杨俊豪","母鸡啊","13838389438");
        Integer a = mapper.updateByTrim(sixth);
        System.out.println(a);
        sqlSession.commit();
    }

结果跟上面set标签一样

7.Mybatis分页功能实现

关键字:limit

pageBegin:页码起始位置

pageSize:每页展示的数据量

需求:分页查询供货商表和入库记录表,条件是根据供货商名称模糊查询、查询结果以创建时间降序排列

接口中的方法:

List<Seventh> selectLimit(@Param("supName") String supName, @Param("pageBegin") Integer pageBegin, @Param("pageSize") Integer pageSize);

映射文件:

<select id="selectLimit" resultType="pojo.Seventh">
        select sl.id,
               sl.supCode,
               sl.supName,
               sl.supDesc,
               sl.supContact,
               sl.supPhone,
               sl.supAddress,
               sl.supFax,
               sl.createdUserId,
               sl.createdTime,
               sl.updateUserId,
               sl.updatedTime,
               sg.srCode,
               sg.goodsName,
               sg.goodsDesc,
               sg.goodsUnit,
               sg.goodsCount,
               sg.totalAmount,
               sg.payStatus
        from t_supplier sl
                 left join t_storagerecord sg on sl.id = sg.supplierId
        <trim prefix="where" prefixOverrides="and | or">
            <if test="supName != null and supName != ''">
                supName like "%"#{supName}"%"
            </if>
        </trim>
        order by sl.createdTime desc
        limit #{pageBegin},#{pageSize}
    </select>

测试类:

@Test
    public void Limit() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        SzMapper mapper = sqlSession.getMapper(SzMapper.class);
        Integer pageIndex = 1;
        Integer pageSize = 2;
        Integer pageBegin = (pageIndex -1) * pageSize;
        List<Seventh> sevenths= mapper.selectLimit("杨", pageBegin, pageSize);
        sz8s.forEach(seventh-> System.out.println(seventh));

    }

执行的sql为

select sl.id, sl.supCode, sl.supName, sl.supDesc, sl.supContact, sl.supPhone, sl.supAddress, sl.supFax, sl.createdUserId, sl.createdTime, sl.updateUserId, sl.updatedTime, sg.srCode, sg.goodsName, sg.goodsDesc, sg.goodsUnit, sg.goodsCount, sg.totalAmount, sg.payStatus from t_supplier sl left join t_storagerecord sg on sl.id = sg.supplierId where supName like "%"?"%" order by sl.createdTime desc limit ?,?

8、sql标签与include标签

sql标签用来声明sql片段

include标签用来将声明的sql片段包含到某个sql语句当中

作用:代码复用。易维护。

语法:

<sql id="sql_fragment_id">
    -- SQL语句片段
</sql>
<include refid="sql_fragment_id" />

下面是一个例子,与上面的表无关

<sql id="carCols">
<!--定义要查的字段-->
id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType
</sql>

<select id="selectAllRetMap" resultType="map">
  select <include refid="carCols"/> from t_car
</select>

<select id="selectAllRetListMap" resultType="map">
  select <include refid="carCols"/> carType from t_car
</select>

<select id="selectByIdRetMap" resultType="map">
  select <include refid="carCols"/> from t_car where id = #{id}
</select>

通过以上示例,我们可以看到MyBatis动态SQL的强大之处。我们可以根据不同的条件灵活地构建SQL语句,而无需手动拼接字符串,大大提高了开发效率和代码的可读性。

总结起来,MyBatis中的动态SQL是一项非常强大和实用的功能,能够帮助我们更轻松地构建和执行数据库操作。通过使用if、choose、when、otherwise、foreach等标签,我们可以根据不同的条件生成不同的SQL语句,让数据库操作更加灵活和高效。

ok,今天的分享就到此结束了,希望以上内容对你有所帮助

关注博主不迷路,期待你的关注!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值