spring3+mbatis3开发实例

最近一直在深入了解struts2,spring,hibernate以及mybatis框架,通过查看这些框架的源码和官方文档,发现自己对于这些框架的原理,使用有了更深的理解,那么今天
我给大家带来的是运用spring和mybatis这两个框架来开发的小例子,并给大家讲述一些开发中需要注意的一些细节。
1、新建一个web项目,修改web.xml文件,我的文件内容如下,大家把需要的拷走就行:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>dreamMall-dubbo-provider</display-name>
<!-- 加载spring文件监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 加载log4j监听器 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- 解决spring容器运行时可能产生的内存溢出 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- spring文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</context-param>
<!-- log4j文件路径 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<!-- 开启watchdog线程监测配置文件的变化 -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<!-- 设置编码格式 -->
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置session超时时间 -->
<session-config>
         <session-timeout>30</session-timeout>
    </session-config>
</web-app>
2、新建spring-app.xml和spring-mybatis.xml文件,其中:
spring-app.xml:
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="  
    http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop     
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/tx  
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"  default-autowire="byName">
   <context:component-scan base-package="com.mall.dubbo" /> 
   <aop:aspectj-autoproxy />
</beans> 
注释的方法大家不用管,这些是我在下一篇博客要给大家带来的关于spring中aop的技术以及使用aop实现事务的管理
spring-mybatis.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="  
    http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
default-autowire="byName">
<bean id="dbConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<!-- <context:property-placeholder location="classpath:jdbc.properties" /> -->
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/dreammall?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="1" />
</bean>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="mapperLocations" value="classpath:com/mall/dubbo/map/*.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 注册Mapper方式二:也可不指定特定mapper,而使用自动扫描包的方式来注册各种Mapper ,配置如下: -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mall.dubbo.dao" />
<property name="markerInterface" value="com.mall.dubbo.dao.GenericDao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> 
</bean>

</beans> 

这里大家需要关注的是Mapper的注册方式,这里我采用的所有的dao都继承GenericiDao,这样的话,你就不需要再去一个一个Mapper的注册,开发中经常使用的是这种方式。

3、这里我需要简单的表述一下我的数据库中表的对于关系,我用了测试的有三个表,teacher表,cource表,student表,我假定一个teacher教一门Cource,一个teacher交
n个student,下面我用3个实体类来描述着三者的关系:
cource.java:
package com.mall.dubbo.entity;

import java.io.Serializable;

public class Cource implements Serializable {


/**
* 
*/
private static final long serialVersionUID = 1L;

private int id;

private String courceName;

private int teacherId;


public int getId() {
return id;
}


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





public int getTeacherId() {
return teacherId;
}


public void setTeacherId(int teacherId) {
this.teacherId = teacherId;
}



public String getCourceName() {
return courceName;
}


public void setCourceName(String courceName) {
this.courceName = courceName;
}


@Override
public String toString() {
return "Cource [id=" + id + ", courceName=" + courceName + "]";
}




}


student.java:
package com.mall.dubbo.entity;


import java.io.Serializable;


public class Student implements Serializable {


/**
* 
*/
private static final long serialVersionUID = 1L;

private int id;

private int age;

private String studentName;

private int sex;

private int teacherId;


public int getId() {
return id;
}


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


public int getAge() {
return age;
}


public void setAge(int age) {
this.age = age;
}


public String getStudentName() {
return studentName;
}


public void setStudentName(String studentName) {
this.studentName = studentName;
}


public int getSex() {
return sex;
}


public void setSex(int sex) {
this.sex = sex;
}


public int getTeacherId() {
return teacherId;
}


public void setTeacherId(int teacherId) {
this.teacherId = teacherId;
}


@Override
public String toString() {
return "Student [id=" + id + ", age=" + age + ", studentName="
+ studentName + ", sex=" + sex + "]";
}




}

Teacher.java:
package com.mall.dubbo.entity;


import java.io.Serializable;
import java.util.List;


public class Teacher implements Serializable{


/**
* 
*/
private static final long serialVersionUID = 1L;

private int id;

private String teacherName;

private int sex;

private int age;

private Cource cource;

private List<Student> students;


public int getId() {
return id;
}


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


public String getTeacherName() {
return teacherName;
}


public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}


public int getSex() {
return sex;
}


public void setSex(int sex) {
this.sex = sex;
}


public int getAge() {
return age;
}


public void setAge(int age) {
this.age = age;
}





public Cource getCource() {
return cource;
}


public void setCource(Cource cource) {
this.cource = cource;
}


public List<Student> getStudents() {
return students;
}


public void setStudents(List<Student> students) {
this.students = students;
}


@Override
public String toString() {
return "Teacher [id=" + id + ", teacherName=" + teacherName + ", sex="
+ sex + ", age=" + age + "]";
}

}


