5.Spring+Mybatis+SpringMVC整合

前端时间搭建了一个关于新闻的后台,使用Restful风格,向前台提供json格式数据。

对于刚学习的时候会觉得整合三个框架是一件很难的事情,但是当自己都熟悉了之后再来整理下思路其实也没有那么难。

就是把三个模块整合运行起来,然后写上自己的业务逻辑就形成了一个项目。

今天把就思路整一下,加深自己的印象,首先谈一下这三个东西分别是什么。

spring

 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。 简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。


mybatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。MyBatis是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

springMVC

 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。


三大框架整合
前面已经介绍了环境的搭建和maven项目的创建,这里就不再赘述。下面直接看搭建过程。
现在我已经创建好了maven项目,如下图

1.maven中引入需要的jar包

接下来添加该项目所需要的jar包,maven的优点就体现出来了,再也不用到处找jar包考进项目了。
为了方便我把所有的相关jar依赖都贴出
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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.Test</groupId>
  <artifactId>test</artifactId>
  <packaging>war</packaging>
  <version>1.0.0-SNAPSHOT</version>
  <name>test Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <!-- 集中定义依赖版本号 -->
	<properties>
		<junit.version>4.10</junit.version>
		<spring.version>4.1.3.RELEASE</spring.version>
		<mybatis.version>3.2.8</mybatis.version>
		<mybatis.spring.version>1.2.2</mybatis.spring.version>
		<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
		<mysql.version>5.1.32</mysql.version>
		<slf4j.version>1.6.4</slf4j.version>
		<jackson.version>2.4.2</jackson.version>
		<druid.version>1.0.9</druid.version>
		<httpclient.version>4.3.5</httpclient.version>
		<jstl.version>1.2</jstl.version>
		<servlet-api.version>2.5</servlet-api.version>
		<jsp-api.version>2.0</jsp-api.version>
		<joda-time.version>2.5</joda-time.version>
		<commons-lang3.version>3.3.2</commons-lang3.version>
		<commons-io.version>1.3.2</commons-io.version>
		<mapper.version>2.3.4</mapper.version>
		<pagehelper.version>3.7.5</pagehelper.version>
	</properties>
    
  <dependencies>
    <!-- 单元测试 -->
			<dependency>
				<groupId>junit</groupId>
				<artifactId>junit</artifactId>
				<version>${junit.version}</version>
				<scope>test</scope>
			</dependency>

			<!-- Spring -->
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-context</artifactId>
				<version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-beans</artifactId>
				<version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-webmvc</artifactId>
				<version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-jdbc</artifactId>
				<version>${spring.version}</version>
			</dependency>
			<dependency>
				<groupId>org.springframework</groupId>
				<artifactId>spring-aspects</artifactId>
				<version>${spring.version}</version>
			</dependency>

			<!-- Mybatis -->
			<dependency>
				<groupId>org.mybatis</groupId>
				<artifactId>mybatis</artifactId>
				<version>${mybatis.version}</version>
			</dependency>
			<dependency>
				<groupId>org.mybatis</groupId>
				<artifactId>mybatis-spring</artifactId>
				<version>${mybatis.spring.version}</version>
			</dependency>
			<!-- 通用Mapper的依赖 -->
			<dependency>
				<groupId>com.github.abel533</groupId>
				<artifactId>mapper</artifactId>
				<version>${mapper.version}</version>
			</dependency>

			<!-- 分页助手 -->
			<dependency>
				<groupId>com.github.pagehelper</groupId>
				<artifactId>pagehelper</artifactId>
				<version>${pagehelper.version}</version>
			</dependency>
			<dependency>
				<groupId>com.github.jsqlparser</groupId>
				<artifactId>jsqlparser</artifactId>
				<version>0.9.1</version>
			</dependency>

			<!-- MySql -->
			<dependency>
				<groupId>mysql</groupId>
				<artifactId>mysql-connector-java</artifactId>
				<version>${mysql.version}</version>
			</dependency>

			<dependency>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-log4j12</artifactId>
				<version>${slf4j.version}</version>
			</dependency>
			<dependency>
			    <groupId>org.slf4j</groupId>
			    <artifactId>slf4j-api</artifactId>
			    <version>${slf4j.version}</version>
			</dependency>

			<!-- JacksonJson处理工具包 -->
			<dependency>
				<groupId>com.fasterxml.jackson.core</groupId>
				<artifactId>jackson-databind</artifactId>
				<version>${jackson.version}</version>
			</dependency>

			<!-- 连接池 -->
			<dependency>
				<groupId>com.jolbox</groupId>
				<artifactId>bonecp-spring</artifactId>
				<version>0.8.0.RELEASE</version>
			</dependency>
			
			
		
			
			<!-- httpclient -->
			<dependency>
				<groupId>org.apache.httpcomponents</groupId>
				<artifactId>httpclient</artifactId>
				<version>${httpclient.version}</version>
			</dependency>

			<!-- JSP相关 -->
			<dependency>
				<groupId>jstl</groupId>
				<artifactId>jstl</artifactId>
				<version>${jstl.version}</version>
			</dependency>
			<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>servlet-api</artifactId>
				<version>${servlet-api.version}</version>
				<scope>provided</scope>
			</dependency>
			<dependency>
				<groupId>javax.servlet</groupId>
				<artifactId>jsp-api</artifactId>
				<version>${jsp-api.version}</version>
				<scope>provided</scope>
			</dependency>

			<!-- 时间操作组件 -->
			<dependency>
				<groupId>joda-time</groupId>
				<artifactId>joda-time</artifactId>
				<version>${joda-time.version}</version>
			</dependency>

			<!-- Apache工具组件 -->
			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-lang3</artifactId>
				<version>${commons-lang3.version}</version>
			</dependency>
			<dependency>
				<groupId>org.apache.commons</groupId>
				<artifactId>commons-io</artifactId>
				<version>${commons-io.version}</version>
			</dependency>
			<dependency>
			    <groupId>commons-fileupload</groupId>
			    <artifactId>commons-fileupload</artifactId>
			    <version>1.3.3</version>
			</dependency>
			<!--Junit测试-->
			<dependency> 
	           <groupId>org.springframework</groupId>  
	           <artifactId>spring-test</artifactId>  
	           <version>4.0.2.RELEASE</version>  
      		</dependency>
      		
  </dependencies>
  <build>
  	<plugins>
  		<!-- 配置Tomcat插件 ,用于启动项目 -->
		<plugin>
			<groupId>org.apache.tomcat.maven</groupId>
			<artifactId>tomcat7-maven-plugin</artifactId>
			<configuration>
				<port>8080</port>
				
				<!-- 访问路径为:http://127.0.0.1:80/项目名
				即:http://127.0.0.1:{port}/{path}
				现在访问某项目的路径为:httP://127.0.0.1:80/即可 -->
				
				<path>/test</path>
			</configuration>
		</plugin>
  	</plugins>
  </build>
  
