MyBatis Mapper XML文件详解

MyBatis教程----------Mapper.xml详解 前言:我们知道,每一款框架产品在实际开发中,都是通过XML文件来培训框架的相关流程的,MyBatis也不例外,主要有两个配置文件:config.xml和Mapper.xml,当然,这两种配置文件可以自定义文件名。config.xml是全局配置文件,主要配置MyBatis的数据源(DataSource),事务管理(TransactionManager),以及打印SQL语句,开启二级缓存,设置实体类别... 阅读详情

MyBatis Mapper XML文件详解

首先需要澄清几个概念:

  • namespace 就是Mapper XML对应的Java接口名.
  • 联合查询: 也就是多表的各种join查询
  • 关联映射: 也就是嵌套映射, 用在一个POJO中包含其他POJO的情况

Mapper XML顶级配置元素

  • cache 启用本xml对应的namespace的二级缓存
  • cache-ref 共享指定namespace的二级缓存
  • resultMap (强制配置字段)进行数据库列和返回Java对象的属性之间的映射
  • sql 可被其他语句引用的可重用sql语句块(地位相当于Java中的private辅助方法或常量)
  • insert/delete/update/select 增删改查映射语句

select

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

以上语句完成的是将符合条件的所有列返回, 以key-value对的形式保存在HashMap类型的对象中.

select子句需要注意的属性有:

属性描述
id与Java接口的方法名对应
resultType如果sql语句返回结果能够对应到Java的基本类型或者集合类型, 使用此属性进行配置
resultMap当sql语句返回结果与某个Domain Object对应时, 使用此属性进行描述, 推荐同时强制设定一个顶级配置元素resultMap进行Java对象和表列之间的映射
flushCachetrue, 每次调用都会导致本地缓存和二级缓存整体清空; 默认是false, 也就是使用缓存. 通常对于增删改类语句配置此属性
useCachetrue, 指定结果使用二级缓存, select子句默认启用
timeout在抛出异常之前, 驱动程序等待数据库返回结果的秒数, 默认继承数据库驱动的配置
fetchSize尝试指定批量返回结果行数, 默认继承驱动的配置
databaseId尝试使用mybatis配置文件中与该id对应的databaseIdProvider提供的主键生成策略, 与动态sql结合, 能够达到适配不同数据库的需求, 增加可移植性

关于select子句, 有以下几点要特别强调的:

  • parameterType通常无须指定, 因为可以根据namespace对应的Java接口方法推断出来
  • 每个resultMap推荐强制在之前进行resultMap的声明, 这样当修改了数据库或Java Domain Object的时候, 这里能够快速报错, 方便问题定位.
  • select子句务必指明所有需要的列, 避免额外的数据传输. 即使是需要全部列也不要用’*’, 因为会增加数据库的解析成本(唯一允许用’*'的地方是count(*)).

insert/delete/update

部分属性与select子句是通用的, 需要额外注意的属性有:

属性描述
useGeneratedKeys(仅对insert/update生效), 告知MyBatis使用JDBC的getGeneratedKeys方法来取出数据库内部生成的自增型主键, 适用于MySQL, SQL Server等, 默认为false

以下是几个例子:

<!--使用主键生成策略获取自增长型id-->
<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

<!--结合动态SQL实现多行插入(需要数据库支持)-->
<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username, password, email, bio) values
  <foreach item="item" collection="list" separator=",">
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
  </foreach>
</insert>

<!--使用自定义的主键生成策略首先生成主键(可以根据resultType类型灵活对应主键类型), 然后执行插入操作-->
<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>

sql

一个例子:

<!--定义一段可重用sql语句(注意这里是钱字号, 代表常量, 我们这里在sql被include的时候会显式赋值, 所以不用担心sql注入的风险, 普通的井字号是接收变量, 也就相当于在statement中添加了一个问号占位符), 相当于定义了一个方法, 可以接收调用者传入的参数-->
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

<!--在其他代码中引用, alias参数被赋值为不同的实际值-->
<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

下面是一个嵌套sql方法的例子:

<sql id="sometable">
  ${prefix}Table
</sql>

<sql id="someinclude">
  from
    <include refid="${include_target}"/>
</sql>

<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

resultMap–结果映射

我们约定强制对所有的select子句都需要显式设定resultMap属性, 因为显式对结果映射进行声明, 有利于后期修改数据库(例如修改列名或增加字段等场景)能够迅速定位异常出现的原因, 对于后期维护节约的成本远远低于声明一个resultMap的成本.

一个符合上述描述标准的简单例子:

