框架搭建-Spring+Hibernate

使用maven的pom.xml导入Jar包

1、需要导入Spring所需的Jar包、Hibernate相关的Jar包
//Spring所需的Jar包
spring-beans、spring-context、spring-core、spring-orm、spring-tx
//Hibernate相关的Jar包
antlr、classmate、dom4j、hibernate-core、hibernate-jpa、jandex、javassist、jboss-logging、jboss-transaction
//数据库连接Jar包
mysql-connector-java
//数据库连接池jar包
com.mchange.C3P0
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.zbt</groupId>
  <artifactId>environment_springhibertnate</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>environment_springhibertnate</name>
  <url>http://www.example.com</url>

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

  <dependencies>
    <!-- hibernate 需要的12个jar包
    antlr、classmate、dom4j、hibernate-core、hibernate-jpa
    jandex、javassist、jboss-logging、jboss-transaction、mysql、-->

    <dependency>
      <groupId>antlr</groupId>
      <artifactId>antlr</artifactId>
      <version>2.7.7</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml</groupId>
      <artifactId>classmate</artifactId>
      <version>1.3.0</version>
    </dependency>

    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.15.Final</version>
    </dependency>

    <dependency>
      <groupId>org.hibernate.javax.persistence</groupId>
      <artifactId>hibernate-jpa-2.1-api</artifactId>
      <version>1.0.0.Final</version>
    </dependency>

    <dependency>
      <groupId>org.jboss</groupId>
      <artifactId>jandex</artifactId>
      <version>2.0.3.Final</version>
    </dependency>

    <dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.22.0-GA</version>
    </dependency>

    <dependency>
      <groupId>org.jboss.logging</groupId>
      <artifactId>jboss-logging</artifactId>
      <version>3.3.1.Final</version>
    </dependency>

    <dependency>
      <groupId>org.jboss.spec.javax.transaction</groupId>
      <artifactId>jboss-transaction-api_1.1_spec</artifactId>
      <version>1.0.1.Final</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.44</version>
    </dependency>

    <!-- 配置com.mchange/c3p0连接池 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>


    <!--配置Spring相关的Jar包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.0.6.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.6.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.6.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.0.6.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.6.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
  </build>
</project>

2、Hibernate映射文件

2.1、编写Student类实体类
public class Student
{
    private int id;
    private String firstName;
    private String lastName;
    private String address;
    private String phone;

    public Student() {
    }

    public Student(int id,String firstName,String lastName,String address,String phone){
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
        this.phone = phone;
    }
    //省略了属性的getters方法和setters方法以及toString方法
}
2.2、Hibernate的映射文件Student.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zbt">
    <class name="Student" table="student">
        <id name="id" column="id">
            <generator class="identity"/>
        </id>
        <property name="firstName" column="firstname"/>
        <property name="lastName" column="lastname"/>
        <property name="address" column="address"/>
        <property name="phone" column="phone"/>
    </class>
</hibernate-mapping>
2.3、数据库配置文件–jdbc.properties
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/pagination
jdbc.user=root
jdbc.password=?????

3、Spring上下文配置

3.1、数据库接入层代码
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by luckyboy on 2018/6/29.
 */

public class StudentDao {

    private SessionFactory sessionFactory;

    public StudentDao(SessionFactory sessionFactory){
        this.sessionFactory = sessionFactory;
    }
}
3.2、配置文件applicationConfig.xml
  • 3.2.1、使用c3p0配置数据源
    <!-- 使用配置文件的方式需要指明配置文件jdbc.properties的位置-->
    <context:property-placeholder location="classpath:/jdbc.properties"/>
    <!--使用c3p0数据源配置数据库连接的相关信息-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
  • 3.2.2、将数据源注入到SessionFactory当中
<!--使用hibernateProperties + DataSource的方式取代hibernate.cfg.xml文件-->
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>Student.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
            </props>
        </property>
    </bean>
  • 3.2.3、将sessionFactory注入到StudentDao中
