Mybatis学习笔记-1-快速入门

mybatis快速入门,参考mybatis官方文档:https://mybatis.net.cn/getting-started.html

一、快速入门

1、搭建环境,引入依赖

XML 复制代码
<!-- mybatis的依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.17</version>
      <scope>compile</scope>
    </dependency>

    <!-- 连接mysql数据库的依赖 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
      <scope>compile</scope>
    </dependency>

2、创建mybatis的核心依赖mybatis-config.xml

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>
<!--    配置连接数据库的环境-->
    <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/mybatis_study"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
<!--    引入映射文件-->
    <mappers>
        <mapper resource="mappers/BrandMapper.xml"/>
    </mappers>
</configuration>

3、创建mapper接口

java 复制代码
public interface BrandMapper {
    /**
     * mybatis面向接口编程的两个一致:
     * 1、映射文件的namespace要和mapper接口的全类名保持一致
     * 2、映射文件中sql语句的id要合mapper接口中的方法名一致
     */

    /**
     * 新增信息
     */
    int insertBrand();
}

4、创建mabatis的映射文件

java 复制代码
package com.doumi.mybatis.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Brand {
    private Integer id;
    private String brandName;
    private String companyName;
    private float price;
}

对应表的建表语句

sql 复制代码
CREATE TABLE `tb_brand` (
  `id` int NOT NULL AUTO_INCREMENT,
  `brand_name` varchar(20) DEFAULT NULL,
  `company_name` varchar(50) DEFAULT NULL,
  `price` decimal(10,0) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

5、通过junit测试功能

java 复制代码
public class MybatisTest {

    @Test
    public void testInsert() throws IOException {
        /**
         * 1、加载核心配置文件
         */
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream);
//        SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);//设置自动提交事务
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
        int i = brandMapper.insertBrand();
        System.out.println(i);

        /**
         * 默认使用jdbc的事务管理器,需要手动提交事务
         * 如果需要自动提交事务,需要openSession的时候添加一个参数
         * SqlSession sqlSession = sqlSessionFactory.openSession(true);//设置自动提交事务
         *
         */
//        sqlSession.commit();
        sqlSession.close();


    }
}

6、加入log4j日志功能

加入log4依赖及log4j.xml的配置

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns="https://logging.apache.org/xml/ns"
               xsi:schemaLocation="
                       https://logging.apache.org/xml/ns
                       https://logging.apache.org/xml/ns/log4j-config-2.xsd">

    <Appenders>

        <!-- 控制台输出 -->
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <Console name="CONSOLE">
            <JsonTemplateLayout/>
        </Console>
    </Appenders>

    <Loggers>
        <Logger name="com.doumi.mybatis" level="DEBUG" >
            <appender-ref ref="STDOUT"/>
        </Logger>
        <Logger name="org.apache.ibatis" level="DEBUG" >
            <appender-ref ref="STDOUT"/>
        </Logger>
        <Root level="DEBUG">
            <AppenderRef ref="CONSOLE"/>
            <AppenderRef ref="STDOUT"/>
        </Root>

    </Loggers>


</Configuration>

二、mybatis核心配置文件

1、核心配置文件mybatis-config.xml

其中的标签需要按照顺序写,否则会报错

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>
<!--    引入properties文件-->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
    </settings>
<!--    类型别名,可以使用别名来表示类名
    typeAlias:设置某个类型的别名
    type:设置需要设置别名的类名
    alias:设置某个类型的别名,如果不设置该属性,那么该类型拥有默认的别名,即类名且不区分大小写

-->
    <typeAliases>
        <typeAlias type="com.doumi.mybatis.pojo.Brand" alias=""></typeAlias>
    </typeAliases>
    <!--
            environments:配置多个连接数据库的环境
            environment 属性:
                id:表示连接数据库的环境的唯一标识,不能重复
            transactionManager:
                type="JDBC|MANAGED"
                    JDBC:表示当前环境,执行sql时使用的是JDBC中原生的事务管理方式,事务的提交需要手动提交
                    MANAGED:被管理,例如spring
    -->

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--
                    dataSource:配置数据源
                    属性:
                        type:设置数据源的类型
                        type="POOLED|UNPOOLED|JNDI"
                        POOLED:比哦啊是使用数据库连接池缓存数据库连接
                        UNPOOLED:表示不使用数据库连接池
                        JNDI:表示使用上下文中的数据源
            -->
            <dataSource type="POOLED">
                <!--                设置连接数据库的驱动 -->
                <property name="driver" value="${jdbc.driver}"/>
                <!--                设置连接数据库的地址 -->
                <property name="url" value="${jdbc.url}"/>
                <!--                设置连接数据库的用户名 -->
                <property name="username" value="${jdbc.username}"/>
                <!--                设置连接数据库的密码 -->
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
<!--    引入映射文件-->
    <mappers>