4、建立映射关系,这部分是最重要的,这里面的知识点,我希望大家可以好好看,如果有什么问题的,可以评论留言,或者去查看mybatis3.2的官方文档
地址是 http://wenku.baidu.com/link?url=L6Lu0GufwrMCgBLGUbsfGy7Os6s7MEcKIsZQj7JhOxIo6BSbsULynqsWeqX0mIyIqkzLIozaQvnaAUROrWypUDQj3QBfe5j6jO3solfO3-G

cource.xml: 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mall.dubbo.dao.CourceDao">
<resultMap type="com.mall.dubbo.entity.Cource" id="courceMap">
<id property="id" column="id" javaType="int" jdbcType="INTEGER"/>
<result property="courceName" column="cource_name" javaType="String" jdbcType="VARCHAR"/>
<result property="teacherId" column="teacher_id" javaType="int" jdbcType="INTEGER"/>
</resultMap>

<parameterMap type="com.mall.dubbo.entity.Cource" id="paraMap">
<parameter property="id"/>
<parameter property="courceName"/>
<parameter property="teacherId"/>
</parameterMap>

<sql id="courceSql">id,cource_name,teacher_id</sql>

<select id="selectAll" resultMap="courceMap">
select <include refid="courceSql"/> from cource
</select>

<select id="selectById" parameterType="int" resultMap="courceMap">
select <include refid="courceSql"/> from cource where
id=#{id,javaType=int,jdbcType=INTEGER}
</select>

<insert id="addCource" parameterMap="paraMap">
insert into cource (<include refid="courceSql"/>) values(
#{id,javaType=int,jdbcType=INTEGER},
#{courceName,javaType=String,jdbcType=VARCHAR},
#{teacherId,javaType=int,jdbcType=INTEGER}
)
</insert>

<update id="updateCourceById" parameterType="com.mall.dubbo.entity.Cource">
update cource set
cource_name=#{courceName,javaType=String,jdbcType=VARCHAR},
teacher_id=#{teacherId,javaType=int,jdbcType=INTEGER}
where id=#{id,javaType=int,jdbcType=INTEGER}
</update>

<delete id="deleteCourceById" parameterType="int">
delete from cource where id=#{id,javaType=int,jdbcType=INTEGER}
</delete>
<delete id="deleteAll">
delete from cource
</delete>
</mapper>

student.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mall.dubbo.dao.StudentDao">
<resultMap type="com.mall.dubbo.entity.Student" id="studentMap">
<id property="id" column="id" javaType="int" jdbcType="INTEGER"/>
<result property="age" column="age" javaType="int" jdbcType="INTEGER"/>
<result property="studentName" column="student_name" javaType="String" jdbcType="VARCHAR"/>
<result property="sex" column="sex" javaType="int" jdbcType="INTEGER"/>
<result property="teacherId" column="teacher_id" javaType="int" jdbcType="INTEGER"/>
</resultMap>
<parameterMap type="com.mall.dubbo.entity.Student" id="parameMap">
<parameter property="id"/>
<parameter property="age"/>
<parameter property="studentName"/>
<parameter property="sex"/>
<parameter property="teacherId"/>
</parameterMap>
<sql id="studentSql">id,age,student_name,sex,teacher_id</sql>

<select id="selectAll" resultMap="studentMap">
select <include refid="studentSql"/> from student
</select>

<select id="selectById" parameterType="int" resultMap="studentMap">
select <include refid="studentSql"/> from student where id=#{id,javaType=int,jdbcType=INTEGER}
</select>

<insert id="addStudent" parameterType="com.mall.dubbo.entity.Student">
insert into student(<include refid="studentSql"/>) values (
#{id,javaType=int,jdbcType=INTEGER},
#{age,javaType=int,jdbcType=INTEGER},
#{studentName,javaType=String,jdbcType=VARCHAR},
#{sex,javaType=int,jdbcType=INTEGER},
#{teacherId,javaType=int,jdbcType=INTEGER}
)
</insert>

<update id="updateStudentById" parameterMap="parameMap">
update student set
age=#{age,javaType=int,jdbcType=INTEGER},
student_name=#{studentName,javaType=String,jdbcType=VARCHAR},
sex=#{sex,javaType=int,jdbcType=INTEGER},
teacher_id=#{teacherId,javaType=int,jdbcType=INTEGER}
where id=#{id,javaType=int,jdbcType=INTEGER}
</update>

<delete id="deleteStudentById" parameterType="int">
delete from student where id=#{id,javaType=int,jdbcType=INTEGER}
</delete>

<delete id="deleteAll">
delete from student
</delete>
</mapper>

