IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring Boot 2.7.0 Mybatis入门 -> 正文阅读

[Java知识库]Spring Boot 2.7.0 Mybatis入门

什么是Mybatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

? 在mybatis这类框架没有出现之前,大多通过 jdbc连接数据库的方式,在java代码中拼接sql语句然后执行,具体如下:

1.加载JDBC驱动程序:

Class.forName("com.mysql.jdbc.Driver") ; 

2.创建数据库的连接:

Connection con = DriverManager.getConnection(url , username , password ) ; 

3.执行预编译语句:

Statement stmt = con.createStatement() ;
//PreparedStatement pstmt = con.prepareStatement(sql) ;
ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;

4.遍历结果集进行数据解析:

while(rs.next()){
   String name = rs.getString("name") ;
   String pass = rs.getString(1) ; 
}

mybatis框架对以上过程进行封装和优化,包括:可以配置数据源建立连接池;将java和 sql语句分离,sql语句可以写在xml配置文件中,接口定义在java中;自定义结果集和实体对象的转换。极大提高了开发人员的编码效率,提高了代码的可读性,节约数据库的性能。

本教程使用如下版本

spring boot 2.7.0

mybatis 2.1.3

druid 1.2.1

mysql 5.6

整合

创建项目

新建一个spring boot 项目。可以通过我之前的教程创建一个空项目。

Spring Boot 新手入门

编辑pom文件

在idea中新建一个maven项目后,首先需要在pom文件中引入如下依赖。

主要包含:mybatis依赖,druid依赖,mysql依赖

 <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!-- web 组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 测试 组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- jdbc 组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!-- mybatis 组件 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <!-- druid 组件 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.1</version>
        </dependency>

        <!-- mysql 组件 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.study.MainStarter</mainClass>
                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

不要忘记重新加载一下依赖,防止找不到jar包!依次点击maven,项目名称=》右键=》Reimport
在这里插入图片描述

目录结构

建立好如下图的包目录结构,具体如下:

在这里插入图片描述

建表语句

在mysql5.6 数据库中执行我们设计好的建表语句。

CREATE DATABASE /*!32312 IF NOT EXISTS*/studydb /*!40100 DEFAULT CHARACTER SET utf8 */;
USE studydb;
DROP TABLE IF EXISTS ser_company;
CREATE TABLE ser_company (
  company_id int(11) NOT NULL AUTO_INCREMENT COMMENT '公司id',
  company_name varchar(64) DEFAULT NULL COMMENT '公司名称',
  company_code varchar(4) DEFAULT NULL COMMENT '公司编号',
  company_msg text COMMENT '公司简介',
  company_crdt timestamp NULL DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (company_id)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

配置数据源及mybatis

application.properties 配置文件中增加如下配置:

#druid数据库连接池
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#数据库地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/studydb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
#数据库账号
spring.datasource.username=root
#数据库密码
spring.datasource.password=root

#清除缓存
spring.thymeleaf.cache=false
#配置mapper映射路径
mybatis.mapper-locations=classpath:mapper/*.xml
#配置实体别名包路径
mybatis.type-aliases-package=com.study.model
#日志级别
logging.level.com.study.* = debug

注意到上述配置文件中的数据库地址,账号,密码,mapper映射路径,实体别名路径,以及日志需要修改至自己有的数据库中。配置mapper映射路径会在spring boot 容器时自动扫描该路径下的文件。配置实体别名包路径可以在编写xml中的类名时不需要写实体类的包名。这里使用的是阿里巴巴druid数据库连接组件。

实体类

在com.study.model包下编写一个实体类,对应ser_company表中的实体。我们以公司对象为例,包含公司名称,公司代码,公司信息,入库时间等字段。代码如下:

package com.study.model;

import org.apache.ibatis.type.Alias;

@Alias("SerCompanyVO")
public class SerCompanyVO {

    private int companyId;
    private String companyName;
    private String companyCode;
    private String companyMsg;
    private String companyCrdt;

    public int getCompanyId() {
        return companyId;
    }

    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public String getCompanyCode() {
        return companyCode;
    }

    public void setCompanyCode(String companyCode) {
        this.companyCode = companyCode;
    }

    public String getCompanyMsg() {
        return companyMsg;
    }

    public void setCompanyMsg(String companyMsg) {
        this.companyMsg = companyMsg;
    }

    public String getCompanyCrdt() {
        return companyCrdt;
    }

    public void setCompanyCrdt(String companyCrdt) {
        this.companyCrdt = companyCrdt;
    }
}

dao

在com.study.dao包下编辑SerCompanyMapper类,映射xml中的相关接口。这里可以选择一个接口例如selectSerCompanyList进行练习。本教程中包含多个接口。除了增加修改删除查询以外。本教程包含批量插入,动态语句插入并返回主键,动态语句修改等示例接口。代码如下:

package com.study.dao;

import com.study.model.SerCompanyVO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface SerCompanyMapper {

    /**
     * 查询全部数据
     * @return
     */
    List<SerCompanyVO> selectSerCompanyList();

    /**
     * 根据id查询信息
     * @return
     */
    SerCompanyVO  selectSerCompanyById(Integer companyId);

    /**
     * 固定字段插入
     * @param serCompanyVO
     * @return
     */
    int insertSerCompanyVO(SerCompanyVO serCompanyVO);

    /**
     * 动态语句插入
     * @param serCompanyVO
     * @return
     */
    int insertSerCompanyDynamic(SerCompanyVO serCompanyVO);

    /**
     * 批量插入
     * @param list
     * @return
     */
    int insertCompanyBatch(List<SerCompanyVO> list);

    /**
     * 修改信息
     * @param serCompanyVO
     * @return
     */
    int updateCompany(SerCompanyVO serCompanyVO);

    /**
     * 动态语句修改
     * @param serCompanyVO
     * @return
     */
    int updateCompanyDynamic(SerCompanyVO serCompanyVO);

    /**
     * 根据id删除信息
     * @param companyId
     * @return
     */
    int deleteCompanyById(Integer companyId);
}