<!--        引入单个映射文件-->
<!--        <mapper resource="mappers/BrandMapper.xml"/>-->
<!--        以包为单位引入映射文件
            要求:
                1、mapper接口所在的包要和映射文件所在的包一致
                2、mapper接口要和映射文件的名字一致
-->
        <package name="com.doumi.mybatis.mapper"/>
    </mappers>

</configuration>

2、在idea中设置mybatis-config的模版

1、在idea的settings中,添加模版:

模版内容如下

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>
    <!--    引入properties文件-->
    <properties resource="db.properties"/>

<!--    定义类型别名-->
    <typeAliases>
        <package name=""/>
    </typeAliases>
    
<!--    环境定义-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

<!--    定义mapper信息-->
    <mappers>
        <package name=""/>
    </mappers>

</configuration>

新建一个mybatis-config.xml类型的文件,直接输入文件名,不需要输入后缀名,即可得到和模版一样的文件,只需按需要修改即可

三、mybatis获取参数值的方式

获取参数值的两种方式:

${}:本质是字符串拼接,需要手动加单引号

#{}:本质是占位符

1、mapper接口方法的参数是单个的字面量类型

可以通过{}和#{}以任意的名称,获取参数数值,但是需要注意{}需要手动加单引号

2、mapper接口方法的参数为多个时

此时mybatis会讲这些参数封装在一个map集合中,以两种方式进行存储

1》以 arg0 、rag1为键,以参数为值

2》以param0、param1为键,以参数为值

因此,只需要通过#{}和{}以键的方式访问值即可,但是需要注意{}的单引号问题

3、若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储

只需要通过#{}和{}以键的方式访问值即可,但是需要注意{}的单引号问题

4、mapper中接口方法的参数是实体类对象的时

只需要通过#{}和${}以属性名进行访问值即可

5、命名参数注解@Param("参数名")

1》以@Param注解的值( 即参数名1 、参数名2 )为键,以参数为值

2》以param0、param1为键,以参数为值

因此,只需要通过#{}和{}以键的方式访问值即可,但是需要注意{}的单引号问题

四、mybatis各种查询功能

1、查询一个实体类对象

2、查询一个list集合

3、查询单个数据

4、查询一条数据为一个map集合

5、查询多条数据为一个map集合

方式一:

方式二:

五、特殊sql的执行

1、模糊查询

2、批量删除

3、动态设置表名

4、添加功能,获取自增主键

六、自动映射

1、resultMap处理字段和属性的映射关系

解决字段名和属性名不一致的情况:

1)给字段起别名,保持和属性名一致

2)设置全局配置,将自动映射为驼峰

3)通过ResultMap设置自定义的映射关系

2、多对一映射处理

2.1 级联属性赋值

2.2 使用association

2.3 分步查询

resultMap设置:

分步查询中,关于延迟加载的说明

设置开启延迟加载:

setting中的延迟加载是全局设置。

设置延迟加载后,如果只查询第一步中的字段,则第二个sql不会被执行。

如果有特殊情况,需要把所有信息都查出来,可以在association中通过fetchType=eager进行设置,那么两个sql都将被执行,如下:

3、一对多映射

3.1 collection

3.2 分步查询

七、动态sql

1、if

2、where

3、trim

4、choose、when、otherwise

5、foreach

批量删除

写法二:

批量添加

6、sql标签

八、mybatis的缓存

1、一级缓存

SqlSession级别的,默认开启

java 复制代码
package com.doumi.mybatis;

import com.doumi.mybatis.mapper.CacheMapper;
import com.doumi.mybatis.mapper.EmpMapper;
import com.doumi.mybatis.pojo.Emp;
import com.doumi.mybatis.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;

public class CacheMapperTest {

