JPA-Hibernate快速入门

测试项目见本地jpademo。
别人写的快速入门资料:https://www.kuangstudy.com/bbs/1370755259508580354

数据库 Hibernate-JPA

JPA懒到不想写sql为此而产生的接口,是参照ORM关系映射思想由用java实现的接口。缺点是不写sql容易退化,适用于单表查询,面对复杂多表查询就没啥用了。

mybatis对复杂的多表查询也有较好支持,可以写sql,特点是mapper接口和mapper.xml实现之间的映射很神奇,以及查询得到的结果映射给对象或者map等集合也很神奇。

mybatis-plus集合了jpa的特性且保留了mybaits特性,针对简单的查询也无需写sql,用代码形式完成对数据库查询。

考虑到仅仅是脚手架分成了用户管理,权限管理,角色管理,每个表都需要单独使用,且后续开发中不需要了解也不太需要维护脚手架因此考虑使用jpa。

JPA和Hibernate和ORM区别

ORM对象关系映射,java对象到关系表之间的映射。JDBC是最原生的ORM思想框架,不管是Hibernate,JPA,mybaits都是常见的ORM思想框架底层最终都是对JDBC的调用

ORM(关系映射思想)—>JPA(java参照ORM写的接口规范)---->JDBC(最原生的实现ORM的框架)----->Hibernate(轻量封装JDBC)

java中实现实体类持久化存到数据库的包

import javax.persistence.*;//将实体类 持久化到数据库中 针对jpa规范使用的。

JPA操作的数据库流程

  • 加载配置文件 创建实体类管理器工厂factory=Persistence.createEntityManagerFactory(“myJpa”)
  • 工厂生成 实体类管理器 entityManager=factory.createEntityManager()
  • 实体类管理器得到事务对象
  • 开启事务
  • 通过实体类管理器完成增删改查
  • 提交事务
  • 释放资源(实体类管理器和工厂资源释放)

通过Persistence 持久化 API先加载jpa配置文件,配置文件内容包括 jpa实现的方式(如Hibernate方式),数据库连接配置,表生成策略(update none create)。当然使用springboot自动化装配,自动配置JpaProperties中的属性即可。

persistence API对象说明

persistence是java当中实现实体类对象持久化存储到数据库的API。包含实体类管理器工厂,实体类管理器,事务等对象,从而操作数据库。其中实体类管理器entityManager是真正和数据库打交道的对象,通过persist,remove,merge,find方法实现增删改查。

@Test
public void testSave() {
    //1.加载配置文件 创建实体类管理器工厂
    EntityManagerFactory factory = Persistence.createEntityManagerFactory ("myJpa");

    //2.工厂生成实体类管理器  有很多方法操作数据库 presist保存 merge更新 remove删除 find查询
    EntityManager entityManager = factory.createEntityManager ();
    //3.得到事务对象
    EntityTransaction tn = entityManager.getTransaction ();
    tn.begin ();//开启事务
    //4.完成增删改查CRUD
    Customer customer = new Customer ();
    customer.setCustName ("javachuan");
    customer.setCustIndustry ("test jpa2");
    //5.保存
    entityManager.persist (customer);
    //6.提交事务
    tn.commit ();
    //7.释放资源
    entityManager.close ();
    factory.close ();
}

JPA增删改查案例

配置文件persistence.xml ,hibernate相关的配置,包括数据库连接,表生成策略等。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!--需要配置persistence-unit节点
        持久化单元:
            name:持久化单元名称
            transaction-type:事务管理的方式
                    JTA:分布式事务管理
                    RESOURCE_LOCAL:本地事务管理
    -->
    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!--jpa的实现方式 采用hibernate -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!--可选配置:配置jpa实现方的配置信息-->
        <properties>
            <!-- 数据库信息
                用户名,javax.persistence.jdbc.user
                密码,  javax.persistence.jdbc.password
                驱动,  javax.persistence.jdbc.driver
                数据库地址   javax.persistence.jdbc.url
            -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpademo"/>

            <!--配置jpa实现方(hibernate)的配置信息
                显示sql           :   false|true
                自动创建数据库表    :  hibernate.hbm2ddl.auto
                        create      : 程序运行时创建数据库表(如果有表,先删除表再创建)
                        update      :程序运行时创建表(如果有表,不会创建表)
                        none        :不会创建表

            -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
</persistence>

Customer对象