<!--显式resultMap声明-->
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<!--根据id使用显式声明的resultMap-->
<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

枚举类型映射

遵循以下法则即可:

  • 数据库中字段直接存枚举的类型名为char或者varchar即可, 例如ERROR;
  • Domain Object中相应字段类型直接用枚举类型;

这样select的时候会自动匹配的.

高级结果映射

当我们的结果映射包含嵌套实体映射的时候, 我们需要启用resultMap的子元素辅助进行嵌套实体映射.

下面我们来介绍resultMap的子元素

id & result

这两个都是用来映射一个简单结果列, 如果是数据库中的id, 那么最好还是使用id, 因为能提高性能(主要是缓存性能和联合查询join的性能).

这两个元素有以下值得关注的属性:

属性描述
property(必选)JavaBean中的属性名
column(必选)数据库中的列
jdbcType如果数据库中的列允许空值, 需要显式配置此属性, 因为列的数据类型不同, 对于空值的处理是不同的, 可用的类型如下表

支持的jdbcType:

支持的jdbcType

constructor

constructor元素的使用场景是当一个POJO的一些属性是private final的或者是private且不提供公有getter的时候, 这时候只能够通过类的构造方法进行注入, constructor元素可以关联到指定type的POJO的相同参数构造方法上, 进行构造注入.

下面是一个例子(since mybatis 3.4.3, 之前的版本参数顺序必须与构造方法参数顺序严格对应):

public class User {
   //...
   public User(@Param("id") Integer id, @Param("username") String username, @Param("age") int age) {
     //...
  }
//...
}

对应的Mapper XML片段如下:

<constructor>
   <idArg column="id" javaType="int" name="id" />
   <arg column="age" javaType="_int" name="age" />
   <arg column="username" javaType="String" name="username" />
</constructor>
assosiation–解决has one类型的关联查询

assosiation是用来做关联映射的, 如果POJO中有嵌套的POJO定义, 使用这个元素获取嵌套的结果. 注意: assosiation本身也可以作为一种resultMap.

关联映射可以使用MyBatis提供的**延迟加载(Lazy Loading)**特性, 也就是说, 如果外层POJO被查询后, 嵌套的POJO如果没有被使用, 那么与之关联的select子句不会被执行, 直到被使用的一刻才会执行.

注意: 延迟加载是为了解决著名的"N+1查询问题"而设定的, 所谓N+1查询问题, 就是说1个外层实体, 可能内嵌N个实体, 外层的一个查询实际会引发"N+1"次查询, 这对于大数据集来说效率是不可接受的, 所以不要执行对大数据集批量返回后紧接着在代码里遍历所有嵌套字段的操作, 这会使延迟加载的特性失效! 此种情况请考虑设计库表添加冗余字段.

例1: (不推荐, 请使用例3做法)一个简单的关联查询, 直接将association作为resultMap使用, 用于联合查询的结果列映射.

<association property="author" javaType="Author">
  <id property="id" column="author_id"/>
  <result property="username" column="author_username"/>
</association>

需要关注的属性有:

属性描述
property(必选)POJO中属性名
javaType(必选)POJO类名
column(必选)对应库表的列名, 或者列名集(如果是复合key的话需要这样), 会作为嵌套select查询的参数传入, 例如: column=“author_id”, column="{param1=col1,param2=col2}"
select嵌套子查询, 可以使用column中传入的参数
fetchTypelazy, 延迟加载;eager, 立即加载; 需要全局的lazyLoadingEnabled开启支持
jdbcType如果数据库中的列允许空值, 需要显式配置此属性, 因为列的数据类型不同, 对于空值的处理是不同的, 支持的类型见上表
columnPrefix如果association重用了一个resultMap的话, 可以用这个标签快速引用联合查询的别名列, 详见[1]

例2: (推荐用法)一个复杂点的例子, 使用select属性进行关联查询:

<resultMap id="blogResult" type="Blog">
  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
</resultMap>

<select id="selectBlog" resultMap="blogResult">
  SELECT * FROM BLOG WHERE ID = #{id}
</select>

<select id="selectAuthor" resultType="Author">
  SELECT * FROM AUTHOR WHERE ID = #{author_id}
</select>

例3: (推荐)一个复杂点的例子, 使用association关联一个resultMap的id进行联合查询结果列映射, 这样单独抽出来的resultMap, 可以重用.

<!--联合查询-->
<select id="selectBlog" resultMap="blogResult">
  select
    B.id            as blog_id,
    B.title         as blog_title,
    B.author_id     as blog_author_id,
    A.id            as author_id,
    A.username      as author_username,
    A.password      as author_password,
    A.email         as author_email,
    A.bio           as author_bio
  from Blog B left outer join Author A on B.author_id = A.id
  where B.id = #{id}
