集成spring、springMVC、mybatis、JSP完整示例

112 篇文章 0 订阅
40 篇文章 0 订阅

我们将通过几个实例来学习 MyBatis 的用法,提供的例子中不仅仅只有MyBatis 部分的代码,还包含Service、Controller、JSP 的代码。

这一节会通过一整套的代码来演示MyBatis在项目开发中的基本用法。按照自下而上的顺序进行开发,从Mapper开始,依次开发 Service 层、Controller 层、JSP 前端页面。在实际开发过程中,可能会根据每一层的需求对各层接口进行调整。

基本准备

在开始之前需要先准备数据库、表和数据,配置的数据源连接的仍是本地的 mybatis数据库,这一节会新增一个字典表,然后针对这个字典表进行增、删、改、查4类操作。字典表的建表语句和基础数据的SQL如下。

drop table if exists n_sysdict;
create table n_sysdict(
	id int not null auto_increment,
	code varchar(64) not null comment '类型',
	name varchar(64) not null comment '字典名',
	value varchar(64) not null comment '字典值',
	primary key(id)
) comment '字典表';

insert into n_sysdict values (1,'性别','男','女');
insert into n_sysdict values (2,'性别','女','女');
insert into n_sysdict values (3,'季度','第一季度','1');
insert into n_sysdict values (4,'季度','第二季度','2');
insert into n_sysdict values (5,'季度','第三季度','3');
insert into n_sysdict values (6,'季度','第四季度','4');

项目情况截图

 

导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<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.shrimpking</groupId>
    <artifactId>mybatis-04</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- 清单管理   -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>4.3.10.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--  spring上下文,核心      -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <!--  jdbc      -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <!-- spring事务       -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
        <!--  spring面向切面      -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <!-- aop依赖       -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
        </dependency>
        <!-- spring web 核心       -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <!-- spring mvc       -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <!-- spring mvc-json依赖       -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.4</version>
        </dependency>
        <!--        -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- mybatis       -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- mysql驱动       -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- jstl模板       -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>

</project>

实体类 

在src/main/java中新建tcom.shrimpking.pojo包,然后新建SysDict实体类。

SysDict.java

package com.shrimpking.pojo;

import java.io.Serializable;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/6/12 15:32
 */
public class SysDict implements Serializable
{
    /**
     *     可序列化
     */
    private static final long serialVersionUID=1L;

    private Integer id;
    private String code;
    private String name;
    private String value;

    public SysDict()
    {
    }

    public SysDict(Integer id, String code, String name, String value)
    {
        this.id = id;
        this.code = code;
        this.name = name;
        this.value = value;
    }

    public Integer getId()
    {
        return id;
    }

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

    public String getCode()
    {
        return code;
    }

    public void setCode(String code)
    {
        this.code = code;
    }

    public String getName()
    {
        return name;
    }

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

    public String getValue()
    {
        return value;
    }

    public void setValue(String value)
    {
        this.value = value;
    }

    @Override
    public String toString()
    {
        return "SysDict{" + "id=" + id + ", code='" + code + '\'' + ", name='" + name + '\'' + ", value='" + value + '\'' + '}';
    }
}

开发Mapper层(Dao层)

Mapper层也就是常说的数据访问层(Dao 层)。使用Mapper接口和XML映射文件结合的方式进行开发,集成 MyBatis 的配置中,自动扫描接口的包名为 com.shrimpking.mapper,因此在创建Mapper接口所在的包时也要参照这个命名规则。

在src/main/java中新建com.shrimpking.mapper包,然后新建SysDictMapper接口。

SysDictMapper.java

package com.shrimpking.mapper;

import com.shrimpking.pojo.SysDict;
import org.apache.ibatis.session.RowBounds;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/6/12 15:37
 */
public interface SysDictMapper
{
    /**
     * 通过id查询
     * @param id
     * @return
     */
    SysDict selectById(Integer id);

    /**
     * 通过条件查询多个
     * @param sysDict
     * @return
     */
    List<SysDict> selectList(SysDict sysDict, RowBounds rowBounds);