package com.zhangchuan.jpa.entity;
import javax.persistence.*; //持久化实体类到数据库中, 针对open jpa实现
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
 * @Description 客户实体类
 *
 * * 客户的实体类
 *  *      配置映射关系
 *  *
 *  *
 *  *   1.实体类和表的映射关系
 *  *      @Entity:声明实体类
 *  *      @Table : 配置实体类和表的映射关系
 *  *          name : 配置数据库表的名称
 *  *   2.实体类中属性和表中字段的映射关系
 *
 *
 * @Author java川
 * @Date 2021-09-18-15:12
 */

@Entity
@Table(name = "cst_customer")
public class Customer {

    /**
     * @Id:声明主键的配置
     * @GeneratedValue:配置主键的生成策略
     *      strategy
     *          GenerationType.IDENTITY :自增,mysql
     *                 * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增)
     *          GenerationType.SEQUENCE : 序列,oracle
     *                  * 底层数据库必须支持序列
     *          GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
     *          GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略
     * @Column:配置属性和字段的映射关系
     *      name:数据库表中字段的名称
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cust_id")
    private Long custId; //客户的主键

    @Column(name = "cust_name")
    private String custName;//客户名称

    @Column(name="cust_source")
    private String custSource;//客户来源

    @Column(name="cust_level")
    private String custLevel;//客户级别

    @Column(name="cust_industry")
    private String custIndustry;//客户所属行业

    @Column(name="cust_phone")
    private String custPhone;//客户的联系方式

    @Column(name="cust_address")
    private String custAddress;//客户地址

    public Long getCustId() {
        return custId;
    }

    public void setCustId(Long custId) {
        this.custId = custId;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustSource() {
        return custSource;
    }

    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustIndustry() {
        return custIndustry;
    }

    public void setCustIndustry(String custIndustry) {
        this.custIndustry = custIndustry;
    }

    public String getCustPhone() {
        return custPhone;
    }

    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    public String getCustAddress() {
        return custAddress;
    }

    public void setCustAddress(String custAddress) {
        this.custAddress = custAddress;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "custId=" + custId +
                ", custName='" + custName + '\'' +
                ", custSource='" + custSource + '\'' +
                ", custLevel='" + custLevel + '\'' +
                ", custIndustry='" + custIndustry + '\'' +
                ", custPhone='" + custPhone + '\'' +
                ", custAddress='" + custAddress + '\'' +
                '}';
    }
}

因为每次都需要获取一个实体类管理器工厂和管理器对象,将其抽象出来进行封装JPAUtils,减少资源消耗。

package com.zhangchuan.jpa.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

/**
 * @Description jpa工具类
 * @Author java川
 * @Date 2021-09-18-16:29
 */
public class JPAUtils {

    private static EntityManagerFactory factory;

    static {
        //1.加载配置文件 创建实体类管理器工厂
        factory = Persistence.createEntityManagerFactory ("myJpa");

    }


    /*
     * @description:
     * 到实体类管理器
     * @param
     * @author java川
     * @date  2021/9/18 16:35
     * @return
     */
    public static EntityManager getEntityManager() {
        //2.工厂生成实体类管理器
        EntityManager entityManager = factory.createEntityManager ();
        return entityManager;
    }


    /*
     * @description:
     * 得到事务对象
     * @param
     * @author java川
     * @date  2021/9/18 16:46
     * @return
     */
    public static EntityTransaction getTransaction() {
        //2.工厂生成实体类管理器
        EntityTransaction tx = getEntityManager ().getTransaction ();
        return tx;
    }