    /**
     * 一级缓存生效
     * 测试一级缓存
     * 一级缓存是sqlSession级别的,通过同一个sqlSession查询的数据将被缓存,下次查询相同的数据,将会从缓存获取,不会重新查询数据库
     * @throws IOException
     */
    @Test
    public void TestLevelOneCache() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        System.out.println(mapper.getEmpById(1));
        sqlSession.close();
    }

    /**
     * 一级缓存生效
     * @throws IOException
     */
    @Test
    public void TestLevelOneCache2() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        CacheMapper mapper2 = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper2.getEmpById(1));
        sqlSession.close();
    }

    /**
     * -------------------以下是一级缓存失效的四种情况----------------------------------------------------------------------
     * 一级缓存失效的四种情况
     * 1、不同的sqlSession
     * 2、不同的查询条件
     * 3、两次查询中有任意增删改操作
     * 4、两次查询之间进行了手动清除缓存
     * @throws IOException
     */
    /**
     * 1、不同的sqlSession
     * @throws IOException
     */
    @Test
    public void TestLevelOneCacheFail1() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        SqlSession sqlSession2 = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        System.out.println(mapper2.getEmpById(1));
        sqlSession.close();
    }

    /**
     * 2、不同的查询条件
     * @throws IOException
     */
    @Test
    public void TestLevelOneCacheFail2() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        System.out.println(mapper.getEmpById(2));
        sqlSession.close();
    }

    /**
     * 3、两次查询中有任意增删改操作
     * @throws IOException
     */
    @Test
    public void TestLevelOneCacheFail3() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession(true);
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        mapper.insertEmp(new Emp(null, "张三", 23, "男", 2));
        System.out.println(mapper.getEmpById(1));
        sqlSession.close();
    }


    /**
     * 4、手动清除缓存
     * @throws IOException
     */
    @Test
    public void TestLevelOneCacheFail4() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession(true);
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        sqlSession.clearCache();
        System.out.println(mapper.getEmpById(1));
        sqlSession.close();
    }

}

2、二级缓存

java 复制代码
package com.doumi.mybatis;

import com.doumi.mybatis.mapper.CacheMapper;
import com.doumi.mybatis.pojo.Emp;
import com.doumi.mybatis.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;

public class CacheTwoTest {


    /**
     * 二级缓存
     * 二级缓存是sqlSessionFactory级别的,通过同一个sqlSessionFactory创建的sqlSession查询的结果会被缓存。
     * 此后若再次执行相同的查询语句,结果就会从缓存中获取
     *
     * 二级缓存开启的条件
     * 1、核心配置文件settings配置参数cacheEnabled=true,默认就是true,缓存开启
     * <setting name="cacheEnabled" value="true"/>
     * 2、mapper中添加标签<cache>
     * 3、二级缓存必须在sqlSession提交或关闭后有效
     * 4、查询的数据转换的实体类必须实现Serializable接口
     *
     * 二级缓存失效的情况:
     * 两次查询之间有增删改操作,是一二级缓存同时失效
     *
     * @throws IOException
     */
    @Test
    public void TestLevelTwoCache() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        sqlSession.close();//必须关闭第一个sqlSession结果数据才能放入二级缓存,负责不能被放入缓存
        SqlSession sqlSession2 = MybatisUtils.getSqlSessionFactory().openSession();
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        System.out.println(mapper2.getEmpById(1));
        sqlSession2.close();
    }

    /**
     * 二级缓存失效
     * 两次查询之间有增删改操作
     * @throws IOException
     */
    @Test
    public void TestLevelTwoCacheFail() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession(true);
        CacheMapper mapper = sqlSession.getMapper(CacheMapper.class);
        System.out.println(mapper.getEmpById(1));
        sqlSession.close();

        SqlSession sqlSession2 = MybatisUtils.getSqlSessionFactory().openSession(true);
        CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
        mapper2.insertEmp(new Emp(null,"二级缓存失效",23,"男",2));
        sqlSession2.close();

        SqlSession sqlSession3 = MybatisUtils.getSqlSessionFactory().openSession(true);
        CacheMapper mapper3 = sqlSession3.getMapper(CacheMapper.class);
        System.out.println(mapper3.getEmpById(1));
        sqlSession3.close();
    }

}

3、二级缓存的相关配置

4、Mybatis缓存的查询顺序

5、整合第三方缓存EHCache

1、添加依赖

2、各jar包功能

3、创建ehcache的配置文件ehcache.xml

4、设置二级缓存

5、加入logback日志

6、EHCache配置文件说明

九、MyBatis的逆向工程

1、添加maven依赖

在项目的 pom.xml 中,你需要添加 MyBatis Generator 的 Maven 插件以及数据库驱动依赖。

XML 复制代码
<build>
    <plugins>
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.4.2</version> <!-- 推荐使用较新版本 -->
            <configuration>
                <overwrite>true</overwrite> <!-- 允许覆盖已生成的文件 -->
                <verbose>true</verbose>     <!-- 打印详细日志 -->
            </configuration>
            <dependencies>
                <!-- 必须包含数据库驱动依赖,否则插件无法连接数据库 -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.33</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

2、创建逆向工程的文件generatorConfig.xml

