JAVA-JDBC: (2) 数据库的粗略的CRUD及SQL注入问题

Java代码审计之JDBC中的sql注入 java代码审计系统课程--代码审计视频教程-信息安全-优快云程序员研修院少写“漏洞” 了解常见代码安全 提升代码安全能力 代码不被黑客黑-https://edu.youkuaiyun.com/course/detail/32634 漏洞原理: 在常见的web漏洞中,SQL注入漏洞较为常见,危害也较大。攻击者一旦利用系统中存在的SQL注入漏洞来发起攻击,在条件允许的情况下,不仅可以获取整站数据,还可通过进一步的渗透来获取服务器权限,从而进入内网。 注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条 阅读详情

1. 数据库的CRUD操作

对数据的增删改查操作变化最大的莫过于对SQL语句的改变、首先我们简单的看下ORACLE中增删改查的SQL语句的简单写法:

1.1 C (Create) 对应 oracle中的 insert语句。

(1)、所有字段都插入:

insert into student values('A001','张三','男','01-5月-05',10);

注释: oracle中默认的日期格式’DD-MON-YY’修改日期的默认格式:

alter session set nls_date_format = 'yyyy-mm-dd'

(2)、插入部分字段:

insert into student(xh,xm,sex) values('2','八路','男‘);

(3)、插入空值:

insert into student(xh,xm,sex,birthday) values('3','Jhone','男',null)
1.2 R(Read) 对应 oracle中的 select 语句。

select查询SQL格式:

select···from···where···group by···having···order by···;
        SELECT子句                --指定查询结果集的列
        FROM子句                  --指定查询来自哪个表或者试图
        [WHERE 子句]              --指定查询的条件
        [GROUP BY 子句]           --指定查询结果集的分组的条件
        [HAVING 子句]             --指定分组或者集合的查询条件
        [ORDERBY 子句]            --对查询的排列顺序
        [UNION 子句]              --多个SELET语句组合,得到结果集的并集

(1)、查询所有的用户:

select * from t_user;

★: 在oracle中这里的表名用别名时不能加as关键字 如:

 select * from t_user u;  正确
 select * from t_user as u;  错误

(2)、查询指定的列:

select username, sex from t_user;

(3)、as给列以别名显示:

select username as 用户名 from t_user;(这里的as关键字可以省略)

(4)、去掉重复的行 distinct:

select distinct username from t_user;

(5)、使用运算符:

select age+10, sex from t_user; (给每个年龄加10岁)

(6)、连接字符串:

select '用户名:' || username from t_user;(Oracle用||做连接字符串操作符);

(7)、where 子句:

select * from t_user where username = '宝宝'; 

(8)、在什么之间 between….and:

select * from t_user where userid between 9 and 10;
select * from t_user where userid >=9 and userid <=10;

(9)、in匹配集合中的任意值:

select * from t_user where username in('马文涛','宝宝'); 

(10)、like模糊查询:

select * from t_user where username like '%涛%'; 

注释 通配符含义:

    %:包含零个或者多个任意字符的字符串
    _:任意单个字符
    ?:任意单个字符 (啥时候用?在LIKE子句中怎么用?)
    #:表示0-9的数字(啥时候用?在LIKE子句中怎么用?)
    []:指定范围或者集合中的任意单个字符,例如[a-f]表示a~f中的一个字符

(11)、null判断某列为空:

select * from t_user where sex is null; 
(这里用is,不能用=,如果要返回不为null的记录就可以用is not null) 

(12)、order by排序:ASC: 升序排列(可以省略),DESC: 降序排列:

select u.userid,u.username from t_user u order by u.userid;
select u.userid,u.username from t_user u order by u.userid desc; 

(13)、group by分组 (分组了就不能直接返回*,经常和聚合函数count(age)一起使用)

按姓名分组,并统计每组人数:select count(*),username from t_user group by username;
根据多个字段分组: select username,age,count(*) from t_user group by username,age;

注释: group by有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面
(14)、having 过滤分组:

select username from t_user group by username having count(*)>2; 

(15)、子查询:
<1>子查询放在select后面,作为其中的一个字段返回。

select u.username,(select d.departname from t_depart d where d.departid = u.departid) from t_user u;

<2>子查询放在from后面,作为一张临时表。

 select * from (select username,sex s from t_user where departid=1) where s = '男';

<3>子查询放在where后面,作为条件的一部分。

select * from t_user where departid = (select departid from t_depart where departname = '财务部');

(16)、联合查询:
<1>等值连接(内连接):

select u.username,d.departname from t_user u,t_depart d                     where u.departid = d.departid;

<2>外连接:即把不满足条件的记录也返回,用个+就行了,
(+)操作符在哪边就代表另外一边不满足联合条件的记录可以被输出。这个感觉不太常用。

select b.book_id,b.book_name from book_info as b,book_click_num as c where b.book_id = c.book_id(+);    
1.3 U (Update)对应oracle中的 update 语句

(1)、修改一个字段:

update student set sex ='女' where xh = '2';

(2)、修改多个字段:

update student set set ='男', birthday ='1998-09-19' where xh ='2';
update student set name = '争伟',sex = '男';
(更新时不加条件表中所有行记录的姓名都被修改了!)
1.4 D (Delete) 对应oracle 中的 delete 和 drop 语句

delete from student;
只删除所有记录,表结构还在,写日志可以恢复,速度慢,例如:
第一步 早上工作时候建立一个保存点
savapoint first;
第二步:不小心出错,或者用了delete from student
第三步:回滚

roolback to first;
drop table student;  删除表的结构和数据;     
delete from student where xh ='2';  删除一行记录
truncate table student;     删除表中的所有记录,表的结构还在 但是不写日志,无法找回数据;速度快;

2. CRUD对应JDBC语句:

  • 增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。

  • 查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对与增、删、改要复杂一些,因为有查询结果要处理。

3. SQL注入问题:

在SQL中包含 特殊字符 或 SQL的关键字(如:’ or 1 or ‘)时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
PreperedStatement(从Statement扩展而来)相对Statement的优点:

  1. 没有SQL注入的问题。

  2. Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。

  3. 数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。

    具体示例,可参考:sql注射示例

4. CRUD相应的粗略JDBC代码


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCCRUD {
    /**
     * 应该 int create(Stu student) throw SQLException{}
     * 这里简化不封装对象了;
     * @return
     * @throws SQLException
     */
    static int create() throws SQLException{
        int numOfResult =0;
        Connection conn = null;
        PreparedStatement ps = null;
        String sql;
        try{
            //注册驱动建立连接
            conn = JDBCUtils.getConnection();
            sql = "insert into stu values('S151208', 'wangwu', 'nan', 79, null)";
            ps = conn.prepareStatement(sql);
            numOfResult = ps.executeUpdate();
        }finally{
            JDBCUtils.free(null, ps, conn);
        }
        return numOfResult;
    }

    static void read(String stuId) throws SQLException{
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        String sql;
        try{
            //注册驱动建立连接
            conn = JDBCUtils.getConnection();
            sql = "select * from stu where stuid = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, stuId);
            rs = ps.executeQuery();
            while(rs.next()){
                System.out.println(rs.getObject("STUID")+"\t"
                        + rs.getObject("STUNAME")+"\t"
                        +rs.getObject("SEX"));
            }
        }finally{
            JDBCUtils.free(rs, ps, conn);
        }
    }

    static int update(int score, String stuId) throws SQLException{
        int numOfResult =0;
        Connection conn = null;
        PreparedStatement ps = null;
        String sql;
        try{
            //注册驱动建立连接
            conn = JDBCUtils.getConnection();
            sql = "update stu set score = ? where STUID= ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, score);
            ps.setString(2, stuId);
            numOfResult = ps.executeUpdate();
        }finally{
            JDBCUtils.free(null, ps, conn);
        }
        return numOfResult;
    }

    static int delete(String stuId) throws SQLException{
        int numOfResult =0;
        Connection conn = null;
        PreparedStatement ps = null;
        String sql;
        try{
            //注册驱动建立连接
            conn = JDBCUtils.getConnection();
            sql = "delete from stu where stuid = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, stuId);
            numOfResult = ps.executeUpdate();
        }finally{
            JDBCUtils.free(null, ps, conn);
        }
        return numOfResult;
    }

    static void readSQLInject(String stuId) throws SQLException{
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        String sql;
        try{
            //注册驱动建立连接
            conn = JDBCUtils.getConnection();
            sql = "select * from stu where stuid = '"+stuId+"'";
            System.out.println(sql);
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getObject("STUID")+"\t"
                        + rs.getObject("STUNAME")+"\t"
                        +rs.getObject("SEX"));
            }
        }finally{
            JDBCUtils.free(rs, st, conn);
        }
    }

    public static void main(String[] args) throws SQLException {

        int num = create();
        System.out.println("num :"+ num);

        read("S151208");

        int num2 = update(100,"S151201");
        System.out.println("num :"+ num2);

        delete("S151208");
        readSQLInject("' or 1=1 or stuid='");

    }

}