teacher.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.mall.dubbo.dao.TeacherDao">
<resultMap type="com.mall.dubbo.entity.Teacher" id="TeacherMap">
<id property="id" column="id" javaType="int" jdbcType="INTEGER" />
<result property="teacherName" column="teacher_name" javaType="String"
jdbcType="VARCHAR" />
<result property="age" column="age" javaType="int" jdbcType="INTEGER" />
<result property="sex" column="sex" javaType="int" jdbcType="INTEGER" />
<!-- 方法一 -->
<!-- 使用这种方式,coulumn的名字不能重复,否则识别不了 -->
<association property="cource" javaType="com.mall.dubbo.entity.Cource">
<id property="id" column="cource_id" javaType="int" jdbcType="INTEGER" />
<result property="courceName" column="cource_name" javaType="String"
jdbcType="VARCHAR" />
<result property="teacherId" column="c_teacher_id" javaType="int"
jdbcType="INTEGER" />
</association>
<!-- 方法二 -->
<!-- <association property="cource" javaType="com.mall.dubbo.entity.Cource" 
resultMap="courceMap"/> -->
<!-- 方法三 -->
<association property="cource" javaType="com.mall.dubbo.entity.Cource" 
column="teacher_id" select="selectCourceById"/>


<!-- 方法一 -->
<!-- 使用这种方式,coulumn的名字不能重复,否则识别不了 -->
<collection property="students" ofType="com.mall.dubbo.entity.Student">
<id property="id" column="student_id" javaType="int" jdbcType="INTEGER" />
<result property="age" column="s_age" javaType="int" jdbcType="INTEGER" />
<result property="studentName" column="student_name" javaType="String"
jdbcType="VARCHAR" />
<result property="sex" column="s_sex" javaType="int" jdbcType="INTEGER" />
<result property="teacherId" column="s_teacher_id" javaType="int"
jdbcType="INTEGER" />
</collection>
<!-- 方法二 -->
<!-- <collection property="students" ofType="com.mall.dubbo.entity.Student" 
resultMap="studentMap"/> -->
<!-- 方法三 -->
<!-- <collection property="students" ofType="com.mall.dubbo.entity.Student" 
column="teacher_id" select="selectStudentByTeacherId"/> -->
</resultMap>


<!-- 对应于方法二 -->
<!-- <resultMap type="com.mall.dubbo.entity.Cource" id="courceMap"> <id 
property="id" column="cource_id" javaType="int" jdbcType="INTEGER"/> 
<result property="courceName" column="cource_name" javaType="String" jdbcType="VARCHAR"/> 
<result property="teacherId"  column="c_teacher_id" javaType="int" jdbcType="INTEGER"/> 
</resultMap> -->
<!-- 对应于方法二 -->
<!-- <resultMap type="com.mall.dubbo.entity.Student" id="studentMap"> <id 
property="id" column="student_id" javaType="int" jdbcType="INTEGER"/> 
<result property="age" column="s_age" javaType="int" jdbcType="INTEGER"/>
<result property="studentName" column="student_name" javaType="String" jdbcType="VARCHAR"/> 
<result property="sex" column="s_sex" javaType="int" jdbcType="INTEGER"/>
<result property="teacherId" column="s_teacher_id" javaType="int" jdbcType="INTEGER"/> 
</resultMap> -->
<parameterMap type="com.mall.dubbo.entity.Teacher" id="paraMap">
<parameter property="id" />
<parameter property="teacherName" />
<parameter property="age" />
<parameter property="sex" />
</parameterMap>
<sql id="teacherSql">id,teacher_name,age,sex</sql>
<!-- 对应于方法三 -->
<!-- <select id="selectCourceByTeacherId" parameterType="int" resultType="com.mall.dubbo.entity.Cource"> 
select * from cource where teacher_id=#{id,javaType=int,jdbcType=INTEGER} 
</select>
<select id="selectStudentByTeacherId" parameterType="int" resultType="com.mall.dubbo.entity.Student"> 
select * from student where teacher_id=#{id,javaType=int,jdbcType=INTEGER} 
</select> -->
<select id="selectTeacerById" parameterType="int" resultMap="TeacherMap">
select t.*,s.id student_id,s.age s_age,s.sex s_sex,s.teacher_id s_teacher_id,s.student_name,
c.id cource_id,c.cource_name,c.teacher_id c_teacher_id
from teacher t join cource c on t.id=c.teacher_id left outer join student
s on t.id=s.teacher_id
where t.id=#{id,javaType=int,jdbcType=INTEGER}
</select>
<!-- <select id="selectTeacerById" parameterType="int" resultMap="TeacherMap">
select * from teacher where id=#{id,javaType=int,jdbcType=INTEGER}
</select> -->
<select id="selectAll" resultMap="TeacherMap">
select t.*,s.id student_id,s.age s_age,s.sex s_sex,s.teacher_id s_teacher_id,s.student_name,
c.id cource_id,c.cource_name,c.teacher_id c_teacher_id
from teacher t join cource c on t.id=c.teacher_id left outer join student
s on t.id=s.teacher_id
</select>
<insert id="addTeacher" parameterMap="paraMap">
insert into teacher(
<include refid="teacherSql" />
)values(
#{id,javaType=int,jdbcType=INTEGER},
#{teacherName,javaType=String,jdbcType=VARCHAR},
#{age,javaType=int,jdbcType=INTEGER},
#{sex,javaType=int,jdbcType=INTEGER}
)
</insert>
</mapper>