</project>



添加完成后保存可以看到依赖的jar包情况。

2.spring与mybatis的整合

2.1创建jdbc属性文件
记录关于数据库的连接地址及用户名和密码

jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.username=root
jdbc.password=root



2.2建立spring-mybatis.xml配置文件
这个相当于spring容器,上一步编写了jdbc属性文件,那么如何能让项目制定这个jdbc文件的存在并读取它的数据呢?
这时就需要用该配置文件进行读取了。


该文件包括如下几个部分:
(1)读取资源文件,配置数据源及连接数据库
(2)扫描包及代码存放的路径
(3)spring与mybatis的整合
(4)事务管理
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"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
                       
<!--读取jdbc资源文件  -->  
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<!-- 允许JVM参数覆盖 -->
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
		<!-- 忽略没有找到的资源文件 -->
		<property name="ignoreResourceNotFound" value="true" />
		<!-- 配置资源文件 -->
		<property name="locations">
			<list>
				<value>classpath:jdbc.properties</value>
			</list>
		</property>
	</bean> 

<!-- 配置数据源 -->
	<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
		destroy-method="close">
		<!-- 数据库驱动 -->
		<property name="driverClass" value="${jdbc.driver}" />
		<!-- 相应驱动的jdbcUrl -->
		<property name="jdbcUrl" value="${jdbc.url}" />
		<!-- 数据库的用户名 -->
		<property name="username" value="${jdbc.username}" />
		<!-- 数据库的密码 -->
		<property name="password" value="${jdbc.password}" />
		<!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 -->
		<property name="idleConnectionTestPeriod" value="60" />
		<!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 -->
		<property name="idleMaxAge" value="30" />
		<!-- 每个分区最大的连接数 -->
		<!-- 
			判断依据:请求并发数
		 -->
		<property name="maxConnectionsPerPartition" value="100" />
		<!-- 每个分区最小的连接数 -->
		<property name="minConnectionsPerPartition" value="5" />
	</bean>                    
