Hibernate认识与入门

web内容回顾:

javaEE三层结构:
1.web层:
2.service层:spring框架
3.dao层:hibernate框架,对数据库进行增删改查(crud)操作
MVC思想:
1.m:模型
2.v:视图
3.c:控制器

Hibernate概述:

框架好处:
1.少写一部分代码实现功能
什么是Hibernate框架:
1.hibernate框架应用在javaee三层结构中的dao层框架
2.在dao层里面做对数据库crud操作,使用hibernate实现crud操作,hibernate底层代码就是jdbc,hibernate对jdbc进行封装,使用hibernate好处是不需要写复杂jdbc代码
3.hibernate开源的轻量级的框架
什么是orm思想:
1.hibernate使用orm思想对数据库进行crud操作
2.在web阶段学习javabean,更正确的叫法是 实体类
3.orm:object 对象 relational 关系 mapping 映射
(1)让实体类和数据库进行一 一对应关系,让实体类首先和数据库表对应,让实体类属性和表里面的字段对应
(2)不需要直接操作数据库表,而操作表对应的实体类
(注意:什么是CRM:客户关系管理 (CRM) 是用于管理公司与当前和未来客户之间的互动的系统。)
在这里插入图片描述
在这里插入图片描述

搭建Hibernate环境:

1.创建java项目
2.导入hibernate的jar包,
3.因为使用hibernate时,有日志信息输出,hibernate本身没有日志输出的jar包,所以要导入其它日志的jar包
4.导入mysql驱动的jar包
把上面需要的Jar包复制到新建的lib目录如下:
在这里插入图片描述

再导入上面需要的jar包如下:
在这里插入图片描述
在这里插入图片描述
lib目录下的jar包可以展开如下图表示导入到程序中成功:
在这里插入图片描述
创建实体类:
类似如下(user表的实体类):
在这里插入图片描述
实体类 User.java:

package com.myHibernate.entity;

/**
 * 用户表
 * @author AUAS
 */
public class User {

    /**
     * Hibernate要求实体类要有一个属性是唯一的,类似与数据库表的主键
     */
     //实体类里面的属性是私有的,实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类
     //八个基本数据类型对应的包装类:int-Integer,char-Character,其它的都是首字母大写,比如double-Double
     //使用包装类的原因如下:比如 表示学生的分数,int score;学生得了0分,int score = 0;表示学生没有参加考试。int score = 0;这样不能准确表示学生是否参加了考试还是0分,因为int score = null 是报错的。而使用包装类Integer,可以等于0或null。
    private Integer id; 
    private String name;
    private Integer password;

	//私有属性使用公开的set和get方法操作
    public Integer getId(){
        return id;
    }

    public void setId(Integer id){
        this.id = id;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }

    public Integer getPassword(){
        return password;
    }

    public void setPassword(Integer password){
        this.password = password;
    }
}

实体类对象的状态(概念):
1.实体类状态有三种
(1)瞬时态:对象里面没有id值,对象与session没有关联,如下:
在这里插入图片描述
(2)持久态:对象里面有id值,对象与session关联,如下:
在这里插入图片描述
(3)托管态:对象有id值,对象与session没有关联,如下:
在这里插入图片描述
2.操作实体类对象的方法
(1)saveOrUpdate方法:可以实现添加,修改操作

        //实体类对象状态是瞬时态,saveOrUpdate做添加操作
//        User user = new User();
//        user.setName("小路2");
//        user.setPassword(22222);
//        session.saveOrUpdate(user);

        //实体类对象状态是托管态,saveOrUpdate做修改操作
        user = new User();
        user.setId(4);
        user.setName("小路6");
        user.setPassword(2);
        session.saveOrUpdate(user);

        //实体类对象状态是持久态,saveOrUpdate做修改操作
//        user = session.get(User.class,1);
//        user.setName("小想");
//        session.saveOrUpdate(user);