//第一种方式:这里使用的是配置的方式将SessionFactory注入StudentDao中
<bean id="studentDao" class="com.zbt.StudentDao">
        <constructor-arg name="sessionFactory" ref="mySessionFactory"/>
</bean>

//第二种方式:使用注解的方式在StudentDao类上添加@Repositroy、在SessionFactory属性上添加@Autowired
@Repository(value="studentDao")
public class StudentDao {
    @Autowired
    private SessionFactory sessionFactory;
}

  • 3.2.4、配置Spring事务管理
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
</bean>
  • 3.2.5、配置包扫描和注解驱动(因为使用了@Transactional注解)
<context:component-scan base-package="com.zbt"/>
<tx:annotation-driven/>
  • 3.2.6、最终的Spring上下文配置文件applicationConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd ">
    <!--使用c3p0配置 使用配置文件的方式需要指明配置文件的位置-->
    <context:component-scan base-package="com.zbt"/>
    <tx:annotation-driven/>
    <context:property-placeholder location="classpath:/jdbc.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--使用hibernateProperties + DataSource的方式取代hibernate.cfg.xml文件-->
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>Student.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
            </props>
        </property>
    </bean>
    <bean id="studentDao" class="com.zbt.StudentDao">
        <constructor-arg name="sessionFactory" ref="mySessionFactory"/>
    </bean>
   <!--将事务交给Spring管理-->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
</beans>

上面就是所做的就是环境搭建完成了。下面使用Hibernate的查询语句进行增删改查操作

4、Hibernate查询语句

在StudentDao中添加Hibernate查询方法,在TestStudent中添加测试方法

4.1、实现添加一个Student对象到数据库中
    /**
    * 使用Session.save(Object object)方法保存某一个对象到数据库中
    * @param stu
    */
    @Transactional
    public void saveStudent(Student stu){
        this.sessionFactory.openSession().save(stu);
    }

测试代码

    @Test
    public void testSaveStudent(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        Student stu = new Student(1,"YU","Delaing","HeNan","1345678912");
        stuDao.saveStudent(stu);
    }

输出结果

Hibernate: insert into student (firstname, lastname, address, phone) values (?, ?, ?, ?)
4.2、更新Student的某一个属性
    /**
     * 根据旧的用户名更改成新的用户名
     * @param newName
     * @param oldName
     */
    @Transactional
    public void updateStudent(String newName,String oldName){
        String hqlUpdate="update Student s set s.firstName= :newName where s.firstName = :oldName";
        this.sessionFactory.getCurrentSession().createQuery(hqlUpdate).
                setParameter("newName",newName).
                setParameter("oldName",oldName).executeUpdate();
    }

测试代码

    @Test
    public void testUpdateStudentFisrtName(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        String newFirstName = "Zou";
        String oldFirstName = "Yu";
        stuDao.updateStudent(newFirstName,oldFirstName);
    }

输出结果

Hibernate: update student set firstname=? where firstname=?
4.3、根据Student属性查询
    /**
     * 根据用户的id进行查询,返回一个Student对象,如果不存在则返回null
     * 下面使用了两种通过id查询用户的方式,第一种是通过
     * 第一种:Session.get(Class<T> class,Serializable id)这种方式只适合用于对id进行查询
     * 第二种:createQuery(hql).setParameter(int position,Object val)注意这里的position的位置是从0开始的;适合对多个属性进行联合查询
     * @param id
     * @return
     */
    @Transactional
    public Student getStudentById(int id){
        String sql = "select student from Student  student where id= :id";
        return (Student) this.sessionFactory.getCurrentSession().createQuery(sql,Student.class).setParameter("id",id).uniqueResult();

    }

测试代码

    @Test
    public void testGetStudentById(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        Object object = stuDao.getStudentById(10);
        System.out.println(object.toString());
    }