</select>

<!--结果映射-->
<resultMap id="blogResult" type="Blog">
  <id property="id" column="blog_id" />
  <result property="title" column="blog_title"/>
  <association property="author" resultMap="authorResult" />
</resultMap>

<!--用于描述association的结果映射-->
<resultMap id="authorResult" type="Author">
  <id property="id" column="author_id"/>
  <result property="username" column="author_username"/>
  <result property="password" column="author_password"/>
  <result property="email" column="author_email"/>
  <result property="bio" column="author_bio"/>
</resultMap>
collection–解决has many类型的关联查询

基本用法与association一致.

例1: 一个简单的例子:

// Blog这个POJO中包含这么一个post list
private List<Post> posts;
<!--某查询语句-->
<select id="selectBlog" resultMap="blogResult">
...
</select>

<!--查询语句的结果映射-->
<resultMap id="blogResult" type="domain.blog.Blog">
...
<collection property="posts" column = "id" select="selectPostsForBlog" />
...
</resultMap>

<!--嵌套select-->
<select id="selectPostsForBlog" resultType="Post">
  SELECT * FROM POST WHERE BLOG_ID = #{id}
</select>

<!--嵌套select对应的resultMap-->
<resultMap id="post" type="domain.blog.Post">
    <id property="id" column="post_id"/>
    <result property="subject" column="post_subject"/>
    <result property="body" column="post_body"/>
</resultMap>

参考链接:


手敲Mybatis(二)-Mapper的XML解析自动注册使用 上一章节实现了mapper注册器来将代理类进行注册,获取等,在测试时手动给与注册路径进行一系列操作,这章节采用自动注册方式,通过MapperFactoryBuilder进行解析xml的select标签、Sql、id、namespace等,解析完毕注册到MapperRegistry中,接下来就还是和上节一样的操作,代理对象使用及调用映射到自己需要调用的方法中 1.xml类图 1.SqlSessionFactoryBuilder 这次测试的入口,通过构建build方法调用XMLConfiBuilder 阅读详情

相关推荐

MyBatis中接口和mapper.xml文件的存放位置、以及名称相同问题,spring整合mybatis时mapper文件放哪,以及解决mapper文件放入resources下访问不到

mybatis、mapper、spring、SSM整合

zhangfuping123456789的博客 1万+

Mybatis 基本使用(xml篇)

使用到的东西 数据库及表的创建 mysql -uroot -p123 //根据自己的数据库账号登录,我的账号是root,密码是123. create database learn_java;//创建名为learn_java的数据库 use learn_java;//使用创建的数据库 //创建用户表 CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `username` varchar(32) NOT NULL COMMENT '用

shanliang 1万+

MyBatis中Mapper接口是怎么和XML文件关联起来的

目录1.前言2. `XML` 文件和 `Mapper` 接口的解析2.1. `XML` 文件的解析 1.前言 使用过 MyBatis 的,都知道它有 Mapper 接口和 Mapper.xml 文件,那么它们是如何关联起来的呢?,又是如何一起运作的呢?接下来,我们从源码级别来分析回答这个问题 2. XML 文件和 Mapper 接口的解析 2.1. XML 文件的解析 XMl 文件的解析过程太过复杂,在这里不再过多赘述,详细过程 在这里,我们先从 这里的 2.6 节点谈起,代码如下 private void

桐花思雨 1万+

Mybatis中useGeneratedKeys =true 和 keyProperty=“id“这两个参数的含义

上边的例子就是当主键id自增的时候返回这个自增的id给keyProperty指定的实体类中的id这个对应数据库主键的属性。

LP'S Blog 7638

mybatis是如何解析mapper的xml文件的

启动时会进行sessionFactory的构建, 开始解析所有mybatis的xml文件解析xml文件, 提前所有的sql对文件中的所有xml的node进行解析解析后分位两类sqlSource, 分别是DynamicSqlSource (判断sql中存在xml的node节点),如果是text节点,则解析为rawSqlSource, rawSqlSource包含staticSqlSource;以下就是静态sql,对于占位符最终后将 #{id, jdbcType=BIGINT} 解析为?

li1011612120的博客 961

Mybatis 源码解析三、Mapper接口与mapper.xml文件绑定

一、流程图介绍整体过程                      1、首先根据MapperScannerConfigurer进行包扫描,扫描Mapper接口,生成Spring特定的描述,并将其交由MapperProxyFactory管理,后期会由其生成动态代理对象。               ClassOathMapperScanner 中的doScan()方法。