注意:
1.以上是使用Session(Hibernate)对象管理持久化上下文(persistence context)。还有一种方法是使用EntityManager(JPA)对象管理持久化上下文(persistence context)。他们都是将Java对象持久化到数据库中去。即有两种方法来处理Hibernate中的持久性:会话(session)和实体管理器。
2.JPA和Hibernate的区别:JPA是规范,Hibernate是实现。Hibernate只是JPA规范的许多实现之一。只有一个JPA规范。但是,有很多不同的实现。DataNucleus,TopLink,EclipseLink,OpenJPA和Hibernate都提供了JPA规范的实现。
3.什么是JDBC:JDBC( Java DataBase Connectivity ) 称为 Java数据库连接 ,它是一种用于数据库访问的应用程序 API ,由一组用Java语言编写的类和接口组成,JDBC支持不同的关系数据库,这使得程序的可移植性大大加强。有了JDBC就可以用统一的语法对多种关系数据库进行访问,而不用担心其数据库操作语言的差异 。
4.MyBatis和Hibernate区别:MyBatis和Hibernate是两种不同的数据访问框架。
原理不同:MyBatis是一种基于SQL语句的持久化框架,它通过预编译SQL语句并执行,以实现数据库访问。而Hibernate是一种基于对象的持久化框架,它通过将Java对象映射到数据库表来实现数据库访问。
使用方式不同:MyBatis的使用方式更加灵活,它允许用户编写自己的SQL语句并执行,支持多种数据库查询方式(如普通查询、存储过程等)。

使用hibernate不需要自己手动创建表,hibernate会自动帮忙创建。
配置实体类和数据库表一 一对应关系(映射关系):
1.使用配置文件实现映射关系
(1)创建xml格式的配置文件(映射配置文件名和位置没有固定要求,建议:映射配置文件在实体类所在包里面创建,实体类名为.hbm.xml)
(2)配置文件是xml格式,在配置文件中首先引入xml约束,学过约束dtd,schema,在hibernate里面引入的约束是std约束
创建如下:
在这里插入图片描述
User.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--引入dtd约束-->
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!--根标签-->
<hibernate-mapping>
    <!-- 标签class:配置实体类和表对应
       属性name:实体类全路径
       属性table:数据库表名称
    -->
    <class name="com.myHibernate.entity.User" table="user">
        <!--   id标签
             属性name:实体类里面的id属性名称
             属性column:生成的表字段名称
        -->
        <id name="id" column="id">
            <!--    设置数据库表id增长策略(主键生成策略,hibernate要求实体类里面有一个属性作为唯一值,对应表主键,主键可以不同生成策略)
                    native:生成表id值就是主键自动增长。会根据不同数据库识别使用不同的值,能适用所有数据库
                    uuid:web阶段写代码生成uuid值,hibernate帮我们自动生成uuid值。使用uuid,实体类id属性类型必须是字符串类型
                    increment:每次增量为1,如每次增长1,2,3
                    identity:自动增长,olicle不支持
                    sequence:序列生成器,mysql不支持
                    
             -->
            <generator class="native"></generator>
        </id>
        <!--    配置实体类其它属性和表字段对应关系
            属性name:实体类属性名称
            属性column:生成表字段名称
         -->
        <property name="name" column="name"></property>
        <property name="password" column="password"></property>

    </class>
</hibernate-mapping>

创建Hibernate的核心配置文件:
1.核心配置文件格式是xml,核心配置文件名和位置是固定的,位置必须在src目录下,名称必须是是hibernate.cfg.xml
2.引入dtd约束
3.hibernate操作过程中,只会加载核心配置文件,其它配置文件不会加载
(1)配置数据库信息
(2)配置hibernate信息
(3)把映射文件放到核心配置文件中
在这里插入图片描述

hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 第一部分: 配置数据库信息 必须的 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		
		<!-- 第二部分: 配置hibernate信息  可选的-->
		<!-- 输出底层sql语句 -->
		<property name="hibernate.show_sql">true</property>
		<!-- 输出底层sql语句格式 -->
		<property name="hibernate.format_sql">true</property>
		<!-- hibernate帮创建表,需要配置之后 
			update: 如果已经有表,更新,如果没有,创建
		-->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!-- 配置数据库方言
			在mysql里面实现分页 关键字 limit,只能使用mysql里面
			在oracle数据库,实现分页rownum
			让hibernate框架识别不同数据库的自己特有的语句
		 -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		
		<!-- 第三部分: 把映射文件放到核心配置文件中 必须的-->
		<mapping resource="cn/itcast/entity/User.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

实现添加操作(生成表,数据库是否有插入数据等):
1.加载hibernate核心配置文件
2.创建SessionFactory对象
3.使用SessionFactory创建session对象
4.开启事务
5.写具体逻辑crud操作
6.提交事务
7.关闭资源
在这里插入图片描述
该测试文件:
HibernateTestDemo:

package cn.itcast.hibernatetest;

import com.myHibernate.entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class HibernateTestDemo {

    @Test
    public void testAdd() {
//		第一步 加载hibernate核心配置文件
        // 到src下面找到名称是hibernate.cfg.xml的配置文件,创建对象,把配置文件放到对象里面(即加载核心配置文件)
        //在hibernate里面封装对象
		Configuration cfg = new Configuration();
		cfg.configure();

//		第二步 创建SessionFactory对象
        //使用Configuration对象创建SessionFactory对象,根据核心配置文件中的数据库配置,映射文件等信息到数据库里面根据映射关系创建数据库表。<property name="hibernate.hbm2ddl.auto">update</property> <!-- hibernate 需要配置之后才帮忙创建表;update:表示已经有表,更新,如果没有,创建-->在hibernate.cfg.xml配置文件中有这句<property>才会创建数据库表。
        
        //读取hibernate核心配置文件内容,创建sessionFactory
        //在过程中,根据映射关系,在配置数据库里面把表创建
		SessionFactory sessionFactory = cfg.buildSessionFactory();

//        SessionFactory sessionFactory = HibernateUtils.getSessionFactory();

//		第三步 使用SessionFactory创建session对象
        // session类似于jdbc中的connection,调用session里面的不同方法实现crud操作
        //添加save方法;修改update方法;删除delete方法;根据id查询 get方法
        //session对象单线程对象,session对象不能共用,只能自己使用
        Session session = sessionFactory.openSession();

//		第四步 开启事务
		//	事务提交tx.commit()和回滚tx.rollback()
		//事务的四个特性:原子性(要么全部成功,要么全部失败);
		//一致性(操作之前之后总数据一致,如付款,一个多了多少,另一个就少多少;
		//隔离性(多个事务操作同一条记录,互不影响);
		//持久性(提交后,保存在数据库)。
		//不考虑隔离性产生问题:胀读;不可重复读;虚读
		//mysql默认隔离级别repeatable read
		//事务代码规范写法:
		//try{
		//	开启事务
		//	提交事务
		//}catch(){
		//	回滚事务
		//}finally{
		//	关闭
		//}
        Transaction tx = session.beginTransaction();

//		第五步 写具体逻辑 crud操作
        //1.添加功能
//       User user = new User();
//        user.setUsername("小马");
//        user.setPassword("1314520");
//        user.setAddress("美国");
//        //调用session的方法实现添加
//        session.save(user);
		//2.查询操作
		//根据id查数据,session里面的get方法,第一个参数:实体类的class,第二个参数:id值
		//User user = session.get(User.class,1);
		//System.out.println(user);
		//3.修改操作
        //修改id=1的name
        //根据id查询
        User user = session.get(User.class,1);
        //向返回的user对象里面设置修改之后的值
        user.setName("小鹿");
        //调用session的update方法修改,(执行过程:到user对象里面找到id,根据id进行修改)
        session.update(user);
        //4.删除操作
        //根据id查询对象
        user = session.get(User.class,2);
        //执行过程,到user对象中查到主键id,删除对应id的数据
        session.delete(user);

//		第六步 提交事务
        tx.commit();

//		第七步 关闭资源
        session.close();
        sessionFactory.close();
    }
}