    /*
     * @description:
     * 释放实体类管理器,实体类管理器工厂资源
     * @param 
     * @author java川
     * @date  2021/9/18 16:37
     * @return 
     */
    public static void close(EntityManager manager) {
        manager.close ();
    }


}

根据id查询用户EntityManager.find(class,primarykey)

/*
 * @description:
 * 根据id查询用户
 * @param
 * @author java川
 * @date  2021/9/18 16:40
 * @return
 */
@Test
public void testFind() {

    //得到实体类对象
    EntityManager em = JPAUtils.getEntityManager ();
    //开启事务
    EntityTransaction tx = JPAUtils.getTransaction ();
    tx.begin ();
    //增删改查 根据id查询用户
    Customer customer = em.find (Customer.class, 1l);//立即加载的方式
    //懒加载的方式查询
    //  Customer customer=em.getReference (Customer.class, 1l);
    System.out.println ("customer = " + customer);
    //提交事务
    tx.commit ();
    //资源关闭
    em.close ();
}

Customer customer = em.find (Customer.class, 1l);以上查询用户采用立即加载方式,**还有延迟加载方式em.getReference (Customer.class, 1l);**也就是不会立刻发送sql语句查询,类比jdbc中的预编译(?),PrepareStatement方式。只有等到调用customer对象的时候才真正执行sql,也就是 System.out.println ("customer = " + customer)的时候才会发送sql执行得到结果。

删除对象

需要先查询得到该对象后删除。

EntityManager.remove(EntityObject)

/*
 * @description:
 * 删除对象
 * @param
 * @author java川
 * @date  2021/9/18 17:07
 * @return
 */
@Test
public void testRemove() {
    //得到实体类对象
    EntityManager em = JPAUtils.getEntityManager ();
    //开启事务
    EntityTransaction tx = JPAUtils.getTransaction ();
    tx.begin();
    //删除用户
    Customer customer = em.find (Customer.class, 1l);
    em.remove (customer);
    //提交事务
    tx.commit ();
    //资源关闭
    em.close ();
    
}

Jpql复杂sql查询语言

Java persistence sql language ,面向java对象的查询语言,JQPL操作的对象是实体对象,对象属性。SQL是面向关系数据库的查询语言,因此SQL操作的对象是数据表、数据列。

jpql语句的语法规则:sql中的表 对应为 对象,sql语句中的列字段 对应对象的属性,其余关键字同样适用jpql。

//面向对象的JPQL语句
 select * from Customer where custAddress likegroup by custName //对Customer实体对象查询,按照Customer对象的custAddress属性查询并按照Customer对象属性custName属性分组。

SQL(Structured Query Language)是关系数据库查询语言。from后面跟的是“表名”,where后用“**表中字段”**做条件

//原生的SQL语句
select * from cst_customer where cust_address like ? group by cust_name //对cst_customer表执行查询,按照表中cust_address数据列查询,按照数据库cust_name分组。

JPQL语句支持两种方式的参数定义方式: 命名参数和位置参数。在同一个查询语句中只允许使用一种参数定义方式。

String jpqlSql="from Customer where custAddress like ? group by custName";
//获得query的对象
Query query = em.createQuery (jpqlSql);
//ii:对占位符参数赋值
 query.setParameter (1, "%beijing");

jpql步骤

与原本的jpa新增的就是得到实体类管理器EntityManager后**调用createQuery(String jpql)**方法。

jpql步骤:
*      1.得到实体类管理器对象工厂
*      2.得到实体类管理器entityManager
*      3.entityManager.getTransaction.begin() 开启事务
*      4.根据sql写jpql语句
     5.entityManager.createQuery(String jpql)得到查询对象query
*     6.给jpql语句中的占位符设置参数 query.setParamter(position,parameter);
*     7.执行jpql封装到对象  query.getResultList()
*     8.关闭事务 和关闭资源
*
jpql的增删改查
package com.zhangchuan.test;

import com.zhangchuan.jpa.utils.JPAUtils;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.util.List;

/**
 * @Description jpql java复杂语言查询语言
 *
 *      jpql语句的语法规则:sql中的表 对应为 对象,其余不变
 *
 *      jpql步骤:
 *      1.得到实体类管理器对象工厂
 *      2.得到实体类管理器entityManager
 *      3.entityManager.getTransaction.begin() 开启事务
 *      4.根据sql写jpql语句
 *     5.entityManager.createQuery(String jpql)得到查询对象query
 *     6.给jpql语句中的占位符设置参数 query.setParamter(position,parameter);
 *     7.执行jpql封装到对象  query.getResultList()
 *     8.关闭事务 和关闭资源
 *
 * @Author java川
 * @Date 2021-09-23-16:19
 */
public class JpqlTest {


    /*
     * @description:
     * 查询全部
     *  sql: SELECT * FROM cst_customer
     *
     * @param
     * @author java川
     * @date  2021/9/23 17:05
     * @return
     */
    @Test
    public void testFindAll() {
        //得到实体类对象
        EntityManager em = JPAUtils.getEntityManager ();
        //开启事务
        EntityTransaction tx = em.getTransaction ();
        tx.begin ();    
        //sql
        String jpqlSql="from com.zhangchuan.jpa.entity.Customer";
        //query对象执行jpql的对象
        Query query = em.createQuery (jpqlSql);
        //得到全部数据
        List resultList = query.getResultList ();
        for (Object o : resultList) {
            System.out.println (o+" ");
        }
        //提交事务
        tx.commit ();
        em.close ();

    }