    /**
     * 新增
     * @param sysDict
     * @return
     */
    int insert(SysDict sysDict);

    /**
     * 修改
     * @param sysDict
     * @return
     */
    int updateById(SysDict sysDict);

    /**
     * 删除
     * @param id
     * @return
     */
    int deleteById(Integer id);
}

同时,SqlSessionFactoryBean 中也配置了扫描 XML 映射文件的目录。

applicationContext.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:context="http://www.springframework.org/schema/context"
       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">

    <context:component-scan base-package="com.shrimpking.service.impl"/>

    <bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimeZone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="mysql123"/>
    </bean>

    <import resource="mybatis-servlet.xml"/>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations">
            <array>
                <value>classpath:com/shrimpking/mapper/*.xml</value>
            </array>
        </property>
        <property name="typeAliasesPackage" value="com.shrimpking.pojo"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.shrimpking.mapper"/>
    </bean>
</beans>

在src/main/resources中新建com/shrimpking/mapper/目录,然后新建SysDictMapper.xml文件。

首先,当需要查看或修改某个具体的字典信息时,要有一个通过主键获取字典信息的方法,在Mapper接口和对应的XML中分别添加如下代码。

SqlSessionFactoryBean 时,将 typeAliasesPackage 配置为com.shrimpking.pojo,所以这里设置resultType时可以直接使用类名,省略包名。

以下代码依次是根据字典参数和分页参数查询字典信息的方法,新增、更新、删除字典的接口的方法。

SysDictMapper.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.shrimpking.mapper.SysDictMapper">

    <!-- 通过id查询   -->
    <select id="selectById" resultType="sysDict">
        select id,code,name,value from n_sysdict where id=#{id}
    </select>

    <!-- 通过条件查询多个   -->
    <select id="selectList" resultType="sysDict">
        select id,code,name,value from n_sysdict
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="code != null and code != ''">
                and code = #{code}
            </if>
        </where>
        order by code,value
    </select>

    <!-- 新增  -->
    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into n_sysdict(code,name,value)
        values (#{code},#{name},#{value})
    </insert>

    <!--  修改  -->
    <update id="updateById">
        update n_sysdict set
        code = #{code},
        name = #{name},
        value = #{value}
        where id = #{id}
    </update>

    <!-- 删除   -->
    <delete id="deleteById">
        delete from n_sysdict where id = #{id}
    </delete>

</mapper>

这5个方法都是很基础的方法,通过这5个方法就可以实现字典表的基本操作。

下面将在这5个接口的基础上,继续编写Service层的代码。

开发业务层(Service层)

虽然针对接口编程对小的项目来说并不重要,但是这里为了形式上的需要仍然提供了Service接口。在src/main/java中新建com.shrimpking.service包,然后添加SysDictService接口,代码如下。

SysDictService.java

package com.shrimpking.service;

import com.shrimpking.pojo.SysDict;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/6/12 15:54
 */
public interface SysDictService
{
    /**
     * 通过id查询
     * @param id
     * @return
     */
    SysDict getById(Integer id);

    /**
     * 通过条件查询多个
     * @param sysDict
     * @param offset
     * @param limit
     * @return
     */
    List<SysDict> getList(SysDict sysDict, Integer offset,Integer limit);

    /**
     * 新增或修改
     * @param sysDict
     * @return
     */
    boolean saveOrUpdate(SysDict sysDict);

    /**
     * 删除
     * @param id
     * @return
     */
    boolean deleteById(Integer id);


}

Service层的saveOrUpdate方法对应Mapper中的insert和updateById方法,其他3 个方法和 Mapper 层方法一 一 对应。在 com.shrimpking.service 包下创建 impl 包,然后新建SysDictService接口的实现类SysDictServiceImpl,代码如下。

SysDictServiceImpl.java

package com.shrimpking.service.impl;

import com.shrimpking.mapper.SysDictMapper;
import com.shrimpking.pojo.SysDict;
import com.shrimpking.service.SysDictService;
import com.sun.istack.internal.NotNull;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/6/12 15:57
 */
