MyBatis配置及单表操作

news2024/11/25 11:04:11

文章目录

  • 一. MyBatis概述
  • 二. MyBatis项目的创建
    • 1. 准备一个数据表
    • 2. 创建项目
  • 三. MyBatis的使用
    • 1. 基本使用
    • 2. SpringBoot单元测试
  • 四. 使用MyBatis实现单表操作
    • 1. 查询
    • 2. 修改
    • 3. 删除
    • 4. 新增
  • 五. 基于注解完成SQL

一. MyBatis概述

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL存储过程以及高级映射;MyBatis 去除了几乎所有的 JDBC 代码和动设置参数以及获取结果集的工作;MyBatis可以使用简单的 XML 或注解来配置和映射原始类型,将接口和 Java 的 POJO(Plain Old Java Objects,普通老式的 Java 对象)映射成数据库中的记录。

简单来说 MyBatis 其实就是对JDBC进行了封装,它是更简单的完成程序和数据库交互的⼯具,也就是更简单的操作和读取数据库工具。

所以我们使用 MyBatis 的时候需要创建 Mapper(Dao)层接口以及对应的xml文件,也可以使用注解代替xml文件进行写 SQL 的方式,但是 SQL 语句复杂的时候使用注解这种方式不太好实现且不太美观

MyBatis 在整个框架中的定位交互如下图:

img

MyBatis 也是⼀个 ORM 框架,ORM(Object Relational Mapping),即对象关系映射;在面向
对象编程语⾔中,将关系型数据库中的数据与对象建立起映射关系,进而自动的完成数据与对象
的互相转换:

  1. 将输⼊数据(即传入对象)+ SQL 映射成原⽣ SQL
  2. 将结果集映射为返回对象,即输出对象

ORM 把数据库映射为对象:

  • 数据库表(table)–> 类(class)
  • 记录(record,行数据)–> 对象(object)
  • 字段(field) --> 对象的属性(attribute)

⼀般的 ORM 框架,会将数据库模型的每张表都映射为⼀个 Java 类,也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表,可以实现对象和数据库表之间的转换。

二. MyBatis项目的创建

1. 准备一个数据表

这里创建以下数据库和数据表。

-- 创建数据库
drop database if exists mycnblog2023;
create database mycnblog2023 DEFAULT CHARACTER SET utf8mb4;

-- 使用数据数据
use mycnblog2023;

-- 创建表[用户表]
drop table if exists  userinfo;
create table userinfo(
    id int primary key auto_increment,
    username varchar(100) not null,
    password varchar(32) not null,
    photo varchar(500) default '',
    createtime timestamp default current_timestamp,
    updatetime timestamp default current_timestamp,
    `state` int default 1
) default charset 'utf8mb4';

-- 创建文章表
drop table if exists  articleinfo;
create table articleinfo(
    id int primary key auto_increment,
    title varchar(100) not null,
    content text not null,
    createtime timestamp default current_timestamp,
    updatetime timestamp default current_timestamp,
    uid int not null,
    rcount int not null default 1,
    `state` int default 1
)default charset 'utf8mb4';

-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
  	vid int primary key,
  	`title` varchar(250),
  	`url` varchar(1000),
		createtime timestamp default current_timestamp,
		updatetime timestamp default current_timestamp,
  	uid int
)default charset 'utf8mb4';

-- 添加一个用户信息
INSERT INTO `mycnblog2023`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES 
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);

-- 文章添加测试数据
insert into articleinfo(title,content,uid)
    values('Java','Java正文',1);
    
-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);

下面的内容主要是对userinfo表进行操作演示,目前执行上述 sql 后,表内的数据如下:
img

所以我们针对我们要操作的数据表,还应该有对应的映射类(userinfo 表对应一个 UserInfo 类)。

package com.example.demo.model;

import lombok.Data;

import java.time.LocalDateTime;

@Data
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDateTime createtime;
    private LocalDateTime updatetime;
    private int state;
}

2. 创建项目

1️⃣第一步,创建 SpringBoot 项目。
img

2️⃣第二步,勾选上 MyBatis 相关依赖,包括Mybatis Framework(一定不能少)和MySQL Driver(看你使用的是哪个数据库就添加哪个)。