注释: 上面涉及到JDBCUtils类 见博客JAVA-JDBC:(1)中。

idea操作jdbc(CRUD、SQL注入、预编译) 2)在idea中新建lib目录存放jar包(需右击add as library)3)编码测试,测试插入一条数据。CRUD操作-create。CRUD操作-update。CRUD操作-delete。1)提取配置信息(解耦合)CRUD操作-read。 阅读详情

相关推荐

【“中间商赚钱秘籍“】——JDBC实现对数据库的CRUD操作

秘籍目录一级目录二级目录三级目录 一级目录 二级目录 三级目录

生活很苦,但学习还得继续 320

JAVA代码审计之SQL注入

本章节课程主要从以下三方面详细的介绍了如何针对java代码中sql注入的审计方法及黑盒验证:1、JDBC连接方式下sql注入的存在的形态及修复方法,like、in情况在如何安全使用预处理来防范sql注入2、在使用Mybatis框架下如何审计sql注入代码,并详细的介绍了如何编写安全的数据库查询语句。3、在使用Hibernate框架下如何审计sql注入代码。并详细介绍了如何编写安全的数据库查询语句。

Java数据库操作实战教程:CRUD及MyBatis框架集成

Java数据库连接(JDBC)是一个Java API,它允许Java程序执行SQL语句。JDBC接口为数据库编程提供了一种标准的方法,使得开发者可以以一致的方式连接多种数据库。JDBC API主要负责SQL语句的发送和结果集的处理。// 一个简单的JDBC连接示例代码try {// 加载数据库驱动// 建立数据库连接// 创建执行SQL语句的Statement对象// 执行SQL查询并获取结果集// 处理结果集// 更多字段...// 关闭资源,释放连接。