上面的第一步 加载hibernate核心配置文件和第二步 创建SessionFactory对象可以直接使用下面这句使用一个静态工具类HibernateUtils代替:

SessionFactory sessionFactory = HibernateUtils.getSessionFactory();

静态工具类HibernateUtils如下:

package com.myHibernate.utils;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


/**
 * hibernate sessionFactory静态工具栏
 * @author AUAS
 */
public class HibernateUtils {
    static Configuration configuration = null;
    static SessionFactory sessionFactory = null;

    //静态代码块实现
    static {
        //加载核心配置文件
        configuration = new Configuration();
        configuration.configure();
        //创建SessionFactory对象
        sessionFactory = configuration.buildSessionFactory();
    }

    /**
     * 提供方法返回sessionFactory
     */
    public static SessionFactory getSessionFactory(){
        return sessionFactory;
    }
}

使用上面这个工具类的好处:静态代码块实现,在类加载时候执行,而且只执行一次。

成功运行测试文件后,会在数据库看到新建了一个t_user表如下:
在这里插入图片描述
注意:
报错一:如果没有出现上面的表,报错如下(是因为对于Maven工程,编译的工作是由Maven程序来完成的,而Maven默认只会把src/main/resources文件夹下的文件拷贝到target/classes文件夹下,所以.hbm.xml都不会被复制到/target/calsses文件夹下,所以Hibernate框架在运行的时候,就会报找不到*.hbm.xml的错误。所以在pom.xml配置文件加上下面的内容即可):
在这里插入图片描述

pom.xml:

<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.myHibernate.study</groupId>
  <artifactId>myHibernate</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>myHibernate</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.1.0.Final</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.6</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
  </dependencies>

  <build>
    <!--  把src/main/java下的所有xml文件,src/main/resources下的xml和properties文件也添加到target目录下。
          不写下面这些配置,默认是xml和properties文件不会添加到target目录下的-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>

</project>

报错二:如果出现这个报错,是因为未引入log4j的依赖或未配置log4j.properties文件
在这里插入图片描述
在pom.xml文件插入如下代码:

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

在src/main/resources目录下添加log4j.properties文件如下:

log4j.rootLogger=debug, stdout, R

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n


HIbernate的一级缓存:
1.缓存:
(1)数据存到数据库里面,数据库本身是文件系统,使用流方式操作文件效率不是很好。
(2)把数据存到内存里面,不需要使用流方式,可以直接读取内存中数据
(3)把数据放到内存中,提供读取效率
2.Hibernate缓存:
(1)hibernate框架提供很多优化方式,hibernate的缓存就是一个优化方式
(2)hibernate缓存特点:
第一类 hibernate的一级缓存
(1)hibernate的一级缓存默认打开
(2)hibernate的一级缓存使用范围,是session范围,从session创建到session关闭范围
(3)hibernate的一级缓存中,存储数据必须持久态数据
第二类 hibernate的二集缓存
(1)目前已经不使用了,替代技术redis
(2)二级缓存默认不是打开的,需要配置
(3)二级缓存使用范围,是sessionFactory范围

一级缓存例子:当有两条一样的查询语句,先查缓存,再查数据库,如下:
在这里插入图片描述
一级缓存特性:持久态自动更新数据库:
在这里插入图片描述
执行过程:
在这里插入图片描述
Hibernate绑定session:
1 session类似于jdbc的connection,之前web阶段学过 ThreadLocal
2 实现与本地线程绑定session
3 获取与本地线程session
(1)在hibernate核心配置文件中配置

<!-- 在hibernate核心配置文件中配置 -->
<property name="hibernate.current_session_context_class">thread</property>	

(2)调用sessionFactory里面的方法得到

	//提供返回与本地线程的session的方法
	public static Session getSessionobject() {
		return sessionFactory.getCurrentSession();
	}