img
3️⃣第三步,项目创建好后此时如果我们直接启动项目是会报错的,我们还需要在application配置文件中配置数据库数据源和 MyBatis xml文件保存路径,其中这个xml文件是用来编写sql语句用的。

🍂先配置数据库链接信息,需要配置数据库的 url,账号与密码以及驱动。

.properties文件格式:

# 设置数据库的相关连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mycnblog2023?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=111111
# 版本8之前版本的数据库使用 com.mysql.jdbc.Driver
# 版本8以及之后版本的数据库使用 com.mysql.cj.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

.yml文件格式:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mycnblog?characterEncoding=utf8
    username: root
    password: 111111
    driver-class-name: com.mysql.cj.jdbc.Driver

🍂接下来设置 MyBatis xml 文件的路径:

.properties文件格式:

# 设置 MyBatis XML 存放路径和命名格式
mybatis.mapper-locations=classpath:mybatis/*Mapper.xml

.yml文件格式:

mybatis:
  mapper-locations: classpath:mybatis/*Mapper.xml

其中*Mapper.xml表示只认Mapper.xml结尾的文件,存放在资源文件(resources)的mybatis路径下。

🍂如果需要更方便观察有关 sql 的运行情况,还可以配置一些日志文件,来显示 sql 相关的日志(debug级别,默认是不显示的):

.properties文件格式:

# 配置 MyBatis 执行时打印 SQL(可选配置)
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug

.yml文件格式:

logging:
  level:
    com:
      example:
        demo: debug
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

这样我们的项目就创建好了,下面的内容介绍 MyBatis 的基本使用。

三. MyBatis的使用

1. 基本使用

MyBatis 的基本使用流程:

  1. 创建一个使用注解@Mapper修饰的接口(用来给 Service 层调用),该注解来自 MyBatis,作用是与我们配置的Mapper.xml结尾的文件做连接。
  2. 在该接口里面定义方法。
  3. 在 xml 文件中按照 MyBatis 的规则编写 sql(接口的具体实现),xml 文件的作用是生成数据库可执行的 sql,并且能将结果映射到程序的对象中。

1️⃣第一步,我们定义接口,该接口在软件分层中属于数据持久层,所以我们定义在自建的dao包下(也可定义为 mapper),为了提高代码的可读性和规范性,接口名称建议Mapper结尾。

@Mapper
public interface UserMapper {
	//方法声明
}

2️⃣第二步,我们在该接口下声明方法,由于该方法的目的就是为了被xml文件“实现”,然后去操作数据库的,比如我们需要所有查询User对象的结果,我们声明一个getAll方法。

// 查询全部用户信息
List<UserInfo> getAll();

3️⃣第三步,在配置文件所规定的目录下创建UserMapper.xml文件,并加上下面的代码,一般一个 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.example.demo.mapper.UserMapper">

</mapper>

当我们要编写 sql 时,需要在<mapper>标签里面写对应的标签来实现对数据库的操作,比如查询使用select标签,插入使用insert标签,更新使用pudate标签,删除使用delete标签等。

而在mapper标签中,我们需要设置该mapper标签对应的接口在哪里,就是在mapper标签头中设置namespace属性,值为加包名的Mapper接口,如:

<mapper namespace="com.example.demo.mapper.UserMapper">
</mapper>

比如要查询全部用户信息,其中标签头的id属性与要实现的方法名对应,resultType表示需要映射的类是哪一个,需要写出完整的包名,这样就会将查询的结果存入到该类的对象中对对象数组中,有一点是需要注意的,那就是使用resultType映射对象一定得保证数据库中的字段名与对象中的属性名一模一样,否则不能匹配赋值。

<select id="getAll" resultType="com.example.demo.model.UserInfo">
    select * from userinfo
</select>

2. SpringBoot单元测试

完成上面的工作后我们可以使用单元测试验证我们写的代码是否符合预期。

1️⃣第一步,我们在类中代码右键,选择Generate选项,比如我们在 Mapper 接口中生成单元测试的类,我们就在右键选择Generate选项。
img
然后会跳出一个框,选择 Test。
img

2️⃣第二步,进行配置 Test,和选择需要测试的方法。
img

3️⃣第三步,第二步勾选上需要测试的方法后,会在 test 目录下生成一个同级的目录,会自动生成测试类和测试方法,当然我们也能够手动创建,创建的测试类就在原来类名最后加上一个Test即可。

单元测试的类创建在如图目录下:
img

再完成以下步骤:

  • 配置单元测试的类,在类上加上@SpringBootTest注解,这个一定不要忘记,它的作用是告诉当前的测试程序,当前的项目是运行在 SpringBoot 容器中。
  • 添加测试方法,并加上@Test注解
  • 通过注入 Mapper 对象,调用里面操作数据库的方法,进行单元测试。
    img
  • 执行单元测试,测试通过结果如下:
    img

四. 使用MyBatis实现单表操作

上面已经创建好了 Mapper 接口和对应的 xml 文件了,此时我们就可以开始写数据库 sql 的语句了,先介绍基础使用,完成对单表的 CRUD 操作。

1. 查询

1️⃣第一步,在 Mapper 接口中声明一个方法,比如通过用户id查询用户信息,就可以声明一个方法getUserById

UserInfo getUserById(@Param(value = "id") Integer id);

@Param注解中的value参数值表示对变量重命名,此时传入到 xml 文件中的变量名字就是设置的这个值,建议该名字与数据库中的字段相对应并同名。

2️⃣第二步,设置 xml 文件所映射的 Mapper 接口,假设我们映射了一个如下图dao包中的UserMapper接口,该接口一定要使用@Mapper修饰,否则就不是属于 MyBatis 中的“接口”,不能与 xml 产生映射。

img
我们将mapper标签中的namespace设置为对应接口在项目目录下的带包全称。

<mapper namespace="com.example.demo.mapper.UserMapper">

3️⃣第三步,设置查询标签以及配置与方法的映射,查询操作使用select标签,查询标签至少设置两个属性,第一个是id表示与哪一个方法相对应,就是设置成相关联的方法的方法名,比如我们在 Mapper 接口中的查询方法是getUserById,则设置id="getUserById"

然后设置resultType属性的值,我们查询需要返回查询结果UserInfo对象,如果可能有多个结果,对应的方法返回值就写List<UserInfo>,否则写UserInfo即可,resultType属性中只需要设置成带包名的类名即可。

<select id="getUserById" resultType="com.example.demo.model.UserInfo">

4️⃣第四步,在 mapper 标签中编写查询 sql,查询 sql 对应的标签就是select标签,如我们要查询id1的用户,那么标签里写的内容如下:

<select id="getUserById" resultType="com.example.demo.model.UserInfo">
    select * from userinfo where id=1
</select>

但是这样写太 sql 就写死了,代码没有通用性,我们可以使用预处理符#{}或者替换符${}来将程序传入的参数替换到 sql 语句中:

<select id="getUserById" resultType="com.example.demo.model.UserInfo">
    select * from userinfo where id=${id}
    //or select * from userinfo where id=#{id}
</select>

其中id=${id}相当于id=传入的id变量的值,比如id=1,则${id}会被替换为1,使用该方法存在 SQL 注入的问题,并且传入字符串等其他非数值类型可能会出现问题,而id=#{id}相当于id=?,相当于替换成一个占位符,然后会将传入的id通过占位符的形式插入到 sql 语句中,可以防止 SQL 注入问题,并且适用于所有类型的变量,关于这两者更多的介绍会在下一篇多表查询中介绍。

经过以上步骤我们的 sql 就写好了,由于我们的id是唯一的,所以查询到的结果也是唯一的,我们以id=1进行查询演示,目前数据库的数据如下:
img
🎯然后我们再写单元测试代码进行验证:

@Test
void getUserById() {
    UserInfo userinfo = userMapper.getUserById(1);
    System.out.println(userinfo.toString());
}

结果如下:

img

2. 修改

我们在 userinfo 表中再插入一条记录,此时表中数据如下:
img
现在我们演示如何使用 MyBatis 根据id修改对应用户名username,其实和查询操作也差不多,默认返回受影响的行数,是基础类型,此时我们是不用设置resultType的。

1️⃣第一步,声明方法:

// 根据 id 修改用户名
Integer updateName(@Param(value = "id") Integer id, @Param(value = "username") String username);

2️⃣第二步,在 xml 中写 sql,修改操作使用update标签。

<update id="updateName" >
    update userinfo set username=#{username} where id=#{id}
</update>

我们将id=2的用户名修改为张三,生成单元测试:

@Test
void updateName() {
    int result = userMapper.updateName(2, "张三");
    System.out.println("受影响行数: " + result);
}

结果如下:
img

再来验证一下数据库中的数据是否完成了修改,

img

结果是符合我们的预期的,实际上单元测试是不应该去影响数据库中的数据的,我们可以在单元测试方法上使用@Transactional注解,这样就可以防止污染数据库,实现原理是利用了数据库事务的回滚,比如:

img

执行单元测试:

img

此时数据库是没有发生修改的,原因是@Transactional注解进行了事务的回滚,但是自增主键不会进行回滚,比如你进行了id3用户插入操作,事务回滚了,下一次插入自增主键id的值为4
img
这也是使用单元测试不会污染数据库的原因所在。

3. 删除

删除其实和查询,修改也是一样的,我们来演示将id2的数据删除。
1️⃣第一步,声明方法:

// 根据id删除用户
public Integer delById(@Param(value = "id") Integer id);

2️⃣第二步,在 xml 文件编写 sql,删除操作使用delete标签:

<delete id="delById">
    delete from userinfo where id=#{id}
</delete>

3️⃣第三步,编写单元测试验证:

@Test
    void delById() {
        int result = userMapper.delById(2);
        System.out.println("受影响行数: " + result);
    }

4️⃣第四步,查询单元测试结果,验证数据库:
imgimg

4. 新增

该操作相比于之前的查询,修改和删除操作要复杂一点,但其实也差不多,为了提高代码的通用性,我们声明方法中的形参传入一个UserInfo对象。

首先,我们来演示插入一条数据,返回一个受影响的行数。

1️⃣第一步,声明方法:

// 添加用户,返回影响行数
Integer add(UserInfo userInfo);

2️⃣第二步,编写 sql 语句,插入操作使用insert标签。

<insert id="add">
    insert into userinfo(username, password, photo) values (#{username}, #{password},#{photo});
</insert>

3️⃣第三步,编写并执行单元测试,验证数据库。

@Test
void add() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("老六");
    userInfo.setPassword("666");
    int result = userMapper.add(userInfo);
    System.out.println("受影响行数: " + result);
}

单元测试结果:
img
数据库查询结果:

img
🎯其实,Mybatis 也可以返回多个参数,比如返回受影响的行数和自增id的值,这个时候我们就需要对xmlinsert标签进行配置。

前面声明方法还是需要的:

Integer addGetId(UserInfo userInfo);

xml 的insert标签中还需要设置useGeneratedKeys="true"表示为是否自增主键,keyProperty="id"表示自增主键是哪一个字段。

<insert id="addGetId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    insert into userinfo(username, password, photo) values (#{username}, #{password},#{photo});
</insert>

单元测试方法:

@Test
void addGetId() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("老八");
    userInfo.setPassword("888");
    userInfo.setPhoto("default.png");
    System.out.println("插入之前的id=" + userInfo.getId());
    int result = userMapper.addGetId(userInfo);
    System.out.println("插入之后的id=" + userInfo.getId());
    System.out.println("受影响行数: " + result);
}

单元测试结果:
img

数据库查询结果:
img

五. 基于注解完成SQL

这个其实很简单,使用配置文件我们需要在指定路径创建配置文件,实现具体接口的执行 sql;而使用注解实现 sql,直接在对应接口上面加上对应操作的注解,括号里面的属性填好 sql 属性即可。

对应操作注解也就对应 SQL 的增删查改,分别为:

  • @Select,查询
  • @Update,更新/修改
  • @Delete,删除
  • @Insert,插入/新增

我们来简单针对数据表演示一个查询操作,

1️⃣第一步,声明一个方法getAllUser()

// 基于注解查询全部用户
List<UserInfo> getAllUser();

2️⃣第二步,使用@Select实现具体的 sql 操作。

img

🎯单元测试代码:

@Test
void updateName() {
    int result = userMapper.updateName(2, "张三");
    System.out.println("受影响行数: " + result);
}

结果如下:

img
其他注解使用起来也是一样的,就不在这里赘述了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/980558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习 -- datetime模块

当涉及到处理日期和时间数据时&#xff0c;Python的datetime模块提供了一系列类来帮助您执行各种操作。以下是各个类及其常用方法的详细介绍&#xff1a; date 类​ date 类表示一个年、月、日的日期对象。以下是一些常用的 date 类方法&#xff1a; date.today() 获取当前…

rtmp推流异常分析

问题描述 向srs媒体服务上推送rtmp流&#xff0c;推送失败 分析过程 srs日志分析 从日志中看到发生错误时层次调用关系 [2023-09-05 11:10:29.933][Error][13594][9w5og10q][11] serve error code3001 : service cycle : rtmp: stream service : rtmp: receive thread : ha…

Spring系列文章3:基于注解方式依赖注入

和XML 配置文件一样&#xff0c;注解本身并不能执行&#xff0c;注解本身仅仅只是做一个标记&#xff0c;具体的功能是框架检测 到注解标记的位置&#xff0c;然后针对这个位置按照注解标记的功能来执行具体操作&#xff0c;本质上所有操作都是Java代码来完成的&#xff0c;XML…

windows安装Oracle19c安装

windows安装Oracle19c安装 百度云安装包地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/11XvBN8Zqb7jbhugP88IHRw 提取码&#xff1a;ybsy 官网下载地址&#xff1a;https://www.oracle.com/database/technologies/oracle-database-software-downloads.html 下载…

基于vue3和element-plus的省市区级联组件

git地址&#xff1a;https://github.com/ht-sauce/elui-china-area-dht 使用:npm i elui-china-area-dht 默认使用 使用方法 <template><div class"app"><!--默认使用--><elui-china-area-dht change"onChange"></elui-china…

【android12-linux-5.1】【ST芯片】【RK3588】【LSM6DSR】HAL源码分析

一、环境介绍 RK3588主板搭载Android12操作系统,内核是Linux5.10,使用ST的六轴传感器LSM6DSR芯片。 二、芯片介绍 LSM6DSR是一款加速度和角速度(陀螺仪)六轴传感器,还内置了一个温度传感器。该芯片可以选择I2C,SPI通讯,还有可编程终端,可以后置摄像头等设备,功能是很…

MySQL阻塞与死锁

MySQL阻塞与死锁 阻塞 因为不同锁之间的兼容性关系&#xff0c;在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它所占用的资源&#xff0c;这就是阻塞。 # 查看等待时间 show variables like innodb_lock_wait_timeout; SETinnodb_lock_wait_timeout60; # 是否在等待…

深度学习面试八股文(2023.9.06持续更新)

一、优化器 1、SGD是什么&#xff1f; 批梯度下降&#xff08;Batch gradient descent&#xff09;&#xff1a;遍历全部数据集算一次损失函数&#xff0c;计算量开销大&#xff0c;计算速度慢&#xff0c;不支持在线学习。随机梯度下降&#xff08;Stochastic gradient desc…

【HTML/CSS】入门导学篇

本文属于HTML/CSS专栏文章&#xff0c;适合WEB前端开发入门学习&#xff0c;如果有所帮助请一键三连支持&#xff0c;对博主系列文章感兴趣点击下方专栏了解详细。 本文内容出自B站pink老师的前端入门教程&#xff0c;感谢pink老师&#xff01;&#xff01;&#xff01; 视频链…

【ARM CoreLink 系列 1 -- CoreLink 系列 产品介绍】

文章目录 ARM CoreLink 介绍ARM CoreLink InterconnectARM CoreLink 处理器外设ARM CoreLink Memory Controllers ARM CoreLink 介绍 ARM的CoreLink系列产品是一套能够进行高效互联的组件和工具&#xff0c;它们用于构建高性能、低功耗的嵌入式和消费电子设备。CoreLink产品系…

Mac MySQL初始登录root报错access denied解决方法

如图&#xff0c;当在mac m2上首次安装mysql后尝试登录root用户时&#xff0c;无论输入什么样的密码&#xff0c;或者直接回车键&#xff0c;都会显示access denied for user rootlocalhost。同时win和ubuntu也出现了一模一样的问题&#xff0c;先记录一下mac的解决方法。 参考…

Sigrity仿真报错:找不到电容的S参数?

很多电子工程师会选择使用Sigrity软件进行高速PCB信号仿真&#xff0c;但在使用过程可能会遇见报错情况&#xff0c;其中之一是提示找不到电容的S参数&#xff0c;那么如何解决这个问题&#xff1f; 一般来说&#xff0c;S参数的全称为Scatter参数&#xff0c;即散射参数&#…

STM32单片机OLED贪吃蛇游戏记分计时

实践制作DIY- GC00165---OLED贪吃蛇游戏 一、功能说明&#xff1a; 基于STM32单片机设计---OLED贪吃蛇游戏 二、功能说明&#xff1a; STM32F103C系列最小系统板0.96寸OLED显示器上、下、左、右4个按键 1.通过OLED配合按键实现贪吃蛇游戏 2.可以上下左右移动。 3.可以统计显…

JavaScript-----DOM元素

目录 前言&#xff1a; 1. DOM介绍 2. 获取节点 3. 操作HTML内容 4. 监听事件 案例 5. 操作节点的标签属性 6. 操作样式 7. 创建、添加、删除节点 前言&#xff1a; 在此之前我们要想去操作网页元素一般是去通过CSS选择器实现的&#xff0c;今天我们就学习JavaScript里…

bit、bin 、mcs文件区别

FPGA里面的可执行文件都涉及到 *.bit&#xff0c; *.mcs&#xff0c; *.bin 和 *.elf。 bit文件 bit 文件一般用于JTAG在线进行调试的时候&#xff0c;是把bit文件是烧写到FPGA中进行在线调试。 bin文件 bin 文件是二进制文件&#xff0c;按顺序只包含原始字节流&#xff0c…

74HC595

简介 74HC595 是一个 8 位串行输入、并行输出的位移缓存器&#xff0c;其中并行输出为三 态输出&#xff08;即高电平、低电平和高阻抗&#xff09; 15 和 1 到 7 脚 QA--QH&#xff1a;并行数据输出 9 脚 QH 非&#xff1a;串行数据输出 10 脚 SCLK 非&#xff08; MR&#…

【UE 材质】制作飘动的旗帜

效果 步骤 1. 首先在建模软件中创建一个平面&#xff0c;注意分段数一定要多 2. 在UE中创建一个材质&#xff0c;这里命名为“Mat_Flag” 打开“Mat_Flag”&#xff0c;先将旗帜纹理连接到基础颜色 先选中导入的模型然后点击根据选中的模型预览材质 创建如下节点可以看到此时模…

本地开发环境大小写不敏感引发的问题

推荐阅读 大小写敏感知多少[1] 文件大小写与文件系统有关&#xff0c;与操作系统无关。 血泪教训--拿到新移动硬盘该做的第一件事[2] MacOS 默认的文件系统APFS&#xff0c;如果没有手动更改&#xff0c;默认不区分大小写(可以在初始化时设置为大小写敏感)。 而公司测试/生产环…

AOSP和AAOS,向左走还是向右走?

Android Automotive OS&#xff08;AAOS&#xff09;和Android Open-Source Project&#xff08;AOSP&#xff09;之间存在很多混乱。这两个Android版本经常被混淆使用&#xff0c;但它们代表不同的平台和方法。为汽车In-Vehicle Infotainment&#xff08;IVI&#xff09;项目选…

2023CSP-S初赛复习整理

目录 逻辑运算常见运算运算规则运算优先级例题 进制转换十进制转二进制、八进制、十六进制二进制、八进制、十六进制转十进制例题 主定理编程语言概况具体分类 逻辑运算 常见运算 非&#xff1a; n o t not not 即 与&#xff1a; a n d and and 即 ∧ ∧ ∧ 或&#xf…