输出结果

Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ where student0_.id=?
Student{id=10, firstName='Zhao', lastName='Gao', address='Hunan', phone='12345678912'}
4.5、删除Student信息
    /**
     * 通过firstName来删除数据库中对应的数据
     * @param firstName
     */
    @Transactional
    public void deleteStudentByFirstName(String firstName){
        String sql = "delete from Student student where student.firstName=:firstName";
        this.sessionFactory.getCurrentSession().createQuery(sql).setParameter("firstName",firstName).executeUpdate();
    }

测试代码

    @Test
    public void testdeleteStudentByFirstName(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        stuDao.deleteStudentByFirstName("Zou");

    }

输出结果

Hibernate: delete from student where firstname=?
4.6、查询所有的Student信息
    /**
     * 使用Session.createQuery(String sql)的方式进行查询,
     * 返回一个Query,调用Query.list() 方法返回Student对象
     * 注意:from子句后面跟的是我们Student这个类的类名,而不是数据库名
     *
     * @return
     */
    @Transactional
    public List<Student> queryStudent(){
        String sql="select student from Student student";
        Query query = this.sessionFactory.getCurrentSession().createQuery(sql);
        return query.list();
    }

测试代码

    @Test
    public void queryStudentByHql(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);

        List<Student> strList = stuDao.queryStudent();
        if(strList != null){
            for(Student str: strList){
                System.out.println(str.toString());
            }
        }else{
            System.out.println("strList is null");
        }
    }