4 获取与本地线程绑定session时候,关闭session报错,不需要手动关闭了
在这里插入图片描述

HIbernate的api使用:
Query对象:
1.使用query对象,不需要写sql语句,但是写hql语句
(1)hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通sql语句很相似
(2)hql和sql语句区别:
使用sql操作表和表字段
使用hql操作实体类和属性
2.查询所有hql语句
(1)from 实体类名称
3 Query对象使用
(1)创建Query对象
(2)调用query对象里面的方法得到结果
在这里插入图片描述
在这里插入图片描述

package cn.itcast.hibernatetest;

import com.myHibernate.entity.User;
import com.myHibernate.utils.HibernateUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import java.util.List;

public class HibernateQueryDemo {

    @Test
    public void testSelect() {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            //提供返回与本地线程的session的方法
            session = HibernateUtils.getSessionObject();
            //开启事务
            transaction = session.beginTransaction();

            //1.创建Query对象
            //方法里面写hql语句
            Query query = session.createQuery("FROM User");

            //2.调用query对象里面的方法得到结果
            List<User> userList = query.list();
            for (User user:userList) {
                System.out.println("333333333333");
                System.out.println(user);
            }

            //提交事务
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            transaction.rollback();
        } finally {
            //关闭操作
//            session.close();
//            sessionFactory.close();
        }
    }
}

Critia对象:
1 使用这个对象查询操作,但是使用这个对象时候,不需要写语句,直接调用方法实现
2 实现过程
(1)创建criteria对象
(2)调用对象里面的方法得到结果
在这里插入图片描述
在这里插入图片描述

package cn.itcast.hibernatetest;

import com.myHibernate.entity.User;
import com.myHibernate.utils.HibernateUtils;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import java.util.List;

public class HibernateQueryDemo {

    @Test
    public void testSelect() {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            //提供返回与本地线程的session的方法
            session = HibernateUtils.getSessionObject();
            //开启事务
            transaction = session.beginTransaction();

            //1.创建criteria对象
            //方法里面参数是实体类class
            Criteria criteria = session.createCriteria(User.class);
            //2.调用方法得到结果
            List<User> userList = criteria.list();
            for (User user:userList) {
                System.out.println("333333333333");
                System.out.println(user);
            }

            //提交事务
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            transaction.rollback();
        } finally {
            //关闭操作
//            session.close();
//            sessionFactory.close();
        }
    }
}

SQLQuery对象:
1 使用hibernate时候,调用底层sql实现
2 实现过程
(1)创建对象
(2)调用对象的方法得到结果
在这里插入图片描述

返回list集合每部分是数组
在这里插入图片描述
返回list中每部分是对象形式
在这里插入图片描述
在这里插入图片描述

package cn.itcast.hibernatetest;

import com.myHibernate.entity.User;
import com.myHibernate.utils.HibernateUtils;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;

public class HibernateQueryDemo {

    @Test
    public void testSelect() {
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try {
            sessionFactory = HibernateUtils.getSessionFactory();
            //提供返回与本地线程的session的方法
            session = HibernateUtils.getSessionObject();
            //开启事务
            transaction = session.beginTransaction();

            //1.创建SQLQuery对象
            //方法里面参数是普通sql语句
            SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM t_user");
//            //2.调用sqlQuery里面的方法得到结果
//            List<Object[]> userList = sqlQuery.list();
//            for (Object[] objects :userList) {
//                System.out.println("333333333333");
//                System.out.println(Arrays.toString(objects));
//            }

            //返回的list中每部分是对象形式
            sqlQuery.addEntity(User.class);
            //调用sqlQuery里面的方法
            List<User> userList = sqlQuery.list();
            for (User user :userList) {
                System.out.println("333333333333");
                System.out.println(user);
            }

            //提交事务
            transaction.commit();
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            transaction.rollback();
        } finally {
            //关闭操作
//            session.close();
//            sessionFactory.close();
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值