weixin_35972981的博客 815

JAVA代码审计之SQL注入,基于Spring boot和jdbc以及mybatis

本节讲述JavaWeb代码审计中存在SQL注入漏洞的情况。基于spring boot,mysql,两种连接方式:jdbc和mybatis。代码比较多,适合自己创建项目,跟着走一遍,如果只想了解原理,可以忽略代码,只看大概即可。比如Controller类或者sql语句的编写。SQL注入漏洞是对数据库进行的一种攻击方式。其主要形成方式是在数据交互中,前端数据通过后台在对数据库进行操作时,由于没有做好安全防护,导致攻击者将恶意代码拼接到请求参数中,被当做SQL语句的一部分进行执行,最终导致数据库被攻击。

GXcodes的博客 4399

深入解析ISO12233标准:SFR算法从理论到代码实现

本文深入解析ISO12233标准中的SFR算法,从理论到代码实现全面介绍如何量化成像系统的解析力。通过e-SFR算法测量边缘扩散函数(ESF)和空间频率响应(SFR),结合光学原理和实际代码示例,帮助开发者准确评估影像质量。文章包含关键步骤的Python实现和工程优化技巧,适用于相机测试、镜头评估等应用场景。

weixin_29200485的博客 154

复现《水化硅铝酸钙微结构和性能的分子动力学模拟研究》的分子动力学模拟

本文详细复现了杨军博士论文中关于水化硅铝酸钙(C-A-S-H)凝胶的分子动力学模拟方法。研究内容包括:1)基于11Å Tobermorite构建C-A-S-H分子模型,通过缺陷引入和Al掺杂调节Ca/Si比;2)使用ReaxFF力场模拟交联C-A-S-H的结构与力学性能;3)采用ClayFF力场研究纳米孔道中水和离子传输行为。研究提供了完整的LAMMPS输入脚本、Python分析代码和力场参数设置,为水泥基材料纳米尺度模拟提供可复现的技术方案。

huanghm88的专栏 104

jdbc——sql注入

在用户输入的数据中有SQL关键字或语法,并且关键字或语法参与了SQL语句的编译。导致SQL语句编译后的条件为true,一直得到正确的结果。这种现象就是SQL注入。上面案例代码中,当你的用户名为 abc' or 1=1;# 密码为123,拼接到SQL语句中,变成如下效果:此SQL语句or 后面1=1永远正确,#后面的成了注释,所以这条语句会将表中所有的数据查询出来,然后再做数据判断的时候,就会得到正确结果,从而说用户名和密码正确,登录成功。