xml

在mapper目录下,新建SerCompanyMapper.xml并编写如下代码:

namespace 为 dao层接口类的路径。

resultMap对查询的结果集进行封装为SerCompanyVO对象。

foreach标签可以对list参数进行遍历。

useGeneratedKeys、keyProperty在插入后可以返回主键。

<?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.study.dao.SerCompanyMapper">

    <resultMap id="resultMap" type="SerCompanyVO">
        <id column="company_id" property="companyId" jdbcType="INTEGER" />
        <result column="company_name" property="companyName" jdbcType="VARCHAR" />
        <result column="company_code" property="companyCode" jdbcType="VARCHAR" />
        <result column="company_msg" property="companyMsg" jdbcType="VARCHAR" />
        <result column="company_crdt" property="companyCrdt" jdbcType="VARCHAR" />
    </resultMap>

    <!-- 新增数据 固定语句 -->
    <insert id="insertSerCompanyVO" useGeneratedKeys="true" keyProperty="companyId">
        insert into ser_company(
            company_name,
            company_code,
            company_msg,
            company_crdt
        ) values (
            #{companyName, jdbcType=VARCHAR},
            #{companyCode, jdbcType=VARCHAR},
            #{companyMsg, jdbcType=VARCHAR},
            #{companyCrdt, jdbcType=TIMESTAMP}
        )
    </insert>

    <!-- 新增数据 动态语句 -->
    <insert id="insertSerCompanyDynamic" useGeneratedKeys="true" keyProperty="companyId">
        insert into ser_company(
            <if test="null != companyName and ''!= companyName">
                company_name,
            </if>
            <if test="null != companyCode and ''!= companyCode">
                company_code,
            </if>
            <if test="null != companyMsg and ''!= companyMsg">
                company_msg,
            </if>
            <if test="null != companyCrdt and ''!= companyCrdt">
                company_crdt
            </if>
        ) values (
            <if test="null != companyName and ''!= companyName">
                #{companyName, jdbcType=VARCHAR},
            </if>
            <if test="null != companyCode and ''!= companyCode">
                #{companyCode, jdbcType=VARCHAR},
            </if>
            <if test="null != companyMsg and ''!= companyMsg">
                #{companyMsg, jdbcType=VARCHAR},
            </if>
            <if test="null != companyCrdt and ''!= companyCrdt">
                #{companyCrdt, jdbcType=TIMESTAMP}
            </if>
        )
    </insert>

    <!-- 新增数据 批量插入 -->
    <insert id="insertCompanyBatch">
        insert into ser_company(
            company_name,
            company_code,
            company_msg,
            company_crdt
        ) values
        <foreach collection="list" item="item" separator=",">
            (
                #{item.companyName, jdbcType=VARCHAR},
                #{item.companyCode, jdbcType=VARCHAR},
                #{item.companyMsg, jdbcType=VARCHAR},
                #{item.companyCrdt, jdbcType=TIMESTAMP}
            )
        </foreach>
    </insert>

    <update id="updateCompanyDynamic" >
        update ser_company set
        <if test="null != companyName and ''!= companyName">
            company_name = #{companyName, jdbcType=VARCHAR},
        </if>
        <if test="null != companyCode and ''!= companyCode">
            company_code = #{companyCode, jdbcType=VARCHAR},
        </if>
        <if test="null != companyMsg and ''!= companyMsg">
            company_msg = #{companyMsg, jdbcType=VARCHAR},
        </if>
        <if test="null != companyCrdt and ''!= companyCrdt">
            company_crdt =  #{companyCrdt, jdbcType=TIMESTAMP}
        </if>
        where company_id = #{companyId, jdbcType=INTEGER}
    </update>

    <update id="updateCompany">
        update ser_company set
        company_name = #{companyName, jdbcType=VARCHAR},
        company_code = #{companyCode, jdbcType=VARCHAR},
        company_msg = #{companyMsg, jdbcType=VARCHAR},
        company_crdt = #{companyCrdt, jdbcType=TIMESTAMP}
        where company_id = #{companyId, jdbcType=INTEGER}
    </update>

    <!-- 删除数据 -->
    <delete id="deleteCompanyById">
        delete from ser_company where company_id = #{companyId, jdbcType=INTEGER}
    </delete>

    <!-- 查询数据 -->
    <select id="selectSerCompanyList" resultMap="resultMap">
        select company_name, company_code, company_msg, company_crdt from ser_company
    </select>

    <!-- 详情查询 -->
    <select id="selectSerCompanyById" resultMap="resultMap" parameterType="java.lang.Integer">
        select company_id,company_name, company_code, company_msg, company_crdt from ser_company where company_id=#{companyId, jdbcType=INTEGER}
    </select>