<!-- 扫描包 -->
	<context:component-scan base-package="com.test"/>     
	
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:mybaits/mappers/*.xml"></property>  
    </bean>  
  
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.test.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean> 
    
<!-- 定义事务管理器 -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>	                   
</beans>



2.3Log4j的配置
为了方便调试,一般都会使用日志来输出信息,Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。 
      Log4j的配置很简单,而且也是通用的,下面给出一个基本的配置,换到其他项目中也无需做多大的调整,如果想做调整或者想了解Log4j的各种配置,参看一篇博文,很详细:点击打开链接,看到一篇不错的日志介绍《
日志组件slf4j介绍及配置详解

Log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E


### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n


### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = D://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n


### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =D://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n



2.4JUnit测试

经过以上步骤,我们已经完成了spring和mybatis的整合,这样我们就可以写一段测试代码来测试下整合是否成功。

2.4.1创建测试表

在连接的数据库中创建一个测试用表

sql语句如下:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  `password` varchar(64) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;



2.4.2利用Mybatis Generator自动创建代码

具体参考文章:mybatis自动生成代码

2.4.3建立service接口和实现类

目录结构:

下面给出具体的内容:
UserService.java
package com.test.service;

import com.test.pojo.User;

public interface UserService {
    public User getUserById(int id);
}
UserServiceImpl.java
package com.test.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.test.dao.UserMapper;
import com.test.pojo.User;
import com.test.service.UserService;

@Service
public class UserServiceImpl implements UserService{
    @Autowired
    private UserMapper userMapper;

    public User getUserById(int id) {
        return this.userMapper.selectByPrimaryKey(id);
    }
}



2.4.4建立测试类
测试类在src/test/java中建立,下面测试类中注释掉的部分是不使用Spring时,一般情况下的一种测试方法;如果使用了Spring那么就可以使用注解的方式来引入配置文件和类,然后再将service接口对象注入,就可以进行测试了。 
       如果测试成功,表示Spring和Mybatis已经整合成功了。输出信息使用的是Log4j打印到控制台。




UserServiceImplTest.java
package com.test.service.impl;


import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


import com.test.pojo.User;
import com.test.service.UserService;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/spring-mybaits.xml"})


public class UserServiceImplTest {
    @Autowired
    private static UserService userService;
    
    @BeforeClass
    public static void init() {//junit之前init spring
        ApplicationContext   context = new ClassPathXmlApplicationContext("classpath:spring/spring-mybaits.xml");
        userService = (UserService)context.getBean("userServiceImpl");
    }


    @Test
    public void testGetUserById() {
        User user=this.userService.getUserById(1);
        System.out.println("-----------------------");
        System.out.println(user);
        System.out.println("-----------------------");
    
    }
为了便于查看效果,可以在user.java中添加toString()方法
package com.test.pojo;

public class User {
    private Integer id;

    private String name;

    private String password;

    private Integer age;

    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 == null ? null : name.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        
        return name+"今年"+age+"岁了";
    }
}

测试这个代码之前一直没有仔细了解过关于测试的东西,这次的测试弄了老半天才弄出来。





spring+mybatis的整合中暂时不用管web.xml
测试结果如下图


3.整合springMVC
上面把spring和mybatis整合测试没有问题后,下面进行springMVC的整合

3.1配置springMVC配置文件

创建了一个spring-mvc.xml的配置文件和jsp文件夹(用于视图模式下定义的路径)

spring-mvc.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"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
    
    <!-- 配置注解驱动 -->
	<mvc:annotation-driven/>
	
	<!-- 扫描controller包 -->
	<context:component-scan base-package="com.test.controller"/>
	
	<!-- 配置视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
</beans>  


主要就是注解驱动、扫描controller包、视图解析器。其他若用到的一些配置可以后期再添加。

3.2web.xml
在这个文件中配置spring-mybatis.xml和spring-mvc.xml两个文件,就是SSM的整合。
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_3_0.xsd"  
    version="3.0">  
    
    <display-name>test</display-name>
    <welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	
	<!-- 加载spring-mybatis -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/spring-mybaits.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
		
	<!-- springmvc的前端控制器 -->
	<servlet>
		<servlet-name>test</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>test</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>


3.3测试
以上就是SSM整合的完整步骤,下面进行测试
3.3.1新建jsp页面

showUser.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SSM整合测试</title>
</head>
<body>
${user.name }
</body>
</html>




3.3.2编写controller控制器
UserController.java

package com.test.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.test.pojo.User;
import com.test.service.UserService;

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/showUser")
    public String getUserById(Integer id,Model model){
      //Integer id1=Integer.parseInt(id);
      User user = this.userService.getUserById(id);
      model.addAttribute("user", user);
      return "showUser";
    }
}





3.3.3启动maven项目
详细见此链接
3.3.4启动项目并访问
在浏览器中输入:http://localhost:8080/test


出现该页面的原因是我在web.xml中配置了欢迎页。

继续访问:http://localhost:8080/test/user/showUser?id=1


访问成功。说明SSM整合没有问题,下面就可以在该项目中添加业务逻辑代码了。


遇到的问题:
1.在启动项目的web.xml中配置前端控制器的时候,拦截路径设置为/*。项目可以正常启动,带上用上面的路径去访问总是报404错误,把*去掉再去访问就成功了,不晓得什么原因,还需要好好研究一下。谨记!!!







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值