无德皇叔的博客 8116

MyBatis 如何将 Mapper 接口与其 XML 映射文件关联:深入原理与实现

MyBatis 是一个简单、灵活的持久层框架,它通过 SQL 语句将 Java 对象与数据库进行映射。MyBatis 支持基于 XML 和注解的配置方式。在实际开发中,XML 映射文件与 Mapper 接口的关联是 MyBatis 的核心功能之一。通过这种关联,开发者可以在 Mapper 接口中定义方法,并在 XML 文件中编写 SQL 语句,从而实现数据操作。MyBatis 中 Mapper 接口与 XML 文件的关联过程,主要通过namespace和id来匹配。

2301_79858914的博客 6113

MyBatis Generator 生成实体,mapper和mapper.xml文件的方法

1.首先在pom.xml引入所需要的jar包依赖        &lt;dependency&gt;     &lt;groupId&gt;org.mybatis.generator&lt;/groupId&gt;     &lt;artifactId&gt;mybatis-generator-core&lt;/artifactId&gt;     &lt;version&gt;1.3.5&...

奋斗中的小白 859

【mybatis】mapper.xml映射文件

mapper.xml是一个 MyBatis 的映射文件,用于定义 SQL 语句和结果映射。它是一个 XML 文件,通常放置在项目的资源目录下。随着mybatis框架的发展,mybatis-plus工具的出现,一些基本的增删改查的sql语句不用在定义,直接调用相关方法,但是一些复杂的sql语句例如涉及到多表查询的话仍然会使用到mapper文件去定义sql语句,或者使用注解的方式代替mapper.xml文件。

m0_67930426的博客 3126

mybatis框架mapper.xml映射文件解析

主要有两个配置文件:config.xml和Mapper.xml,当然,这两种配置文件可以自定义文件名。 config.xml是全局配置文件,主要配置MyBatis的数据源(DataSource),事务管理(TransactionManager),以及打印SQL语句,开启二级缓存,设置实体类别名等功能。 Mapper.xml的作用是"半自动"的ORM框架,即SQL语句需要开发者自定义,MyBatis的关注点在POJO与SQL之间的映射关系。 首先来介绍Mapper.xml常用属性: parameterTyp

WG102753的博客 756

MyBatis中的Mapper文件配置——编写mybatis mapper.xml文件

MyBatis 是一款优秀的持久层框架,它可以使得使用 SQL 和 HQL 来操作数据库变得很简单, MyBatis 将原生的jdbc API隐藏在接口中,使开发人员更关注业务逻辑,从而方便地实现数据持久化操作。MyBatis 中最重要的组件之一就是 MyBatis 的 Mapper XML 配置文件。Mapper XML 配置文件用来描述 MyBatis 映射器接口及其对应的 SQL、SQL语句的参数类型、返回值类型等信息。

AI天才研究院 7700

深入解析 MyBatis 映射文件(Mapper XML 文件)

本文深入解析了MyBatis框架中的Mapper XML文件,详细介绍了其基本结构、常见标签和高级用法。通过学习和理解Mapper XML文件,开发者可以更加熟练地使用MyBatis框架进行数据库操作,提高开发效率和代码质量。希望本文能够帮助读者深入理解和掌握MyBatis框架中Mapper XML文件的使用方法和技巧。继续学习和实践,将MyBatis框架应用到实际项目中,发挥其强大的持久化能力和灵活性。

FireFox1997 1529

STM32CubeMX的正交编码器encoder

由于最近干活遇到需要获取正交编码的功能,所以返回来研究一下STM32CubeMX的编码器功能,之前也更新过STM32的定时器功能,但是因为之前搞平衡车的正交编码器没有搞清楚原理,就直接用了脉冲输入功能草草了事,现在也算是为之前的年轻买单了,不过看到现有的Encoder说明都比较简单,所以就当是为开发者做贡献了,我研究清楚之后来一篇博客。

ASWaterbenben的博客 1万+

MyBatis mapper.xml文件DOCTYPE 是干啥用的

案例: <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > 很多人好奇这行代码在 mapper.xml文件起到了什么作用;反正我是蛮好奇的 把http://mybatis.org/dtd/mybatis-3-map...

u010235716的博客 9893

vue 插件vue-awesome-swiper实现 三张图片,左右两边显示一半的效果的示例

希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

weixin_50450473的博客 3245

Linux环境下使用线程方式操作UART读写功能

本文介绍Linux环境下使用线程方式操作UART的方法,实现了串口打开,关闭,发送数据,接收数据功能,还编写测试代码,验证该功能。