</mapper>

service及实现类

在com.study.service包下 新建 SerCompanyService接口,代码如下:

package com.study.service;

import com.study.model.SerCompanyVO;

import java.util.List;

public interface SerCompanyService {

    List<SerCompanyVO> querySerCompanyList();

    int addCompany(SerCompanyVO serCompanyVO);

    int addCompanyDynamic(SerCompanyVO serCompanyVO);

    int addCompanyBatch(List<SerCompanyVO> list);

    SerCompanyVO querySerCompanyById(Integer companyId);

    int updateCompany(SerCompanyVO serCompanyVO);

    int updateCompanyDynamic(SerCompanyVO serCompanyVO);

    int deleteCompanyById(Integer companyId);
}

在com.study.service.impl包下新建SerCompanyServiceImpl实现类,代码如下:

这里使用了我们刚刚写好的SerCompanyMapper。通过该类进行mybatis xml中语句的调用。

package com.study.service.impl;

import com.study.dao.SerCompanyMapper;
import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SerCompanyServiceImpl implements SerCompanyService {

    private Logger log = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private SerCompanyMapper serCompanyMapper;

    @Override
    public List<SerCompanyVO> querySerCompanyList() {
        return serCompanyMapper.selectSerCompanyList();
    }

    @Override
    public int addCompany(SerCompanyVO serCompanyVO) {
        return serCompanyMapper.insertSerCompanyVO(serCompanyVO);
    }

    @Override
    public int addCompanyDynamic(SerCompanyVO serCompanyVO) {
        return serCompanyMapper.insertSerCompanyDynamic(serCompanyVO);
    }

    @Override
    public int addCompanyBatch(List<SerCompanyVO> list) {
        return serCompanyMapper.insertCompanyBatch(list);
    }

    @Override
    public SerCompanyVO querySerCompanyById(Integer companyId) {
        return serCompanyMapper.selectSerCompanyById(companyId);
    }

    @Override
    public int updateCompany(SerCompanyVO serCompanyVO) {
        return serCompanyMapper.updateCompany(serCompanyVO);
    }

    @Override
    public int updateCompanyDynamic(SerCompanyVO serCompanyVO) {
        return serCompanyMapper.updateCompanyDynamic(serCompanyVO);
    }

    @Override
    public int deleteCompanyById(Integer companyId) {
        return serCompanyMapper.deleteCompanyById(companyId);
    }
}

controller

在com.study.controller中新建如下类:

package com.study.controller;

import com.study.model.SerCompanyVO;
import com.study.service.SerCompanyService;
import com.study.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
public class SerCompanyController {

    private Logger log = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private SerCompanyService serCompanyService;

    /**
     * 查询公司信息列表
     * http://localhost:8080/querySerCompanyList
     * @return
     */
    @RequestMapping(method= RequestMethod.GET, value = "querySerCompanyList")
    @ResponseBody
    public List<SerCompanyVO> querySerCompanyList(){
        if(log.isDebugEnabled()){
            log.debug("do querySerCompanyList begin.");
        }
        return serCompanyService.querySerCompanyList();
    }

    /**
     * 查询公司信息根据id
     * http://localhost:8080/querySerCompanyById?companyId=1
     * @return
     */
    @RequestMapping(method= RequestMethod.GET, value = "querySerCompanyById")
    @ResponseBody
    public SerCompanyVO querySerCompanyById(Integer companyId){
        return serCompanyService.querySerCompanyById(companyId);
    }