m0_72960906的博客 1103

国科大学习资料--人工智能原理与算法-2021年期末考试题解析(学长整理)

国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 根据学弟的反馈,该年的期末题只有5道,且均是作业题(所以大家一定要积极完成作业,考前多做几遍!!!!) 下面解析: 3.25 由于该题,我没有做过,所以只能给你英文版的答案。答案如下,其他的题目答案都是中文版。 5.9 8.10 12.20 15.13 ...

无名何许人的博客 3978

JAVA连接数据库(JDBC)连接操作,CRUD 操作,SQL注入问题解决方案

简介 JDBC(Java DataBase Connectivity,java数据库连接) 我们学习的技术是JDBC 不是 MYSQLJDBC 也不是 ORACLE JDBC JDBC是一套标准,是Java与各大数据库厂商共同定制的一套接口. 这套接口由各大数据库厂商进行了实现. 是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。 J

weixin_51426897的博客 2035

【Unity 实用工具篇】| Unity中 实现背景模糊效果,简单易用

背景模糊 是一个很实用的功能,它可以帮助游戏在视觉上有更好的专注力和表现力。 实现模糊的种类和方式有很多种,大家自行选择适合自己的就可以了。 下面一起来看下本文实现背景模糊的效果和使用方式吧!

努力前行,总会成为自己心中的那道光 4万+

在Simulink中实现一个基于SiC MOSFET的高效率电机驱动系统

本文介绍了在Simulink中构建基于SiC MOSFET的高效率电机驱动系统的详细流程。系统由直流电源模块、SiC MOSFET逆变器模块、PMSM电机模型、控制策略模块(包括矢量控制和PWM生成)以及反馈测量模块组成。文章逐步指导了从模型创建到参数设置的完整过程,包括各模块的具体实现方法。通过仿真可以评估系统在不同负载条件下的响应速度、效率、功率密度等性能指标。该建模方法为电机驱动系统的设计和优化提供了有效工具,同时建议根据实际硬件规格和工程需求进行参数调整和定制化开发。

xiaoheshang_123的博客 248

JDBC从入门到熟练使用——功能类详解、增删改查(CRUD)、sql注入、事务、连接池