    /*
     * @description:
     * 倒序排序
     *  sql:SELECT* FROM cst_customer ORDER BY cust_id DESC
     *  jpql: from Customer ORDER BY custId;
     * @param
     * @author java川
     * @date  2021/9/23 17:15
     * @return
     */
    @Test
    public void testSort() {
        //得到实体类对象
        EntityManager em = JPAUtils.getEntityManager ();
        //开启事务
        EntityTransaction tx = em.getTransaction ();
        tx.begin ();
        //jpql语句
        String jpqlSql="from Customer ORDER BY custId DESC ";
        //query对象执行jpql的对象
        Query query = em.createQuery (jpqlSql);
        //得到全部数据
        List resultList = query.getResultList ();
        for (Object o : resultList) {
            System.out.println (o+" ");
        }
        //提交事务
        tx.commit ();
        em.close ();

    }


    /*
     * @description:
     *    统计查询
     *  sql: select count(*) from cst_customer
     *  jpql:select count(*) from Customer
     * @param
     * @author java川
     * @date  2021/9/23 17:22
     * @return
     */
    @Test
    public void teststatisticalQuery() {
        //得到实体类对象
        EntityManager em = JPAUtils.getEntityManager ();
        //开启事务
        EntityTransaction tx = em.getTransaction ();
        tx.begin ();
        //jpql语句
        String jpqlSql="select count(*) from Customer";
        //query对象执行jpql的对象
        Query query = em.createQuery (jpqlSql);
        //打印结果
        Object singleResult = query.getSingleResult ();
        System.out.println ("singleResult = " + singleResult);
        //提交事务
        tx.commit ();
        em.close ();
        
    }


    /*
     * @description:
     * 分页查询
     * sql: select * from cst_customer limit ?,?
     * jpql:
     * @param
     * @author java川
     * @date  2021/9/23 17:29
     * @return
     */
    @Test
    public void testpagingQuery() {
        //1得到实体类对象
        EntityManager em = JPAUtils.getEntityManager ();
        //2开启事务
        EntityTransaction tx = em.getTransaction ();
        tx.begin ();
        //3jpql语句
        String jpqlSql="from Customer";
        //4query对象执行jpql的对象
        Query query = em.createQuery (jpqlSql);
        //ii:对占位符参数赋值 ---分页参数
        //设置起始索引
        query.setFirstResult (0);
        //每页查询2条
        query.setMaxResults (2);
        //iii:发送查询并封装结果
        List resultList = query.getResultList ();
        //5打印结果
        for (Object o : resultList) {
            System.out.println (o+" ");
        }
        //6提交事务
        tx.commit ();
        em.close ();
    }


    /*
     * @description:
     * 条件 分组查询
     *
     * sql:select * from cst_customer where cust_address like ? group by cust_name
     * jpql: from Customer where custAddress like ? group by custName
     * @param
     * @author java川
     * @date  2021/9/23 17:38
     * @return
     */
    @Test
    public void testConditionsTheQuery() {
        //1得到实体类对象
        EntityManager em = JPAUtils.getEntityManager ();
        //2开启事务
        EntityTransaction tx = em.getTransaction ();
        tx.begin ();
        //3jpql语句
        String jpqlSql="from Customer where custAddress like ? group by custName";
        //4query对象执行jpql的对象
        Query query = em.createQuery (jpqlSql);
        //ii:对占位符参数赋值 ---分页参数
        query.setParameter (1, "%beijing");
        //iii:发送查询并封装结果
        List resultList = query.getResultList ();
        //5打印结果
        for (Object o : resultList) {
            System.out.println (o+" ");
        }
        //6提交事务
        tx.commit ();
        em.close ();
    }

}

JPA之原生sql查询

有些时候,JPQL使用不当会导致转化成的sql并不如理想或者特定场合需要sql优化,还是得用到原生SQL查询的。EntityManager对象的createNativeQuery方法,可以实现十分复杂的查询,但不能跨数据库。

获得原生SQL查询对象

Query query = entityManager.createNativeQuery ("select * from cst_customer", Customer.class);

相比jpql只是将entityManager.createQuery(String jpql)改为entityManager.createNativeQuery(String sql);

jpa-原生SQL增删改查
package com.zhangchuan.test;

import com.zhangchuan.jpa.entity.Customer;
import com.zhangchuan.jpa.utils.JPAUtils;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import java.util.List;

/**
 * @Description 原生的sql查询,jpql有时候使用不当还是要用原生sql
 * jpql的好处就是自动映射查询结果到对象中,原生sql查询需要手动映射结果到对象中。
 * @Author java川
 * @Date 2021-09-24-9:50
 */
public class RawSqlTest {