    /**
     * 新增公司固定字段
     * @param serCompanyVO
     * http://localhost:8080/addCompany?companyName=百度&companyCode=321&companyMsg=百度是一家上市公司
     * @return
     */
    @RequestMapping(method= RequestMethod.GET, value = "addCompany")
    @ResponseBody
    public Map<String, Object> addCompany(SerCompanyVO serCompanyVO){
        if(log.isDebugEnabled()){
            log.debug("companyName:{}", serCompanyVO.getCompanyName());
        }
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        serCompanyVO.setCompanyCrdt(timestamp.toString());
        int num = serCompanyService.addCompany(serCompanyVO);
        Map<String ,Object> map =  ResultUtil.getRsMap(num);
        map.put("serCompanyVO", serCompanyVO);
        return map;
    }

    /**
     * 新增公司动态字段
     * http://localhost:8080/addCompanyDynamic?companyName=字节跳动&companyCode=&companyMsg=
     * @param serCompanyVO
     * @return
     */
    @RequestMapping(method= RequestMethod.GET, value = "addCompanyDynamic")
    @ResponseBody
    public Map<String, Object> addCompanyDynamic(SerCompanyVO serCompanyVO){
        if (log.isDebugEnabled()){
            log.debug("companyName:{}", serCompanyVO.getCompanyName());
        }
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        serCompanyVO.setCompanyCrdt(timestamp.toString());
        int num = serCompanyService.addCompanyDynamic(serCompanyVO);
        Map<String ,Object> map =  ResultUtil.getRsMap(num);
        map.put("serCompanyVO", serCompanyVO);
        return map;
    }

    /**
     * 批量新增公司
     * http://localhost:8080/addCompanyBatch
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "addCompanyBatch")
    @ResponseBody
    public Map<String, Object> addCompanyBatch(){
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String timeStr = timestamp.toString();
        SerCompanyVO serCompanyVO = new SerCompanyVO();
        serCompanyVO.setCompanyName("导入1");
        serCompanyVO.setCompanyCode("3301");
        serCompanyVO.setCompanyCrdt(timeStr);
        SerCompanyVO serCompanyVO1 = new SerCompanyVO();
        serCompanyVO1.setCompanyName("导入2");
        serCompanyVO1.setCompanyCode("3302");
        serCompanyVO1.setCompanyCrdt(timeStr);
        List<SerCompanyVO> list = new ArrayList<>();
        list.add(serCompanyVO);
        list.add(serCompanyVO1);
        int num = serCompanyService.addCompanyBatch(list);
        return ResultUtil.getRsMap(num);
    }

    /**
     * 修改公司信息 固定语句
     * http://localhost:8080/updateCompany?companyId=13&companyName=百度2&companyCode=333&companyMsg=百度2是一家上市公司
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "updateCompany")
    @ResponseBody
    public Map<String, Object> updateCompany(SerCompanyVO serCompanyVO){
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String timeStr = timestamp.toString();
        serCompanyVO.setCompanyCrdt(timeStr);
        int num = serCompanyService.updateCompany(serCompanyVO);
        return  ResultUtil.getRsMap(num);
    }

    /**
     * 修改公司信息 动态语句
     * http://localhost:8080/updateCompanyDynamic?companyId=13&companyName=百度3&companyCode=333
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "updateCompanyDynamic")
    @ResponseBody
    public Map<String, Object> updateCompanyDynamic(SerCompanyVO serCompanyVO){
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String timeStr = timestamp.toString();
        serCompanyVO.setCompanyCrdt(timeStr);
        int num = serCompanyService.updateCompanyDynamic(serCompanyVO);
        return  ResultUtil.getRsMap(num);
    }

    /**
     * 删除公司信息
     * http://localhost:8080/deleteCompanyById?companyId=15
     * @param companyId
     * @return
     */
    @RequestMapping(method = RequestMethod.GET, value = "deleteCompanyById")
    @ResponseBody
    public Map<String, Object> deleteCompanyById(Integer companyId){
        int num = serCompanyService.deleteCompanyById(companyId);
        return  ResultUtil.getRsMap(num);
    }
}

启动类

在com.study 中编写MainStarter类,用于spring boot启动,代码如下:

package com.study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainStarter {

    public static void main(String[] args) {
        SpringApplication.run(MainStarter.class, args);
    }

}

测试

右键运行MainStarter类。观察控制台输出如下,观察项目正常启动:

在这里插入图片描述

打开浏览器,输入如下地址进行接口测试,选择一个查询数据的接口:

http://localhost:8080/querySerCompanyList

结果如下

在这里插入图片描述

其他的接口地址都在controller类中可以找到,依次测试即可。

好了,spring boot整合 mybatis基本完成。

写在最后

开源是一种美德,尽早加入开源社区,共建美好生态!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:47:16  更:2022-06-26 16:48:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 16:31:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码