@Service
public class SysDictServiceImpl implements SysDictService
{
    @Autowired
    private SysDictMapper sysDictMapper;

    /**
     * 通过id查询
     * @param id
     * @return
     */
    @Override
    public SysDict getById(@NotNull Integer id)
    {
        return sysDictMapper.selectById(id);
    }

    /**
     * 通过条件查询多个,可以分页,mysql方式
     * @param sysDict
     * @param offset
     * @param limit
     * @return
     */
    @Override
    public List<SysDict> getList(SysDict sysDict, Integer offset, Integer limit)
    {
        RowBounds rowBounds = RowBounds.DEFAULT;
        if(offset != null && limit != null)
        {
            rowBounds = new RowBounds(offset,limit);
        }
        return sysDictMapper.selectList(sysDict,rowBounds);
    }

    /**
     * 新增或修改
     * @param sysDict
     * @return
     */
    @Override
    public boolean saveOrUpdate(SysDict sysDict)
    {
        if (sysDict.getId() == null)
        {
            //新增
            return sysDictMapper.insert(sysDict) == 1;
        }
        else
        {
            //修改
            return sysDictMapper.updateById(sysDict) == 1;
        }
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteById(Integer id)
    {
        return sysDictMapper.deleteById(id) == 1;
    }
}

Service的实现类中需要添加@Service注解,集成Spring时配置过自动扫描包,包名是 com.shrimpking.service.impl,SysDictServiceImpl 实现类所在的包就是符合这个包名规则的,加上注解后,Spring在初始化时就会扫描到这个类,然后由Spring管理这个类。因为配置了自动扫描Mapper接口,所以在Service 层可以直接通过以下代码注入Mapper。

其他配置文件

mybatis-servlet.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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--启用controller注解支持-->
    <mvc:annotation-driven/>
    <!-- 映射静态资源   -->
    <mvc:resources mapping="/static/**" location="classpath:static/"/>
    <!-- 包扫描   -->
    <context:component-scan base-package="com.shrimpking.controller"/>
    <!--  视图解析器  -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="cacheEnabled" value="true"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

</configuration>

 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--spring 配置文件在哪里-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>mybtis</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mybatis-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mybtis</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>springEncoding</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>springEncoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

开发控制层(Controller层)

在com.shrimpking.controller包下,新建SysDictController类,代码如下。

package com.shrimpking.controller;

import com.shrimpking.pojo.SysDict;
import com.shrimpking.service.SysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Shrimpking
 * @create 2023/6/12 16:07
 */
@Controller
@RequestMapping("/dicts")
public class SysDictController
{
    @Autowired
    private SysDictService sysDictService;

    /**
     * 查询
     * http://localhost:8089/dicts?offset=0&limit=6
     * @param sysDict
     * @param offset
     * @param limit
     * @return
     */
    @RequestMapping
    public ModelAndView dicts(SysDict sysDict,Integer offset,Integer limit)
    {
        ModelAndView modelAndView = new ModelAndView();
        List<SysDict> sysDictList = sysDictService.getList(sysDict, offset, limit);
        modelAndView.addObject("dicts",sysDictList);
        modelAndView.setViewName("dicts");
        return modelAndView;
    }

    /**
     * 跳转新增
     * @param id
     * @return
     */
    @RequestMapping(value = "/toAdd",method = RequestMethod.GET)
    public ModelAndView add(Integer id)
    {
        ModelAndView modelAndView = new ModelAndView();
        SysDict sysDict;
        if(id == null)
        {
            //如果id不存在,就是新增,创建一个空对象;
            sysDict = new SysDict();
        }
        else
        {
            //修改
            sysDict = sysDictService.getById(id);
        }
        modelAndView.addObject("model",sysDict);
        modelAndView.setViewName("dict_add");
        return modelAndView;
    }