输出结果

Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_
Student{id=4, firstName='Wu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=5, firstName='Zhou', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=6, firstName='Sun', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=7, firstName='Li', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=8, firstName='Liu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=9, firstName='Wang', lastName='Tao', address='Hunan', phone='12345678912'}
Student{id=10, firstName='Zhao', lastName='Gao', address='Hunan', phone='12345678912'}
Student{id=11, firstName='Li', lastName='Mazi', address='Hunan', phone='12345678912'}
Student{id=12, firstName='Zhang', lastName='Mazi', address='Hunan', phone='12345678912'}
Student{id=13, firstName='Zheng', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=14, firstName='Wang', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=15, firstName='Zeng', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=16, firstName='Qiu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=17, firstName='Dan', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=18, firstName='Hua', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=19, firstName='Mao', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=20, firstName='Li', lastName='Feng', address='GuangXi', phone='12345678998'}
Student{id=28, firstName='Zou', lastName='Delaing', address='HeNan', phone='1345678912'}
4.7、如果返回的我们查询的对象不存在,返回的List对象不是Null
    @Transactional
    public List<Student> queryStudentByLastName(String lastName){
        String hql = "select s from Student as s where lastName= :lastName";
        return (List<Student>) this.sessionFactory.getCurrentSession().createQuery(hql).setParameter("lastName",lastName).list();
    }
    @Test
    public void testQueryStudentByLastName(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        List<Student> list = stuDao.queryStudentByLastName("Die");
        if(list == null){
            System.out.println("当前用户不存在,返回的List对象为空");
        }
        if(list.size() == 0){
            System.out.println("当前用户不存在,但是返回的List对象不为null");
        }
    }

输出结果

Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ where student0_.lastname=?
当前用户不存在,但是返回的List对象不为空
4.8、使用聚集函数count()查询database中Student的数量

需要注意的是我们这里返回的是Long类型的数据,不要用Integer类型的数据

    @Transactional
    public Long countStudent(){
        String hql = "select count(id) as total from Student";
        return (Long)this.sessionFactory.getCurrentSession().createQuery(hql).uniqueResult();
    }

测试代码

    @Transactional
    public Long countStudent(){
        String hql = "select count(id) as total from Student";
        return (Long)this.sessionFactory.getCurrentSession().createQuery(hql).uniqueResult();
    }

输出结果

Hibernate: select count(student0_.id) as col_0_0_ from student student0_
the number of studne in database is : 18
4.9、使用Hibernate实现分页查询,主要用到的Query中的两个方法
Query.setFirstResult(int row) //设置查询的起始行,从零开始,0表示第一行,和Limit中的第一个参数一致
Query.setMaxResult(int row)//设置返回的最大行数
    @Transactional
    public List<Student> getLimitStudents(int pageNum,int pageSize){
        String hql = "select s from Student as s";
        Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
        query.setFirstResult(pageNum*pageSize);//设置起始行
        query.setMaxResults(pageSize);//设置查询最大的返回结果
        return query.list();
    }

测试代码

    @Test
    public void testGetLimitStudent(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        int pageNum = 0;
        int pageSize = 5;
        List<Student> stus = stuDao.getLimitStudents(pageNum,pageSize);
        for(Student stu:stus){
            System.out.println(stu.toString());
        }
    }

输出结果

Hibernate: select student0_.id as id1_0_, student0_.firstname as firstnam2_0_, student0_.lastname as lastname3_0_, student0_.address as address4_0_, student0_.phone as phone5_0_ from student student0_ limit ?
Student{id=4, firstName='Wu', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=5, firstName='Zhou', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=6, firstName='Sun', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=7, firstName='Li', lastName='BaiTao', address='Hunan', phone='12345678912'}
Student{id=8, firstName='Liu', lastName='BaiTao', address='Hunan', phone='12345678912'}

我们看一下使用Mysql的LIMIT关键字查询结果,与上面的结果是一样的。

mysql> select *from student limit 0,5;
+----+-----------+----------+---------+-------------+
| id | firstname | lastname | address | phone       |
+----+-----------+----------+---------+-------------+
|  4 | Wu        | BaiTao   | Hunan   | 12345678912 |
|  5 | Zhou      | BaiTao   | Hunan   | 12345678912 |
|  6 | Sun       | BaiTao   | Hunan   | 12345678912 |
|  7 | Li        | BaiTao   | Hunan   | 12345678912 |
|  8 | Liu       | BaiTao   | Hunan   | 12345678912 |
+----+-----------+----------+---------+-------------+
4.10、使用POJO的方式封装特定的对象
    @Transactional
    public List<Student> queryStudentByLastName(String lastName){
        String hql = "select new Student(id,firstName) from Student as s where lastName= :lastName";
        return (List<Student>) this.sessionFactory.getCurrentSession().createQuery(hql).setParameter("lastName",lastName).list();
    }

注意上面我们使用了 new Student(id,firstName)将我们查询的结果进行封装了,

select new Student(id,firstName) from Student as s where lastName= :lastName"

这种情况下我们必须要在Student中添加相应的构造方法

    public Student(int id,String firstName){
        this.id = id;
        this.firstName = firstName;
    }

测试代码

    @Test
    public void testQueryStudentByLastName(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        List<Student> list = stuDao.queryStudentByLastName("Mazi");
        for(Student stu:list){
            System.out.println(stu.toString());
        }
    }

输出结果

Student{id=11, firstName='Li', lastName='null', address='null', phone='null'}
Student{id=12, firstName='Zhang', lastName='null', address='null', phone='null'}
4.11、使用Hibernate执行批量插入数据
    @Transactional
    public void batchInsertStudents(List<Student> stuList){
        Session session = this.sessionFactory.getCurrentSession();
        for(int i = 0 ;i<stuList.size();i++){
            session.save(stuList.get(i));
            if(i%20 == 0){
                session.flush();
                session.clear();
            }
        }
    }

测试代码

    @Test
    public void testBatchInsert(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
        StudentDao stuDao = context.getBean("studentDao",StudentDao.class);
        List<Student> stuList = new ArrayList<Student>(10000);
        for(int i = 0;i<10000;i++) {
            Student stu = new Student(i, "firstName" + i, "lastName" + i, "address" + i, "phone" + i);
            stuList.add(stu);
        }
        stuDao.batchInsertStudents(stuList);
    }

从结果我们可以看到,返回的Student对象确实只封装了我们想要的信息

GitHub代码下载地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值