src/main/resources 目录下创建 generatorConfig.xml。这是逆向工程的"大脑",控制着生成什么代码以及生成在哪里。

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 上下文配置 -->
    <context id="MysqlContext" targetRuntime="MyBatis3">

        <!-- 1. 注释生成器配置 -->
        <commentGenerator>
            <!-- 是否去除注释 -->
            <property name="suppressAllComments" value="false"/>
            <!-- 是否去除生成的日期 -->
            <property name="suppressDate" value="true"/>
        </commentGenerator>

        <!-- 2. 数据库连接配置 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/mybatis_study?useSSL=false&amp;serverTimezone=UTC"
                        userId="root"
                        password="root123456">
        </jdbcConnection>

        <!-- 3. 生成 Java 实体类的位置 -->
        <javaModelGenerator targetPackage="com.doumi.mybatis.pojo" targetProject="src/main/java">
            <!-- 是否在包下生成子包 -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否对字符串字段调用 trim -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- 4. 生成 Mapper XML 文件的位置 -->
        <sqlMapGenerator targetPackage="com.doumi.mybatis.mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 5. 生成 Mapper 接口的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.doumi.mybatis.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 6. 指定要生成的表 -->
        <!-- tableName: 数据库表名 -->
        <!-- domainObjectName: 生成的 Java 类名 -->
        <table tableName="emp" domainObjectName="Emp" enableCountByExample="false" enableUpdateByExample="false"/>
        <table tableName="dept" domainObjectName="Dept" enableCountByExample="false" enableUpdateByExample="false"/>
        <table tableName="tb_brand" domainObjectName="Brand" enableCountByExample="false" enableUpdateByExample="false"/>

    </context>
</generatorConfiguration>

3、执行生成命令

配置完成后,在 Maven 项目面板中找到 mybatis-generator 插件,双击运行 mybatis-generator:generate 目标。或者在命令行执行:

bash 复制代码
mvn mybatis-generator:generate

十、分页插件

1、分页插件使用步骤

1>、添加依赖

2>、配置分页插件

2、分页插件的使用

java 复制代码
package com.doumi.mybatis;

import com.doumi.mybatis.mapper.DeptMapper;
import com.doumi.mybatis.mapper.EmpMapper;
import com.doumi.mybatis.pojo.Dept;
import com.doumi.mybatis.utils.MybatisUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class PageHelperTest {

    /**
     * limit index pageSize
     * index:当前页的起始索引
     * pageSize:每页显示的条数
     * pageNum:当前页的页码
     * index = (pageNum-1)* pageSize
     *
     * 使用Mybatis的分页插件实现分页功能:
     * 1、需要在查询功能之前开启分页
     * PageHelper.startPage(int pageNum, int pageSize);
     * 2、在查询功能之后获取分页相关信息
     * PageInfo<Dept> pageInfo = new PageInfo<>(list,3);
     * list 表示分页数据
     * 3:表示当前导航分页的数量
     */
    @Test
    public void testPageHelper() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        Page<Object> page = PageHelper.startPage(1, 3);
        mapper.selectByExample(null);
        System.out.println(page);
        sqlSession.close();
    }

    /**
     * 导航栏
     * @throws IOException
     */
    @Test
    public void testPageHelperNavigator() throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSessionFactory().openSession();
        DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
        PageHelper.startPage(4, 3);
        List<Dept> list = mapper.selectByExample(null);
        PageInfo<Dept> pageInfo = new PageInfo<>(list,3);
        System.out.println(pageInfo);
        sqlSession.close();
    }
}
相关推荐
Orange_sparkle2 小时前
learn claude code学习记录-S04
学习
很小心的小新2 小时前
大模型应用开发笔记
人工智能·笔记·langchain·大模型
Xpower 172 小时前
算法学习笔记 Day 1:迁移学习与域自适应(DANN/CORAL)
笔记·学习·算法
skywalk81632 小时前
https://www.voscreen.com/ 是一个非常好的学习英语的网站,请判断和总结它是怎样实现的?如果想复刻一个该网站,需要怎么做?
学习
后季暖2 小时前
agent学习笔记4
笔记·学习
凯尔萨厮2 小时前
Spring学习笔记(基于注解)
笔记·学习·spring
某风吾起3 小时前
通过mmwave studio配置TI毫米波雷达IWR1843的StaticConfig
嵌入式硬件·学习
EnglishJun3 小时前
ARM嵌入式学习(二十二)-- 操作系统的中断处理以及ioctl
学习
南無忘码至尊3 小时前
Unity学习90天-第3天-认识触屏输入(手游基础)并完成手机点击屏幕,物体向点击位置移动
学习·unity·c#·游戏引擎·游戏开发