Mybatis学习笔记--(一)Mybatis基础

本文为how2java Mybatis教程的学习笔记,原教程链接如下:http://how2j.cn/k/mybatis/mybatis-tutorial/1087.html#nowhere

入门项目

1、创建数据库:

create database how2java

2、创建表category_

USE how2java;

CREATE TABLE category_ (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(32) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

3、导入数据

USE how2java;
INSERT INTO category_ VALUES (null,'category1');
INSERT INTO category_ VALUES (null,'category2');

4、创建工程导入jar包

创建java project:mybatis,在项目目录下新建lib文件夹,导入以下两个jar包并在项目内添加对这两个jar包的依赖。
这里写图片描述

5、创建实体类Category,用于映射表category_

package com.how2java.pojo;

public class Category {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

6、配置文件mybatis-config.xml

在src目录下创建mybatis的主配置文件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>
    <typeAliases>
      <package name="com.how2java.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="admin"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/how2java/pojo/Category.xml"/>
    </mappers>
</configuration>
  • 以下部分提供连接数据库用的驱动,数据库名称,编码方式,账号密码:
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/how2java?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
  • 通过typeAliases标签设置别名,程序自动扫描com.how2java.pojo下的类型,使得在后续配置文件Category.xml中使用resultType的时候,可以直接使用Category,而不用写全com.how2java.pojo.Category
<typeAliases>
    <package name="com.how2java.pojo"/>
</typeAliases>
  • 映射Category.xml:
<mappers>
    <mapper resource="com/how2java/pojo/Category.xml"/>
</mappers>

7、配置文件Category.xml

在包com.how2java.pojo下,新建文件Category.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.how2java.pojo">
        <select id="listCategory" resultType="Category">
            select * from   category_      
        </select>
    </mapper>

命名空间是com.how2java.pojo,在后续调用sql语句的时候,会用到它。里面定义了一条sql语句。

  • id=”listCategory”:进行标示以供后续代码调用。
  • resultType=”Category”:表示返回的数据和Category关联起来。

这里本应该使用的是 com.how2java.pojo.Category, 但是因为上一步配置了别名,所以直接使用Category就行了

8、测试

编写测试类:

package com.how2java;

public class TestMybatis {

    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new 
                            SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session=sqlSessionFactory.openSession();

        List<Category> cs=session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c.getName());
        }

    }
}
  • 根据配置文件mybatis-config.xml得到sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  • 然后再根据sqlSessionFactory 得到session
SqlSession session=sqlSessionFactory.openSession();
  • 最后通过session的selectList方法,调用sql语句listCategory。listCategory这个就是在配置文件Category.xml中那条sql语句设置的id。执行完毕之后,得到一个Category集合,遍历即可看到数据。
List<Category> cs = session.selectList("listCategory");
for (Category c : cs) {
    System.out.println(c.getName());
}

运行结果:

这里写图片描述

9、基本原理

  1. 应用程序找Mybatis要数据
  2. mbatis从数据库中找来数据
    1. 通过mybatis-config.xml 定位哪个数据库
    2. 通过Category.xml执行对应的select语句
    3. 基于Catgory.xml把返回的数据库记录封装在Category对象中
    4. 把多个Category对象装在一个Category集合中
  3. 返回一个Category集合

这里写图片描述

CRUD(增删改查)

以下测试将省略如下获取sqlSessionFactory、Session的代码:

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new   
                    SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory.openSession();

1、修改配置文件Category.xml

首先一次性修改配置文件Category.xml,提供CRUD对应的sql语句:

<?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.how2java.pojo">
        <insert id="addCategory" parameterType="Category" >
            insert into category_ ( name ) values (#{name})    
        </insert>

        <delete id="deleteCategory" parameterType="Category" >
            delete from category_ where id= #{id}   
        </delete>

        <select id="getCategory" parameterType="_int" resultType="Category">
            select * from   category_  where id= #{id}    
        </select>

        <update id="updateCategory" parameterType="Category" >
            update category_ set name=#{name} where id=#{id}    
        </update>
        <select id="listCategory" resultType="Category">
            select * from   category_      
        </select>     
    </mapper>

2、增加

增加的SQL语句:#{name}会自动获取Category对象的name属性值

<insert id="addCategory" parameterType="Category" >
    insert into category_ ( name ) values (#{name})    
</insert>

通过session.insert()调用addCategory对应的SQL语句

Category c = new Category();
c.setName("新增加的Category");
session.insert("addCategory",c)

3、删除

删除的SQL语句:

<delete id="deleteCategory" parameterType="Category" >
    delete from category_ where id= #{id}   
</delete>

通过session.delete()调用deleteCategory对应的SQL语句:

Category c = new Category();
c.setId(6);
session.delete("deleteCategory",c);

4、获取

获取单条记录

SQL语句:

<select id="getCategory" parameterType="_int" resultType="Category">
    select * from   category_  where id= #{id}    
</select>

通过session.selectOne()调用getCategory对应的SQL语句获取单条记录

Category c= session.selectOne("getCategory",3);

获取多条记录

SQL语句:

<select id="listCategory" resultType="Category">
    select * from   category_      
</select>

通过session.selectList()调用listCategory对应的SQL语句获取多条记录

List<Category> cs = session.selectList("listCategory");
模糊查询

SQL语句:其中#{0}中的0代表第一个参数,更多模糊查询的知识参考Mysql模糊查询。

<select id="listCategoryByName"  parameterType="string" resultType="Category">
    select * from   category_  where name like concat('%',#{0},'%')
</select>

测试代码:

List<Category> cs = session.selectList("listCategoryByName","cat");
多条件查询

SQL语句:

<select id="listCategoryByIdAndName" resultType="Category">
    select * from   category_  where id> #{id}  and name like concat('%',#{name},'%')
</select>

测试代码:selectList()方法又只接受一个参数对象,所以需要把多个参数放在Map里,然后把这个Map对象作为参数传递进去

 Map<String,Object> params = new HashMap<>();
 params.put("id", 3);
 params.put("name", "cat");
 List<Category> cs = session.selectList("listCategoryByIdAndName",params);

5、修改

修改的SQL语句:

<update id="updateCategory" parameterType="Category" >
    update category_ set name=#{name} where id=#{id}    
</update>

通过session.update()调用updateCategory对应的SQL语句:

session.update("updateCategory",c);

一对多

以下以一个分类Category对应多个产品Product来举例

1、新建产品表

use how2java;
create table product_(
id int NOT NULL AUTO_INCREMENT,
name varchar(30)  DEFAULT NULL,
price float  DEFAULT 0,
cid int ,
PRIMARY KEY (id)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2、准备数据

清空category_ 和 product_ 表
新增2条分类数据,id分别是1,2
新增6条产品数据,分辨关联上述2条分类数据

use how2java;
delete from category_;
INSERT INTO category_ VALUES (1,'category1');
INSERT INTO category_ VALUES (2,'category2');
delete from product_;
INSERT INTO product_ VALUES (1,'product a', 88.88, 1);
INSERT INTO product_ VALUES (2,'product b', 88.88, 1);
INSERT INTO product_ VALUES (3,'product c', 88.88, 1);
INSERT INTO product_ VALUES (4,'product x', 88.88, 2);
INSERT INTO product_ VALUES (5,'product y', 88.88, 2);
INSERT INTO product_ VALUES (6,'product z', 88.88, 2);

3、创建Product实体类

package com.how2java.pojo;

public class Product {
    private int id;
    private String name;
    private float price;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public float getPrice() {
        return price;
    }
    public void setPrice(float price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Product [id=" + id + ", name=" + name + ", price=" + price + "]";
    }

}

4、修改Category实体类

修改Category实体类,提供products的集合。

package com.how2java.pojo;

import java.util.List;

public class Category {
    private int id;
    private String name;
    List<Product> products;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<Product> getProducts() {
        return products;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }
    @Override
    public String toString() {
        return "Category [id=" + id + ", name=" + name + "]";
    }   
}

5、修改Category.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.how2java.pojo">
        <resultMap type="Category" id="categoryBean">
            <id column="cid" property="id" />
            <result column="cname" property="name" />

            <!-- 一对多的关系 -->
            <!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->
            <collection property="products" ofType="Product">
                <id column="pid" property="id" />
                <result column="pname" property="name" />
                <result column="price" property="price" />
            </collection>
        </resultMap>

        <!-- 关联查询分类和产品表 -->
        <select id="listCategory" resultMap="categoryBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
        </select>    
    </mapper>
  • 通过left join关联查询,对Category和Product表进行关联查询。
  • 与前面学习的有所区别,这里不是用的resultType, 而是通过resultMap进行字段和属性的对应,通过resultMap把数据取出来放在对应的对象属性里。
  • 使用collection 进行一对多关系关联
  • 注: Category的id 字段和Product的id字段同名,Mybatis不知道谁是谁的,所以需要通过取别名cid,pid来区分。name字段同理。

6、测试

public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new 
                            SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();

        List<Category> cs = session.selectList("listCategory");
        for (Category c : cs) {
            System.out.println(c);
            List<Product> ps = c.getProducts();
            for (Product p : ps) {
                System.out.println("\t"+p);
            }
        }

        session.commit();
        session.close();

    }

运行结果:

这里写图片描述

多对一

1、修改修改Product实体类

为Product增加category属性

public class Product {
    ...
    private Category category;

    public Category getCategory() {
        return category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
    ... 
}

2、创建Product.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.how2java.pojo">
        <resultMap type="Product" id="productBean">
            <id column="pid" property="id" />
            <result column="pname" property="name" />
            <result column="price" property="price" />

            <!-- 多对一的关系 -->
            <!-- property: 指的是属性名称, javaType:指的是属性的类型 -->
            <association property="category" javaType="Category">
                <id column="cid" property="id"/>
                <result column="cname" property="name"/>
            </association>
        </resultMap>

        <!-- 根据id查询Product, 关联将Orders查询出来 -->
        <select id="listProduct" resultMap="productBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
        </select>    
    </mapper>
  • 提供Product.xml,通过listProduct配置关联查询的sql语句。
  • 然后通过resultMap ,进行字段和属性的对应。
  • 使用association 进行多对一关系关联,指定表字段名称与对象属性名称的一一对应关系

3、在mybatis-config.xml中增加对于Product.xml的映射

...
<mappers>
    <mapper resource="com/how2java/pojo/Category.xml"/>
    <mapper resource="com/how2java/pojo/Product.xml"/>
</mappers>
...

4、测试

public static void main(String[] args) throws IOException {
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new 
                        SqlSessionFactoryBuilder().build(inputStream);
    SqlSession session = sqlSessionFactory.openSession();

    List<Product> ps = session.selectList("listProduct");
    for (Product p : ps) {
        System.out.println(p+" 对应的分类是 \t "+ p.getCategory());
    }

    session.commit();
    session.close();

}

运行结果:

这里写图片描述

多对多

这里以订单Order和产品Product为例:

  • 一张订单里 可以包含多种产品
  • 一种产品 可以出现在多张订单里

这就是多对多关系。为了维系多对多关系,必须要一个中间表。 在这里我们使用订单项(OrderItem)表来作为中间表

1、创建表order_和order_item_

create table order_ (
  id int(11) NOT NULL AUTO_INCREMENT,
  code varchar(32) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

create table order_item_(
  id int(11) NOT NULL AUTO_INCREMENT,  
  oid int , 
  pid int ,
  number int ,
  PRIMARY KEY(id)
)AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2、导入数据

之前已经有Product数据了,这里就只准备订单数据和订单项数据:

  • 插入两个订单
  • 插入6条订单项数据,建立如下关系
    • 订单1对应产品 1,2,3
    • 订单2对应产品 2,3,4
INSERT INTO order_ VALUES (1,'code000A');
INSERT INTO order_ VALUES (2,'code000B');

INSERT INTO order_item_ VALUES (null, 1, 1, 100);
INSERT INTO order_item_ VALUES (null, 1, 2, 100);
INSERT INTO order_item_ VALUES (null, 1, 3, 100);
INSERT INTO order_item_ VALUES (null, 2, 2, 100);
INSERT INTO order_item_ VALUES (null, 2, 3, 100);
INSERT INTO order_item_ VALUES (null, 2, 4, 100);

3、实体类

Order类:

package com.how2java.pojo;

import java.util.List;

public class Order {
    private int id;
    private String code;

    List<OrderItem> orderItems;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public List<OrderItem> getOrderItems() {
        return orderItems;
    }
    public void setOrderItems(List<OrderItem> orderItems) {
        this.orderItems = orderItems;
    }

}

OrderItem类:

package com.how2java.pojo;

public class OrderItem {
    private int id;
    private int number;
    private Order order;
    private Product product;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
    public Order getOrder() {
        return order;
    }
    public void setOrder(Order order) {
        this.order = order;
    }
    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }

}

4、映射文件

Order.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.how2java.pojo">
        <resultMap type="Order" id="orderBean">
            <id column="oid" property="id" />
            <result column="code" property="code" />

            <collection property="orderItems" ofType="OrderItem">
                <id column="oiid" property="id" />
                <result column="number" property="number" />
                <association property="product" javaType="Product">
                    <id column="pid" property="id"/>
                    <result column="pname" property="name"/>
                    <result column="price" property="price"/>
                </association>                
            </collection>
        </resultMap>

        <select id="listOrder" resultMap="orderBean">
            select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname' 
                from order_ o 
                left join order_item_ oi    on o.id =oi.oid 
                left join product_ p on p.id = oi.pid 
        </select>

        <select id="getOrder" resultMap="orderBean">
            select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname' 
                from order_ o 
                left join order_item_ oi on o.id =oi.oid 
                left join product_ p on p.id = oi.pid 
            where o.id = #{id} 
        </select>
    </mapper>

OrderItem.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.how2java.pojo">

        <insert id="addOrderItem" parameterType="OrderItem">
            insert into order_item_ 
                values(null,#{order.id},#{product.id},#{number})
        </insert>    
        <delete id="deleteOrderItem" parameterType="OrderItem">
            delete from order_item_ 
                where oid = #{order.id} and pid = #{product.id}
        </delete>    

    </mapper>

Product.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.how2java.pojo">
        <resultMap type="Product" id="productBean">
            <id column="pid" property="id" />
            <result column="pname" property="name" />
            <result column="price" property="price" />

            <!-- 多对一的关系 -->
            <!-- property: 指的是属性名称, javaType:指的是属性的类型 -->
            <association property="category" javaType="Category">
                <id column="cid" property="id"/>
                <result column="cname" property="name"/>
            </association>
        </resultMap>

        <!-- 根据id查询Product, 关联将Orders查询出来 -->
        <select id="listProduct" resultMap="productBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' 
                from category_ c 
                left join product_ p on c.id = p.cid
        </select>    
        <select id="getProduct" resultMap="productBean">
            select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' 
                from category_ c 
                left join product_ p on c.id = p.cid 
            where p.id = #{id}
        </select>    
    </mapper>

5、修改mybatis-config.xml

添加对于Order.xml和OrderItem的映射

...
<mappers>
    <mapper resource="com/how2java/pojo/Category.xml"/>
    <mapper resource="com/how2java/pojo/Product.xml"/>
    <mapper resource="com/how2java/pojo/Order.xml"/>
    <mapper resource="com/how2java/pojo/OrderItem.xml"/>
</mappers>
...

6、查询操作

联合order_, order_item_, product_ 三张表进行查询:

<select id="listOrder" resultMap="orderBean">
    select o.*,p.*,oi.*, o.id 'oid', p.id 'pid', oi.id 'oiid', p.name 'pname' 
        from order_ o 
        left join order_item_ oi    on o.id =oi.oid 
        left join product_ p on p.id = oi.pid 
</select>

查询结果 id和code字段放在Order对象里, 然后通过一对多的collection标签把oiid和number放在OrderItem对象里,最后通过多对一的association标签把pid,pname,price放进Product对象里。

<resultMap type="Order" id="orderBean">
    <id column="oid" property="id" />
    <result column="code" property="code" />

    <collection property="orderItems" ofType="OrderItem">
        <id column="oiid" property="id" />
        <result column="number" property="number" />
        <association property="product" javaType="Product">
            <id column="pid" property="id"/>
            <result column="pname" property="name"/>
            <result column="price" property="price"/>
        </association>              
    </collection>
</resultMap>

测试代码:

private static void listOrder(SqlSession session) {
        List<Order> os = session.selectList("listOrder");
        for (Order o : os) {
            System.out.println(o.getCode());
            List<OrderItem> ois= o.getOrderItems();
            for (OrderItem oi : ois) {
                System.out.format("\t%s\t%f\t%d%n", oi.getProduct().getName(),oi.getProduct().getPrice(),oi.getNumber());
            }
        }
    }

运行结果:

这里写图片描述

7、建立关系

所谓建立关系,就是在OrderItem插入一条记录。
让订单000A和产品z建立了关系:首先通过id分别获取Ordre对象和Product对象,然后创建一个新的OrderItem对象,接着设置Order,设置Product,设置数量,最后调用”addOrderItem” 对应的sql语句插入数据。

private static void addOrderItem(SqlSession session) {
        Order o1 = session.selectOne("getOrder",1);
        Product p6 = session.selectOne("getProduct",6);
        OrderItem oi = new OrderItem();
        oi.setProduct(p6);
        oi.setOrder(o1);
        oi.setNumber(200);

        session.insert("addOrderItem", oi);
    }

addOrderItem调用insert into 语句插入一条OrderItem记录:

<insert id="addOrderItem" parameterType="OrderItem">
    insert into order_item_ 
        values(null,#{order.id},#{product.id},#{number})
</insert> 

8、删除关系

所谓的删除关系,就是删除掉OrderItem记录。

 private static void deleteOrderItem(SqlSession session) {
        Order o1 = session.selectOne("getOrder",1);
        Product p6 = session.selectOne("getProduct",6);
        OrderItem oi = new OrderItem();
        oi.setProduct(p6);
        oi.setOrder(o1);
        session.delete("deleteOrderItem", oi);      
    }

deleteOrderItem调用delete from 语句删除一条OrderItem记录:

<delete id="deleteOrderItem" parameterType="OrderItem">
    delete from order_item_ 
        where oid = #{order.id} and pid = #{product.id}
</delete>

9、修改关系

多对多不存在修改关系的做法,就是删除旧的,然后新增一条即达到修改的效果。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值