以上就是三者的映射关系,在这里对于student.xml和cource.xml我不想过多的去说,大家注意resultMap,resultType,paramType,paramMap这四个属性的不同就行
我重点讲一下teacher.xml文件中的映射关系,这里面涉及到collection和association这两个元素,这两个元素分别代表者1对多和1对1的关系,需要注意的是,
查询的结果总不要有相同的字段名,如果存在相同的字段名会覆盖,从而导致查询的结果不对。

5、对应的Dao接口
GenericDao:
package com.mall.dubbo.dao;


public interface GenericDao {


}

该接口是所有的dao接口的父接口,对于与配置文件中的markerInterface

CourceDao:
package com.mall.dubbo.dao;


import org.springframework.stereotype.Repository;


import com.mall.dubbo.entity.Cource;


@Repository
public interface CourceDao extends GenericDao {


public abstract void addCource(Cource cource);

public abstract Cource selectById(int id);

public abstract void updateCourceById(Cource cource);
}

StudentDao:
package com.mall.dubbo.dao;


import com.mall.dubbo.entity.Student;
@Repository
public interface StudentDao extends GenericDao {


public abstract void addStudent(Student student);
}


TeacherDao:


package com.mall.dubbo.dao;


import java.util.List;


import org.springframework.stereotype.Repository;


import com.mall.dubbo.entity.Teacher;


@Repository
public interface TeacherDao extends GenericDao{


public abstract void addTeacher(Teacher teacher);

public abstract Teacher selectTeacerById(int id);

public abstract List<Teacher> selectAll();

}

6、编写测试类
CourceTest.java:
package com.mall.dubbo.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;


import com.mall.dubbo.dao.CourceDao;
import com.mall.dubbo.entity.Cource;


public class CourceTest {


private ApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-mybatis.xml");

@Test
public void addCource(){

Cource cource = new Cource();
cource.setCourceName("English");
cource.setId(2);
cource.setTeacherId(1);

CourceDao dao = context.getBean(CourceDao.class);

dao.addCource(cource);
}

//@Test
public void getCourceById(){

CourceDao dao = context.getBean(CourceDao.class);

Cource c = dao.selectById(1);

System.out.println(c);
}

//@Test
public void updateCourceById(){
Cource cource = new Cource();
cource.setCourceName("France");
cource.setId(1);
cource.setTeacherId(2);
CourceDao dao = context.getBean(CourceDao.class);
dao.updateCourceById(cource);
}
}

StudentTest.java:
package com.mall.dubbo.test;


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;


import com.mall.dubbo.dao.StudentDao;
import com.mall.dubbo.entity.Student;


public class StudentTest {


ApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-mybatis.xml");

StudentDao dao = context.getBean(StudentDao.class);

@Test
public void addStudentTest(){

Student stu = new Student();
stu.setAge(21);
stu.setId(3);
stu.setSex(1);
stu.setStudentName("zhangqi");
stu.setTeacherId(1);

dao.addStudent(stu);
}
}
TeacherTest.java:
package com.mall.dubbo.test;


import java.util.List;


import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;


import com.mall.dubbo.dao.TeacherDao;
import com.mall.dubbo.entity.Cource;
import com.mall.dubbo.entity.Student;
import com.mall.dubbo.entity.Teacher;


public class TeacherTest {


ApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-mybatis.xml");


TeacherDao dao = context.getBean(TeacherDao.class);

//@Test
public void addTeacherTest(){

Teacher t = new Teacher();

t.setAge(45);
t.setId(1);
t.setSex(0);
t.setTeacherName("liusanming");

dao.addTeacher(t);
}

@Test
public void getTeacherById(){

Teacher t = dao.selectTeacerById(1);
Cource c = t.getCource();
List<Student> stus = t.getStudents();
System.out.println(stus+","+stus.size());
System.out.println(c);
System.out.println(t);
}
//@Test
public void getTeachers(){
List<Teacher> ts = dao.selectAll();
System.out.println(ts.size());
Teacher t = ts.get(0);
Cource c = t.getCource();
List<Student> stus = t.getStudents();
System.out.println(stus+","+stus.size());
System.out.println(c);
System.out.println(t);


}
}

到此整个的开发过程就结束了,内容有点多,希望能够对大家有帮助。大家如果有什么问题,请留言!
本人也毕业未满一年,如果讲的有什么不对的地方,请指正,我们一块进步,谢谢!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值