mftang的博客 2078

idea如何新建mybatis mapper.xml文件

如题 试图点击file——>new——> XML Configure File,但是新建的文件都不是自己想要的,记得上一次直接从别处直接找来的xxxMapper.xml文件内容复制粘贴再修改的。这次又遇到了,索性记录一下正儿八经的步骤。 1. 新建一个模板 点击 File——> Settings,然后如下图: 点击 + 号,新建模板,输入易识别的名字,然后后缀是 xml,在下方框里输入mybatis-mapper.xml的通用模板内容,然后点击应用。 模板如下: <?xml ve

初心不改 1万+

图像修复黑科技:对比BM3D/DnCNN等5种去噪器在PNP框架中的实战效果

本文深度评测了BM3D、DnCNN等五款主流去噪器在即插即用(PnP)优化框架中的实战表现。通过量化指标、视觉对比及超分等泛化任务测试,揭示了深度学习模型在性能与收敛速度上的优势,并为不同应用场景提供了选型指南与工程化建议。

weixin_29065959的博客 366

Mybatis自动生成mapper、实体类及mapper xml文件

项目中用的mybatis,依据数据库表手工写java实体类、mapper接口及mapper xml文件,是一件很郁闷的乏味的事情,而且容易出错,下面记录了一下本人用工具类自动生成这些文件的过程及碰到的坑。 1. maven pom.xml 配置(只列出需要用到的2个核心依赖库) <!-- jdbc driver --> <dependency> <groupId>org.postgresql</groupId> <artifactId&...

hello_junz的专栏 7455

计算机组成原理(二)—— 数据的表示与运算

本章目录引言一、数制与编码1.1 进位计数制1.1.1 进制及转换1.1.2 真值、机器数1.2 BCD码1.3 ASCII 码1.4 校验码1.4.1 奇偶校验码1.4.2 海明码1.4.3 CRC循环冗余码二、定点数的表示和运算2.1 定点数的表示2.1.1 无符号2.1.2 有符号(原码、反码、补码、移码)2.2 定点数的运算2.2.1 移位运算2.2.2 加减运算(溢出判断)2.2.3 乘法运算2.2.4 除法运算2.3 强制类型转换2.4 数据的存储和排列三、浮点数的表示和运算3.1 浮点数的表示

S mile0804的博客 7473

单片机毕业设计-基于STM32单片机的智能镜系统-仿真设计

可通过MQ-2监测当前烟雾浓度可通过温湿度传感器监测当前温湿度可通过光照强度传感器监测光照强度可通过蜂鸣器进行烟雾报警可通过语音识别模块进行反馈播报状态可通过按键设置阈值三个继电器控制灯、加湿、风扇标签:STM32单片机、OLED112864、DHT11、BH1750、继电器、SU-03T、MQ-2、蜂鸣器题目扩展:智能家居安防、智能大棚控制系统、智能环境检测系统项目编号:ZL-32-240604-FZ。

bsdog11的博客 966

eclipse 的mybatis中mapper.xml文件标签没有提示的解决方法

1、首先我们来看看mapper.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 nam...

红桃峰峰 的博客 2405

华为OD面试手撕真题 【合并相邻且相等的元素】多语言题解

华为OD面试高频手撕真题【合并相邻且相等的元素】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 546

MyBatis-Plus中实现Mapper与多XML文件绑定的实践指南

MyBatis-Plus中实现Mapper与多XML文件绑定的实践指南 【免费下载链接】mybatis-plus mybatis 增强工具包,简化 CRUD 操作。 文档 http://baomidou.com 低代码组件库 http://aizuda.com ...

gitblog_01408的博客 870

华为OD机试 - 音乐小说内容重复识别 - 并查集(Java 双机位C卷 200分)

华为OD机试 双机位C卷题库疯狂收录中,刷题。

学Java,找哪吒 159

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mybatis热部署加载*Mapper.xml文件,手动刷新*Mapper.xml文件

由于项目已经发布到线上,要是修改一个Mapper.xml文件的话,需要重启整个服务,这个是很耗时间的,而且在一段时间内导致服务不可用,严重影响用户的体验度。所以希望可以有一个机制可以,当修改某个mapper.xml的时候,只要重新加载这个mapper.xml就好了,参考网上的一些资料和demo,加上一些自己的总结,下面的代码是通过测试的,可以供你们参考和使用。[java] view plain c...

小稣的专栏 1400

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

上一篇: Spring 缓存使用
下一篇: Spring核心技术--IoC container用法详解
congyh
博客等级 码龄15年 43粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值