    /*
     * @description:
     * 排序查询 sql:select * from cst_customer order by cust_id desc
     * @param
     * @author java川
     * @date  2021/9/24 10:03
     * @return
     */
    @Test
    public void testOrder() {
        // 1.获取entityManager对象 && 开启事务
        EntityManager entityManager = JPAUtils.getEntityManager ();
        EntityTransaction transaction = entityManager.getTransaction ();
        transaction.begin ();
        // 采用链式调用,默认情况(升序)
        List<Customer> list1 = entityManager.createNativeQuery ("select * from cst_customer order by cust_id", Customer.class).getResultList ();

        // 采用链式调用,升序情况
        List<Customer> list2 = entityManager.createNativeQuery ("select * from cst_customer order by cust_id asc ", Customer.class).getResultList ();

        // 采用链式调用,降序情况
        List<Customer> list3 = entityManager.createNativeQuery ("select * from cst_customer order by cust_id desc", Customer.class).getResultList ();

        for (Customer customer : list1) {
            System.out.println (customer);
        }
        for (Customer customer : list2) {
            System.out.println (customer);
        }

        for (Customer customer : list3) {
            System.out.println (customer);
        }

        // 4.提交事务 && 释放资源
        transaction.commit ();
        entityManager.close ();
    }

    /**
     * 条件查询
     * sql:SELECT * FROM cst_customer where c_sex = ?1 and c_name like ?2
     * sql:SELECT * FROM cst_customer where c_sex = :aaa and c_name like :bbb
     */
    @Test
    public void  testWhere() {
        // 1.获取entityManager对象 && 开启事务
        EntityManager entityManager = JPAUtils.getEntityManager ();
        EntityTransaction transaction = entityManager.getTransaction ();
        transaction.begin ();
        // 条件查询:按参数位置绑定
        Query query1 = entityManager.createNativeQuery ("SELECT * FROM cst_customer where cust_address like ? group by cust_name", Customer.class);
        query1.setParameter (1, "beijing%");
        List<Customer> list1 = query1.getResultList ();
        for (Customer customer : list1) {
            System.out.println (customer);
        }

        // 4.提交事务 && 释放资源
        transaction.commit ();
        entityManager.close ();
    }

    /**
     * 分页查询 sql:select * from cst_customer limit 2,5
     *        sql:select * from cst_customer limit 3 offset 2
     */
    @Test
    public void  testLimit() {
        // 1.获取entityManager对象 && 开启事务
        EntityManager entityManager = JPAUtils.getEntityManager ();
        EntityTransaction transaction = entityManager.getTransaction ();
        transaction.begin ();
        // 分页查询
        Query query = entityManager.createNativeQuery ("select * from cst_customer limit 3 offset 2", Customer.class);
        // 起始索引、每页查询的条数
        // query.setFirstResult(2).setMaxResults(5);
        List<Customer> list1 = query.getResultList ();
        for (Customer customer : list1) {
            System.out.println (customer);
        }
        // 4.提交事务 && 释放资源
        transaction.commit ();
        entityManager.close ();
    }


}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
spring-boot-starter-data-jpa 是 Spring Boot 提供的一个快速开发 JPA 应用的起步依赖。它提供了一系列默认的配置和依赖,方便我们快速地使用 JPA 进行开发。 以下是入门步骤: 1. 添加依赖:在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 2. 配置数据源:在 application.properties 或 application.yml 文件中配置数据库连接信息,例如: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 3. 创建实体类:创建一个用于映射数据库表的实体类,例如: ```java @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private Integer age; // 省略 getter 和 setter 方法 } ``` 4. 创建 Repository 接口:创建一个继承 JpaRepository 接口的 Repository 接口,例如: ```java public interface UserRepository extends JpaRepository<User, Long> { } ``` 5. 使用 Repository:在业务逻辑中使用 UserRepository 进行增删改查操作,例如: ```java @Service public class UserService { @Autowired private UserRepository userRepository; public User save(User user) { return userRepository.save(user); } public User findById(Long id) { return userRepository.findById(id).orElse(null); } public List<User> findAll() { return userRepository.findAll(); } public void deleteById(Long id) { userRepository.deleteById(id); } } ``` 以上就是使用 spring-boot-starter-data-jpa 开发 JPA 应用的基本步骤。需要注意的是,该起步依赖默认使用 Hibernate 作为 JPA 的实现,因此需要添加 Hibernate 的相关依赖。同时,也可以根据需要进行自定义配置,例如配置 JPA 的缓存、事务管理等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值