MyBatis第二天

知识点一.使用注解方式配置映射

CRUD

注意
1.results中的每个result需要用逗号分隔
2.查询所有的时候因为使用d_id,d_username这种列名,所以要有ResultMap,来知晓与User中的哪些属性来对应,否则查出来的都是null。

public interface UserMapper {
//    @Insert("insert into t_user(username,password,age) values (#{username},#{password},#{age})")
//    @Options(keyColumn = "id",keyProperty = "id",useGeneratedKeys = true)
    void save(User u);

//    @Update("update t_user set username=#{username},password=#{password},age=#{age} where id = #{id}")
    void update(User u);

//    @Select("select id,username,password,age from t_user where id = #{id}")
    User get(Long id);

//    @Select("select id as d_id,username as d_username,password as d_password,age as d_age from t_user")
//    @ResultMap("base_map")    用配置文件中的base_map
//    @Results({               //不用配置文件中的base_map
//            @Result(column = "d_id",property = "id"),
//            @Result(column = "d_username",property = "username"),
//            @Result(column = "d_password",property = "password"),
//            @Result(column = "d_age",property = "age"),
//    })
    List<User> list();

//    @Delete("delete from t_user where id = #{id}")
    void delete(Long id);
    }

以上可替代下面的内容:

 <resultMap id="base_map" type="User">

        <!--column:查询出来的字段名
            property:对象中属性名-->
        <id column="d_id" property="id"></id>
        <result column="d_username" property="username"></result>
        <result column="d_password" property="password"></result>
        <result column="d_age" property="age"></result>
    </resultMap>
    <!--
    inser表示插入语句
    parameterType表示调用insert传入的参数
    keyColumn表示数据库中自增长的字段名
    keyProperty表示自增长的字段值应该注入到实体中的哪个字段
    useGeneratedKeys表示标记这个标签需要使用数据库中的自增长id
    -->
    <insert id="save" parameterType="User" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_user(username,password,age) values (#{username},#{password},#{age})
    </insert>

    <update id="update" parameterType="User">
        update t_user set username=#{username},password=#{password},age=#{age} where id = #{id}
    </update>

    <!--
    parameterType:
    resultType:表示查询出来的每一条结果封装成User对象
    -->
    <select id="get" parameterType="long" resultType="User">
        select id,username,password,age from t_user where id = #{id}
    </select>

    <!--resultType:表示查询出来的每一条结果封装成User对象
        resultType与resultMap不可混用-->
    <select id="list" resultMap="base_map">
        select id as d_id,username as d_username,password as d_password,age as d_age from t_user
    </select>

    <delete id="delete" parameterType="java.lang.Long">
        delete from t_user where id = #{id}
    </delete>

知识点二.使用@param的注解

问题:mybatis中的方法都是只支持传入一个参数。
如果想传入多个参数.

注意此处要指定resultType

 <select id="login" resultType="User">
        select * from t_user where username = #{username} and password = #{password}
    </select>

mapper接口中常规如下
1.在方法参数定义Map集合,把需要传入的参数放入map中.

  User login(Map<String,Object> map);

测试类中常规:

        Map<String,Object> uMap = new HashMap<String,Object>();
        uMap.put("username","卡丁");
        uMap.put("password","66");
        User u = mapper.login(uMap);
        System.out.println(u);

使用了@param之后

mapper接口中如下:
2.使用@Param注解来解决.

 User login(@Param("username") String username,@Param("password") String password);

测试类中:

        User u = mapper.login("卡丁","66");
        System.out.println(u);

其原理:
在这里插入图片描述

知识点三.MyBatis对象关系映射细节

1.Many2One员工2部门

员工(Employee)和部门(Department),多对一:员工表中含有外键(部门号)

domain包:

public class Employee {
    private Long id;
    private String name;
    private Department dept;
    public Employee() {
    }
    public Employee(String name) {
        this.name = name;
    }
//getter setter方法略
}
public class Department {
    private Long id;
    private String name;

    public Department() {
    }

    public Department(String name) {
        this.name = name;
    }
   
  //getter setter略去
}

主配置文件添加mapper,添加别名

 <typeAliases>
        <typeAlias type="com.mxl.mybatis01_hello.domain.User" alias="User"/>
        <typeAlias type="com.mxl.mybatis02_day02.domain.Employee" alias="Employee"/>
        <typeAlias type="com.mxl.mybatis02_day02.domain.Department" alias="Department"/>
    </typeAliases>
 <mappers>
        <mapper resource="com/mxl/mybatis01_hello/UserMapper.xml"></mapper>
        <mapper resource="com/mxl/mybatis02_day02/EmployeeMapper.xml"></mapper>
        <mapper resource="com/mxl/mybatis02_day02/DepartmentMapper.xml"></mapper>
    </mappers>

两mapper接口

public interface EmployeeMapper {
    void save(Employee e);
    Employee get(Long id);
}
---------------------------
public interface DepartmentMapper {
    void save(Department d);
    Department get(Long id);
}

两mapper.xml文件

== 注意此处insert中部门号要#{dept.id},就是说从dept中找id==

<mapper namespace="com.mxl.mybatis02_day02.mapper.EmployeeMapper">
    <insert id="save" parameterType="Employee" keyColumn="id"
            keyProperty="id" useGeneratedKeys="true">
        insert into t_employee(name,dept_id) values (#{name},#{dept.id})
    </insert>

    <select id="get" parameterType="long" resultType="Employee">
        select id,name,dept_id from t_employee where id = #{id}
    </select>
</mapper>
<mapper namespace="com.mxl.mybatis02_day02.mapper.DepartmentMapper">
    <insert id="save" parameterType="Department" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_department(name) values (#{name})
    </insert>
    <select id="get" parameterType="long" resultType="Department">
        select id,name from t_department where id = #{id}
    </select>
</mapper>

测试类:
注意:此处many2one的保存操作,要先保存one方,再保存many方
1.保存

    @Test
    public void testSave(){
        SqlSession session = MybatisUtils.openSession();
        EmployeeMapper eMapper = session.getMapper(EmployeeMapper.class);
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Employee e = new Employee();
        Department d = new Department();
        d.setName("一号部门");
        e.setName("一号员工");
        e.setDept(d);
        dMapper.save(d);
        eMapper.save(e);
        session.commit();
        session.close();
    }
}

2.查询

这里有坑需要注意:
简单的查,是不能通过员工把部门也查询出来的,所以EmployeeMapper.xml要配置resultMap


<mapper namespace="com.mxl.mybatis02_day02.mapper.EmployeeMapper">

    <!--
       property:表示实体类的关联关系属性名
       column:哪个字段
       javaType:实体类类型
       select:表示需要发送sql去查询
其实配置这里的目的就是要调用Department中的get
	-->
    <resultMap id="base_map" type="Employee">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <association column="dept_id" property="dept"
                     javaType="Department" select="com.mxl.mybatis02_day02.mapper.DepartmentMapper.get">
        </association>
    </resultMap>

    <insert id="save" parameterType="Employee" keyColumn="id"
            keyProperty="id" useGeneratedKeys="true">
        insert into t_employee(name,dept_id) values (#{name},#{dept.id})
    </insert>

    <select id="get" parameterType="long" resultMap="base_map">
        select id,name,dept_id from t_employee where id = #{id}
    </select>
</mapper>

myBatis中的延时加载.

1.在myBatis中默认的延时加载时禁用的.
在主配置文件中开启延时加载
lazyLoadingEnabled:默认为false,禁用延时加载.
2.many变成代理对象.
当调用many方的任意属性,都会触发one方的加载.
aggressiveLazyLoading:当启用时, 有延迟加载属性的对象在被调用时将会完全加载任意属性。否则, 每种属性将会按需要加载。
3.在many方默认的调用equals,clone,hashCode,toString 方法都会出发one方的加载
lazyLoadTriggerMethods
主配置文件中配置settings

   <settings>
        <!--全局启用或禁用延迟加载。当禁用时, 所有关联对象都会即时加载。默认为flase-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 当启用时, 有延迟加载属性的对象在被调用时将会完全加载任意属性.禁用则每种属性将会按需要加载。-->
        <setting name="aggressiveLazyLoading" value="false"/>
        <!--Object对象上面的哪些方法触发延迟加载.默认equals,clone,hashCode,toString-->
        <setting name="lazyLoadTriggerMethods" value="clone"/>
    </settings>

N+1问题

在查询所有many记录,每个many对应的one都是不同,查询N个many对象,总共会发出N+1条SQL.(性能特别不友好)

使用leftJoin的方式来解决.

这里写于resultMap中,不采用发sql的方式
   <association property="dept" javaType="Department">
       <result column="dept_id" property="id"/>
       <result column="dept_name" property="name"></result>
   </association>
--------------------------
 <select id="list" resultMap="base_map">
        SELECT e.id,e.name,d.id AS dept_id,d.name AS dept_name FROM t_employee e LEFT JOIN t_department d ON d.id=e.dept_id
    </select>

dept_ 采用 columnPrefix措施简化

 <association property="dept" javaType="Department" columnPrefix="dept_">
       <result column="id" property="id"/>
       <result column="name" property="name"></result>
   </association>

一级缓存

生命周期:
和session一样的生命周期.
通过session.get(1L),session.get(1L),总共两次get方法只会发一条SQL.第二次使用的是一级缓存的内容

//清除一级缓存中内容
session.clearCache();

针对数据量大的时候,使用分页+clearCache()及时清除缓存

2.One2Many部门2员工

one需要处理外键关系
员工类中的dept_id属性删除,并在部门类中增加员工对象emps.

public class Department {
    private Long id;
    private String name;
    private List<Employee> emps = new ArrayList<Employee>();

    public Department() {
    }
    public Department(String name) {
        this.name = name;
    }
//getter setter方法
//toString方法(id,name)
}

主配置文件中定义别名,注册mapper:

<typeAliases>
        <typeAlias type="com.mxl.mybatis02_day02.one2many.domain.Employee" alias="Employee"/>
        <typeAlias type="com.mxl.mybatis02_day02.one2many.domain.Department" alias="Department"/>
    </typeAliases>
 <mappers>
        <!--one2many-->
        <mapper resource="com/mxl/mybatis02_day02/one2many/EmployeeMapper.xml"></mapper>
        <mapper resource="com/mxl/mybatis02_day02/one2many/DepartmentMapper.xml"></mapper>
    </mappers>

两个mapper接口

public interface DepartmentMapper {
    void save(Department e);
    Department get(Long id);
    void handlerRelation(@Param("deptId")Long deptId,@Param("empId")Long empId);
}
----------------------------
public interface EmployeeMapper {
    void save(Employee e);
    Employee get(Long id);
}

两个mapper文件

<mapper namespace="com.mxl.mybatis02_day02.one2many.mapper.DepartmentMapper">
    <resultMap id="base_map" type="Department">
        <id column="id" property="id"/>
        <result property="name" column="name"/>
        <!--
        ofType:查询出来集合中的类型
        <collection column="id" property="emps" ofType="Employee" select="com.mxl.mybatis02_day02.one2many.mapper.EmployeeMapper.selectByDeptId"/>
        -->
        <collection property="emps" ofType="Employee">
            <result></result>
        </collection>
    </resultMap>

    <select id="get" parameterType="long" resultMap="base_map">
        select id,name from t_department where id = #{id}
    </select>

    <insert id="save" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_department (name) values (#{name})
    </insert>
    
    <update id="handlerRelation">
        update t_employee set dept_id = #{deptId} where id = #{empId}
    </update>
</mapper>
<mapper namespace="com.mxl.mybatis02_day02.one2many.mapper.EmployeeMapper">
    <insert id="save" keyProperty="id" keyColumn="id" parameterType="Employee" useGeneratedKeys="true">
        insert into t_employee (name) values (#{name})
    </insert>

    <select id="get" parameterType="long" resultType="Employee">
        select id,name,dept_id where id = #{id}
    </select>
    <select id="selectByDeptId" resultType="Employee">
        select id,name from t_employee where dept_id = #{deptId}
    </select>
</mapper>

测试:

public class TestOne2Many {
    @Test
    public void test01() {
        SqlSession session = MybatisUtils.openSession();
        EmployeeMapper eMapper = session.getMapper(EmployeeMapper.class);
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Employee e1 = new Employee("一号员工");
        Employee e2 = new Employee("二号员工");
        Department d = new Department("一号部门");

        d.getEmps().add(e1);
        d.getEmps().add(e2);

        eMapper.save(e1);
        eMapper.save(e2);
        dMapper.save(d);
        //需要由one方去处理外键关系
        List<Employee> es = d.getEmps();
        for (Employee e : es) {
            dMapper.handlerRelation(d.getId(),e.getId());
        }
        session.commit();
        session.close();
    }
    @Test
    public void testGet() {
    SqlSession session = MybatisUtils.openSession();
        DepartmentMapper dMapper = session.getMapper(DepartmentMapper.class);
        Department dept = dMapper.get(22L);
        System.out.println(dept);
        List<Employee> emps = dept.getEmps();
        for (Employee emp : emps) {
            System.out.println(emp);
        }
        session.close();
    }
}

3.many2many(教师2学生)

在这个地方,犯了个错误,就是用insert,update,delete更改数据库中的内容的时候,切记session.commit操作,要不然数据库中内容不会改变.

保存操作如下:

1.建数据库表,学生表,教师表,中间表(学生id,教师id)
2.教师类学生类分别提供id,name属性,无参及有参(name)构造器,对应属性的getter,setter方法.
3.在主配置文件中定义别名,并注册对应mapper.xml.
4.两个mapper接口

public interface StudentMapper {
    void save(Student t);
}
---------------------------------
public interface TeacherMapper {
    void save(Teacher t);
    void handlerRelation(@Param("teaId")Long teaId,@Param("stuId")Long stuId);
}

两个mapper.xml文件,注意TeacherMapperz中的handlerRelation

<mapper namespace="com.mxl.mybatis02_day02.many2many.mapper.StudentMapper">
	<insert id="save" parameterType="Student" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_student(name) values (#{name})
    </insert>
</mapper>

-------------------------------------------------------
<mapper namespace="com.mxl.mybatis02_day02.many2many.mapper.TeacherMapper">
    <insert id="save" parameterType="Teacher" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_teacher(name) values (#{name})
    </insert>
    <insert id="handlerRelation">
        insert into tea_stu (t_id,s_id) values (#{teaId},#{stuId})
    </insert>
</mapper>

测试类:

  @Test
    public void test(){
        Teacher t1 = new Teacher();
        t1.setName("老师一");
        Teacher t2 = new Teacher();
        t2.setName("老师二");

        Student s1 = new Student();
        s1.setName("学生一");
        Student s2 = new Student();
        s2.setName("学生二");

        t1.getStus().add(s1);
        t1.getStus().add(s2);
        t2.getStus().add(s1);
        t2.getStus().add(s2);

        SqlSession session = MybatisUtils.openSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        StudentMapper sMapper = session.getMapper(StudentMapper.class);

        tMapper.save(t1);
        tMapper.save(t2);
        sMapper.save(s1);
        sMapper.save(s2);

        //来处理中间表的的关系
        List<Student> t1Stus = t1.getStus();
        for (Student student : t1Stus) {
            tMapper.handlerRelation(t1.getId(),student.getId());
            System.out.println(student);
        }
        List<Student> t2Stus = t2.getStus();
        for (Student student : t2Stus) {
            tMapper.handlerRelation(t2.getId(),student.getId());
            System.out.println(student);
        }
        session.commit();
        session.close();
    }

查询操作

注意
resuilMap代替resultType

mapper接口中提供get方法.

public interface StudentMapper {
    Student get(Long id);
}
---------------------------------------
public interface TeacherMapper {
    Teacher get(Long id);
}

mapper的xml文件中:
StudentMapper

 	<select id="selectByTeaId" parameterType="long" resultType="Student">
      	  SELECT * FROM t_student WHERE id IN
      	  (SELECT s_id FROM tea_stu WHERE t_id IN
      	  (SELECT id FROM t_teacher WHERE id = #{teaId}))
    </select>

TeacherMapper

  <resultMap id="base_map" type="Teacher">
            <id column="id" property="id"/>
            <result property="name" column="name"/>
            <collection
                    property="stus"
                    ofType="Student"
                    column="id"
select="com.mxl.mybatis02_day02.many2many.mapper.StudentMapper.selectByTeaId"/>
        </resultMap>
        <select id="get" parameterType="long" resultMap="base_map">
            select id,name from t_teacher where id = #{id}
        </select>

测试:

    @Test
    public void testQ(){
        SqlSession session = MybatisUtils.openSession();
        TeacherMapper tMapper = session.getMapper(TeacherMapper.class);
        Teacher teacher = tMapper.get(9L);
        List<Student> stus = teacher.getStus();
        for (Student student : stus) {
            System.out.println(student);
        }
        System.out.println(teacher);
        session.close();
    }

-----------------------分隔符---------------------------------------------------

spring与mybatis简单集成(jar):

Mapper的使用
1.把mapper当做是Dao辅助工具
2.直接将mapper当做是Dao.
步骤:
1.导入相关的资源包
1.myBatis自身的包
2.spring相关的包
3.spring-mybatis-plugins.jar整合
数据库连接池druid.
在这里插入图片描述
2.创建resources添加配置文件
在这里插入图片描述
3.编写配置文件
1.导入外部文件db.properties
2.配置数据源
3.配置sessionFactory
4.配置事务管理器
5.配置事务模板
6.AOP切面配置
定义service,Mapper对应bean.

application.xml中内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--注解扫描-->
    <context:component-scan base-package="com.mxl.crm"/>

    <!--1.导入外部文件db.properties-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--2.配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${db.driverClassName}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean>
    <!--3.配置sessionFactory-->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/mxl/crm/mappper/*Mapper.xml"/>
        <!--4.配置别名-->
        <property name="typeAliasesPackage" value="com.mxl.crm.domain"/>
    </bean>
    <!--5.配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--6.配置事务模板-->
    <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="list*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <!--7.配置aop切面-->
    <aop:config>
        <aop:pointcut id="pointCut" expression="execution(* com.mxl.crm.service.*.*(..))"/>
        <aop:advisor advice-ref="advice" pointcut-ref="pointCut"/>
    </aop:config>

    <!--配置mapper-->
    <bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.mxl.crm.mappper"/>
    </bean>

    <!--配置service,mapper的bean-->
    <!--<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
        <!--<property name="mapperInterface" value="com.mxl.crm.mappper.UserMapper"></property>-->
    <!--</bean>-->
    <!--<bean  id="userService" class="com.mxl.crm.service.impl.UserServiceImpl">-->
        <!--<property name="mapper" ref="userMapper"></property>-->
    <!--</bean>-->
</beans>

1.service全都变成注解配置的方式.

2.在配置文件中添加注解扫描的配置

    <!--注解扫描-->
    <context:component-scan base-package="com.mxl.crm"/>

3.添加扫描mapper的类

 <!--配置mapper-->
    <bean id="configurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.mxl.crm.mappper"/>
    </bean>

最后:二级缓存

1.回顾hibernate中的缓存
二级缓存的生命周期和sessionFactory一样的生命周期
什么样类型的对象适合放入二级缓存
读远远大于写的对象.
hibernate中的缓存:
1.一级缓存
2.二级缓存
3.查询缓存(限制很多,命中率比较低)
开启二级缓存后,get (),insert(),get(); 总共发2条sql


MyBatis中的二级缓存.
一般来说,我们将myBatis中二级缓存说成是myBatis缓存

步骤:
1.需要在mapper文件中添加<cache />
2.缓存的对象需要实现序列化接口

myBatis开启二级缓存后,get (),insert(),get(); 总共发3条sql

在mybatis中无论是selectOne还是selectList都是使用查询缓存.当对象新增,更新,删除的时候,都回去清空查询缓存
让myBatis的缓存和hibernate中的二级缓存靠近
步骤:
1.让所有list都不是缓存 userCache=false
在这里插入图片描述 2.让新增操作不清空缓存. flashCache=false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的海滨体育馆管理系统,源码+数据库+毕业论文+视频演示 本基于Spring Boot的海滨体育馆管理系统设计目标是实现海滨体育馆的信息化管理,提高管理效率,使得海滨体育馆管理工作规范化、高效化。 本文重点阐述了海滨体育馆管理系统的开发过程,以实际运用为开发背景,基于Spring Boot框架,运用了Java技术和MySQL作为系统数据库进行开发,充分保证系统的安全性和稳定性。本系统界面良好,操作简单方便,通过系统概述、系统分析、系统设计、数据库设计、系统测试这几个部分,详细的说明了系统的开发过程,最后并对整个开发过程进行了总结,实现了海滨体育馆相关信息管理的重要功能。 本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高海滨体育馆管理效率。 关键词:海滨体育馆管理,Java技术,MySQL数据库,Spring Boot框架 本基于Spring Boot的海滨体育馆管理系统主要实现了管理员功能模块和学生功能模块两大部分,这两大功能模块分别实现的功能如下: (1)管理员功能模块 管理员登录后可对系统进行全面管理操作,包括个人中心、学生管理、器材管理、器材借出管理、器材归还管理、器材分类管理、校队签到管理、进入登记管理、离开登记管理、活动预约管理、灯光保修管理、体育论坛以及系统管理。 (2)学生功能模块 学生在系统前台可查看系统信息,包括首页、器材、体育论坛以及体育资讯等,没有账号的学生可进行注册操作,注册登录后主要功能模块包括个人中心、器材管理、器材借出管理、器材归还管理、校队签到管理、进入登记管理、离开登记管理、活动预约管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值