    /**
     * 新增保存
     * @param sysDict
     * @return
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public ModelAndView save(SysDict sysDict)
    {
        ModelAndView modelAndView = new ModelAndView();
        try
        {
            sysDictService.saveOrUpdate(sysDict);
            modelAndView.setViewName("redirect:/dicts");
        }
        catch (Exception e)
        {
            modelAndView.setViewName("dict_add");
            modelAndView.addObject("msg",e.getMessage());
            modelAndView.addObject("model",sysDict);
        }
        return modelAndView;
    }

    @RequestMapping(value = "/delete",method = RequestMethod.POST)
    @ResponseBody
    public ModelMap delete(@RequestParam Integer id)
    {
        ModelMap modelMap = new ModelMap();
        try
        {
            boolean success = sysDictService.deleteById(id);
            modelMap.put("success",success);
        }
        catch (Exception e)
        {
            modelMap.put("success",false);
            modelMap.put("msg",e.getMessage());
        }

        return modelMap;
    }


}

开发视图层(View层)

按照视图配置,需要在web下面的WEB-INF中创建view目录,然后在view中创建dicts.jsp和dict_add.jsp,dicts.jsp代码如下。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <c:set var="path" value="${pageContext.request.contextPath}"/>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>字典信息</title>
    <script src="${path}/static/jQuery-3.4.1.js"></script>
</head>
<body>
<table style="border: 1px solid black;width: 50%;border-collapse: collapse;padding: 10px;text-align: center;">
    <tr>
        <th colspan="4">字典管理</th>
    </tr>
    <tr>
        <th>类别名</th>
        <th>字典名</th>
        <th>字典值</th>
        <th>操作[<a href="${path}/dicts/toAdd">新增</a>]</th>
    </tr>
    <c:forEach items="${dicts}" var="dict">
        <tr id="dict-${dict.id}">
            <td>${dict.code}</td>
            <td>${dict.name}</td>
            <td>${dict.value}</td>
            <td>
                [<a href="${path}/dicts/toAdd?id=${dict.id}">编辑</a>]
                [<a href="javascript:;" onclick="deleteById(${dict.id},'${dict.name}')">删除</a>]
            </td>
        </tr>
    </c:forEach>
</table>
<script>
    function deleteById(id, label) {
        var result = confirm('确定要删除<' + label + '>吗');
        if(result)
        {
            $.ajax({
                url:'${path}/dicts/delete',
                data:{
                    id:id
                },
                dataType:'json',
                type:'POST',
                success:function (data) {
                    if(data.success)
                    {
                        $('#dict-' + id).remove();
                    }
                    else
                    {
                        alert(data.msg);
                    }
                }
            })
        }
    }
</script>
</body>
</html>

dict_add.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <c:set var="path" value="${pageContext.request.contextPath}"/>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>字典维护</title>
</head>
<body>
<form action="${path}/dicts/add" method="post">
    <input type="hidden" name="id" value="${model.id}">
    <table>
        <c:if test="${msg != null}">
            <tr>
                <th colspan="2" style="color: red;max-width: 400px;">${msg}</th>
            </tr>
        </c:if>
        <tr>
            <th colspan="2">字典维护</th>
        </tr>
        <tr>
            <th>类别名</th>
            <td><input type="text" name="code" value="${model.code}"></td>
        </tr>
        <tr>
            <th>字典名</th>
            <td><input type="text" name="name" value="${model.name}"></td>
        </tr>
        <tr>
            <th>字典值</th>
            <td><input type="text" name="value" value="${model.value}"></td>
        </tr>
        <tr>
            <th colspan="2">
                <input type="submit" value="保存">
                <input type="button" value="取消" onclick="backToList()">
            </th>
        </tr>
    </table>
</form>
<script>
    function backToList() {
        location.href = '${path}/dicts';
    }
</script>
</body>
</html>

dicts.jsp 代码中使用了 jquery-3.4.1.js,然后放在resources/static/目录下面。

部署和运行应用

将项目部署到 Tomcat 下,然后启动服务。服务器启动完成后,在浏览器中输入http://localhost:8089/dicts 并访问,简单的字典管理操作界面便实现了,如图 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虾米大王

有你的支持,我会更有动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值