一、JDBC入门 1.jdbc的概念 JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。 JDBC的作用:可以通过java代码操作数据库 2.jdbc的本质 其实就是java官方提供的一套规范(接口)。用于帮助开发人员快速实现不同关系型数据库的连接! 3.jdbc的快速入门程序 导入jar包 注册驱动 Class.forName("c

weixin_45195665的博客 8万+

我的python学习之路

Python 是一门功能强大且易于学习的编程语言,广泛应用于数据分析、人工智能、Web 开发、自动化等领域。以下是一个 Python 学习路径的总结,帮助你系统地掌握 Python 编程。

数据知道的博客 3万+

JDBC? Java Database Connectivity(Java语言连接数据库)

JDBC课堂笔记 1、什么是JDBC? Java DataBase Connectivity 在java语言中编写sql语句,对mysql数据库中的数据进行CRUD操作。 2、JDBC相关的类库在哪里? java.sql.*; 3、JDBC本质上是一堆什么呢? java.sql.*; 这个包下都是JDBC的接口,SUN公司制定的! JDBC是体现“接口作用”的非常经典的例子。 JDBC降低了耦合度,提高了扩展力。 对于java程序员来说,不需要关心数据库是哪个品牌。只要面向JDBC接口编程就行! JDBC整

途中的博客 1万+

C# 动态壁纸实战:7步带你从零开始制作动态壁纸

动态壁纸是指在计算机桌面上播放视频、动画或交互式内容的一种技术。与传统的静态壁纸相比,动态壁纸更加生动有趣,可以大大提升桌面的观赏性和互动性。通过本文的详细讲解和代码示例,相信你已经学会了如何使用C#实现动态壁纸。动态壁纸不仅能够提升桌面的美观度,还能展示你的编程技能。希望这篇教程对你有所帮助,期待你在C#编程中取得更大的成就!🌟✨如果你有任何问题或建议,欢迎在评论区留言交流!希望这篇教程对你有所帮助,期待你在C#编程中取得更大的成就!😊✨😊✨。

java专栏 1672

QCM2290 PM-3 如何让mirco-usb支持关机充电

PM4125-3插入type-C触发开机进入关机充电的CC脚中断条件是否可以软件上屏蔽, 做到只通过VBUS中断即可触发进入关机充电模式,达到和PM4125-2的效果一样只要插入micro USB 就可以触发进入关机充电模式。硬件团队提议修改寄存器 SCHG_L_MISC_SYSOK_CFG 0x164A bit[4] 目前修改如下 — a/BOOT.XF.4.1/boot_images/QcomPkg/Library/PmicLib/target/Agatti_pmCocos/psi/pm_confi

墨染天玑的博客 441

Java连接mysql数据库

JDBC连接,SQL注入以及如何解决SQL注入问题

qq_46480020的博客 3万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

JDBC JAVA连接数据库(黑马程序员)

把数据保存到可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存到硬盘上加以”固化”,而持久化的实现过程大多通过各种关系数据库来完成。持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、XML数据文件中。JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,()使用这些类库可以以一种标准。

F2022697486的博客 1920

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

JDBC实现CRUD操作

目录 前言 一、JDBC介绍 1、概念 2、关系 3、优点 二、JDBC编程步骤 1、导包 2、获取连接 2.1创建配置文件 2.2数据连接方式(通用格式) 3、实现CRUD操作 3.1为什么要替换? 3.2使用PreparedStatement实现增、删、改操作 3.3使用PreparedStatement实现查询操作 4、资源释放 三、JDBC API 总结 前言 前面介绍了MySQL基本的增删改查操作,那么如何在java中来实现对数据库的数据操作呢!本编介绍的JDB

shmilyche的博客 2241

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

数据库驱动和JDBC

Java提供操作数据库的规范(接口),将规范给各大数据库厂商。各大数据库厂商实现规范(接口),广大Java程序员学习规范,。 maven官网: https://mvnrepository.com/artifact/mysql/mysql-connector-java mysql官网: https://dev.mysql.com/downloads/connector/j/ 1.3.2 导入数据库驱动 1.3.2.1 方式一:创建lib导入 在项目下新建lib文件夹,将数据库驱动放入,鼠标右键点击选择添加到库

希望有点用 5032

MySQL使用JDBC实现CRUD

JDBC概述和CRUD 回顾 1 数据完整性 :数据的正确性。 实体完整性: 主键约束:不能重复,不能为为null 唯一约束: 不能重复 ,可以为null 自动增长: auto_increment, 默认从1 开始每次增长1 域完整性: 数据类型: int double double(5,2) decimal(5,2); ...

♾️ 2240

JDBC详解(三):使用PreparedStatement实现CRUD操作(超详解)

⭕ 可以通过调用Connection对象的方法获取对象⭕接口是Statement的子接口,它表示一条预编译过的 SQL 语句⭕对象所代表的 SQL 语句中的参数用问号(?)来表示,调用对象的setXxx()方法来设置这些参数。setXxx()方法有两个参数,第一个参数是要设置的SQL语句中的参数的索引(从1开始),第二个是设置的SQL。

weixin_52533007的博客 2087

java与数据库连接学习,JDBC

JDBC(Java DataBase Connectivity)是 Java 用于数据库访问的应用程序 API 接口,由一系列 Java 类和接口构成。它提供了统一的语法来操作多种关系型数据库,屏蔽了不同数据库操作语言的差异。这意味着开发人员无需为每种数据库编写特定的访问程序,大大提高了数据库访问的通用性和便利性。无论使用 MySQL 还是 Oracle 数据库,都可以使用相同的 JDBC 代码结构进行连接和操作,只需要更换对应的数据库驱动和连接信息。

mhjnmh的博客 1556

JDBC概述和CRUD

JDBC概述和CRUD 今日内容 1.JDBC简介 2.JDBC执行DQL语句 3.JDBC执行DML语句 4.JDBC执行DDL语句 5.JDBC的Connection、Statement、ResultSet 6.PreparedStatement的使用 教学目标 1.了解JDBC简介 2.掌握JDBC执行DQL语句 3.掌握JDBC执行DML语句 4.了解什么是SQL注入 5.掌握PreparedStatement的使用 第一节 关于JDBC的简介 1.1 简介 JDBC(java Database

qq_41861690的博客 325

Java——JDBC(Java DataBase Connectivity)数据库连接技术

Java——JDBC(Java DataBase Connectivity)数据库连接技术

程序员阿龙的博客 1118
上一篇: JAVA-JDBC: (1) java连接数据库的粗略步骤
下一篇: JAVA-JDBC: (3)操作日期类型和CLOB、BLOB类型
Coder-Qian
博客等级 码龄11年 63粉丝 73原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值