java-Mybatis框架02

news2024/11/15 17:41:37

1.#{} ${}区别

 #{} 是占位符,是采用编译方式向sql中传值,可以防止sql注入,如果往sql中传值,使用#{}
 ${} 是将内容直接拼接到sql语句中,一般不用于向sql中传值,一般用于向sql中动态传递列名。
 区别:
1.底层实现不同
#{} 采用预编译方式 可以防止sql注入 更加安全


${} 采用字符串拼接,直接将值拼接到sql中

2.使用场景不同


#{} 一般用于向sql中的列传值
${} 一般用于sql动态传递列名  例如,排序时order by  后面的列名是可以改变的。例如,select后面的列名也可以自由选择

2.特殊处理定义 resultMap

(1)定义resultMap

<resultMap id="studentMap" type="Student">
    <id column="id" property="id"></id>
    <result column="num" property="num"></result>
    <result column="name" property="name"></result>
    <result column="gender" property="gender"></result>
</resultMap>
1. resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为 “studentMap”
2. resutlMap 的 type 属性是映射的 POJO 类型
3. id 标签映射主键,result 标签映射非主键
4. property 设置对象属性名称,column 映射查询结果的列名称
(2)使用resultMap
 <select id="findStudentFindById" resultMap="studentMap">
        select
s.id,
s.num,
s.name,
s.gender,
m.name mname

 from student s inner join major m on s.majorid=m.id where s.id=#{id}
    </select>
1. 本例的输出映射使用的是 resultMap,而非 resultType
2. resultMap 引用了 studentMap

3.多表关联处理结果集

resultMap 元素中 association , collection 元素.
association 一个复杂类型的关联;许多结果将包装成这种类型
  • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
Collection  一个复杂类型的集合( 关联元素处理一对多关联
  • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
关联查询方式
1.关联查询方式一:直接多表关联查询获得学生及专业的信息
2.关联查询方式二:先查询主表(学生表),再通过学生表中的majorid与专业表关联,查询专业表
,得到Major对象,最后将得到的Major对象封装到学生对象中。

4.动态SQL

对SQL语句进行逻辑判断

1.if

<select id="teachers" resultType="Teacher">
    select * from teacher
   <where>
       <if test="num!=null">
            num= #{num}
       </if>
       <if test="name!=null">
      and   name= #{name}
       </if>
       <if test="gender!=null">
       and     gender= #{gender}
       </if>
   </where>

语法:<if test=""></if>

注意:test属性成立,执行if标签体,不成立就不执行

2.where

<select id="teachers" resultType="Teacher">
    select * from teacher
   <where>
       <if test="num!=null">
            num= #{num}
       </if>
       <if test="name!=null">
      and   name= #{name}
       </if>
       <if test="gender!=null">
       and     gender= #{gender}
       </if>
   </where>
</select>

语法:<where></where>

注意:当where标签中的if语句有条件成立时, 就会动态的添加where 关键字, 还可以动态删除where 紧跟着的关键字,例如 and or

3.trim

<select id="teachers" resultType="Teacher">
    select * from teacher
   <trim prefix="where" prefixOverrides="and| or">
     <if test="num!=null">
       num= #{num}
   </if>
       <if test="name!=null">
           or  name= #{name}
       </if>
       <if test="gender!=null">
           and     gender= #{gender}
       </if>
   </trim>
</select>

语法<trim prefix="where" prefixOverrides=""> </trim>

作用: trim 当判断条件成立时,可以自定义前缀关键字和后缀关键字

prefix="where"

prefixOverrides="and|or" 覆盖指定关键字

4.choose when otherwise

<select id="teachers" resultType="Teacher">
    select * from teacher
    <trim prefix="where" prefixOverrides="and| or">
       <choose>
           <when test="name!=null">
               name=#{name}
           </when>
           <otherwise>
               name='李老师'
           </otherwise>
       </choose>
    </trim>
</select>

语法:

<choose> 

 <when test="判断条件">

   执行的sql语句

    </when>

<otherwise> 

执行其他的sql语句

</otherwise>

</choose>

作用:MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句

5.set

可以把最后一个逗号去掉
<update id="updateTeacher" parameterType="Teacher">
update teacher
<set>
    <if test="num!=null">
        num=#{num},
    </if>
    <if test="name!=null">
        name=#{name},

    </if>
    <if test="gender!=null">
        gender=#{gender}
    </if>
</set>
where id=#{id}
    </update>

也可以用trim实现

<update id="updateTeacher" parameterType="Teacher">
    update teacher
  <trim prefix="set" suffixOverrides=",">
      <if test="num!=null">
          num=#{num},
      </if>
      <if test="name!=null">
          name=#{name},

      </if>
      <if test="gender!=null">
          gender=#{gender}
      </if>
  </trim>
    where id=#{id}
</update>

6.foreach

主要用在构建 in 条件中,它可以在 SQL 语句中进行迭代一个集合。foreach 元素的属性主要有 item,index,collection,open,separator,close。
item 表示集合中每一个元素进行迭代时的别名。
index 指定一个名字,用于 表示在迭代过程中,每次迭代到的位置。
open 表示该语句以什么开始。
separator 表示在每次进行迭代之间以什么符号作为分隔符。
close 表示以什 么结束。
  在使用 foreach 的时候最关键的也是最容易出错的就是 collection 属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的。
如果传入的是单参数且参数类型是一个 List 的时候,collection 属 性值为 list
如果传入的是单参数且参数类型是一个 array 数组的时候, collection 的属性值为 array
例如,可以用foreach来批量删除教师表的信息,用Integer[]数组来存放id,foreach循坏拿到id,
放入数组中

array:


<delete id="deleteTeacher">

delete from teacher where id in

<foreach item="id" collection="array" open="(" separator="," close=")">

#{id} </foreach>

</delete>

List:


<select id="findTeacher" resultType="Teacher">

select

<foreach item="col" collection="list" separator=",">

${col}

</foreach>

from teacher

</select>

5.特殊符号处理

在 mybatis 中的 xml 文件中,存在一些特殊的符号,比如:<、>、"、&、<> 等,正常书写 mybatis 会报错,需要对这些符号进行转义。具体转义如下所示:
特殊字符 转义字符
<      &lt
>     &gt
"      &quot
’      &apos
&     &amp
除了可以使用上述转义字符外,还可以使用<![CDATA[]]>来包裹特殊字符。如 下所示:
<if test="id != null">
AND <![CDATA[ id <> #{id} ]]>
</if>
<![CDATA[ ]]>是 XML 语法。在 CDATA 内部的所有内容都会被解析器忽略。
问题:那就是 <if> </if> <where> </where> <choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以 我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小<![CDATA[ ]]> 的范围。

6.mybatis 一级缓存二级缓存

缓存作用:是为了减去数据库的压力,提高查询性能

缓存原理:是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存) 中,当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库 执行 select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。(先从缓存中查询数据,缓存中如果没有,去数据库查询,查询到后把数据放到缓存中,下次直接从缓存中获取

1.mybatis一级缓存

(1)定义:在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调 用一个 Mapper 方法,往往只执行一次 SQL,因为使用 SelSession 第一次查询 后,MyBatis 会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新, 并且缓存没有超时的情况下,SqlSession 都会取出当前缓存的数据,而不会再 次发送 SQL 到数据库。(默认是SqlSession级别的,在同一个SqlSession中查询到数据先缓存到SqlSession对象中 第二次查询数据时,先从SqlSession中查询,如果有直接返回,没有,再去查询数据库

(2)一级缓存生命周期:
开始于SqlSession创建

结束于SqlSession的关闭
如果执行期间新增,修改,删除操作,也会清空当前SqlSession对象中缓存数据。调用sqlSession.clearCache(),强制清空一切缓存数据。

2.mybatis二级缓存

(1)定义:二级缓存是 SqlSessionFactory 级别的,根据 mapper 的 namespace 划分区域的,相同 namespace 的 mapper 查询的数据缓存在同一个区域,如果使 用 mapper 代理方法每个 mapper 的 namespace 都不同,此时可以理解为二 级缓存区域是根据 mapper 划分。 每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数 据写入缓存。Mybatis 内部存储缓存使用一个 HashMap,key 为 hashCode+sqlId+Sql 语句。value 为从查询出来映射生成的 java 对象。

作用: 二级缓存是SqlSessionFactory级别的,可以让多个SqlSession共享数据

注意

* mybatis默认没有开启二级缓存,使用时需要配置开启。

* 如果开启二级缓存,当SqlSession关闭时,会将一级缓存数据存储到二级缓存中 , 其他的SqlSession就会从二级缓存中查询到之前的SqlSession数据。

sqlSession 执行 insert、update、delete 等操作 commit 提交后会清空缓存区 域,防止脏读。
二级缓存机制设计及工作模式如下图所示:

(2)配置二级缓存设置

<1>启用二级缓存

在mybaits.xml文件中配置全局二级缓存开关

如下代码所示,当 cacheEnabled 设置为 true 时启用二级缓存,设置为 false 时禁用二级缓存。

<setting name="cacheEnabled" value="true"/>
<2>对象序列化
将所有的 POJO 类实现序列化接口 Java.io. Serializable(这里我用的是Teacher类)
<3>配置映射文件
在 TeacherMapper 映射文件中添加<cache />/<cache></cache>,表示此 mapper 开启二级缓存。
当 SqlSeesion 关闭时,会将数据存入到二级缓存.
注意:可以在使用的方法上配置是否开启二级缓存 使用useCache=""属性可以来开启或关闭二级缓存

3.mybatis架构

7.Java反射

在mybatis中,给了什么类型,mybatis就可以将结果封装映射到给定的类的对象中
<select id="findAdminByld" parameterType="int" resultType="Admin">
<select id="teachers" resultType="com.ffyc.mybatispro.model.Teacher">

框架需要只写一套程序,就可以处理给其的任意类,

框架是如何做到写一套程序,就可以处理任意类了?

以前已知类名的使用方式,可以看做是正向使用类.

框架需要对任意类处理时,只是知道类的名字,通过类的名字动态才去获取类中的信息.

把这种对类的使用方式,称为反向使用.

1.java反射概念及作用

Java反射:是在运行状态中,对于任意一个类,都能够知道这个 类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制。(在运行状态中在仅知道一个类名时,就可以动态获得类中信息,创建对象,调用对象成员的机制称为java反射机制)
作用  动态获取类的信息。

2.java反射相关API

2.1.Class类(java.lang.Class)

(1)概念:Class类表示当前正在运行中的类和接口

注意;一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被 使用时都会创建一个Class对象;

Class类是Java反射机制的基础,通过Class类,可以得到一个类的基本 信息。

(2)获得Class类的方法

Object类中的getClass方法:适用于通过对象获得Class实例的情况
类名.class方式:适用于通过类名获得Class实例的情况
Class类的静态方法 forName(String name)
(3)java创建对象的四种方式
 1.new  +对象名
2.反序列化
3.反射机制  获取到对象的包名和类名
 4.对象克隆

2.2 Constructor类

Constructor是获取对象的构造方法的类

获取Constructor的实例:

1.通过Class实例获得,Class类中定义了如下方法

Constructor<T> getConstructor(Class... parameterTypes)
通过指定参数类型,返回构造方法

(1)getConstructor()  获得指定的公共构造方法

(2).getConstructors();//获得所有公共的构造方法

(3).getDeclaredConstructor();//获得类中任意的构造方法(包含私有)

(4)getDeclaredConstructors();//获得类中所有的构造方法(包含私有)

2.Constructor类可以通过getXXX方法获得构造方法的基本信息.

getName:返回构造方法的名字
除了获得构造方法的基本信息,还可以创建实例
newInstance(Object... initargs) :创建实例

2.3 Field类

Field类作用是获取到对象的成员变量

1.获得Field类实例:

 public Field getField(String name)通过指定Field名字,返回 Field实例.   注意Field的访问权限

(1)getField("成员变量");//获得指定名称的公共的成员变量

(2)getFields() 获得所有的公共成员变量

(3)getDeclaredField( "成员变量t");//获得指定名称的成员变量,包含私有的

(4)getDeclaredFields( );//获得所有的成员变量,包含私有的

2.Field类的作用

  Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也
可以对属性进行赋值.
  getName:返回属性的名字
  set:设置属性值

2.4  Method类

1.获取Method类的实例:

Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例
2.Method类作用
1.  Method类将类中的方法进行封装,可以动态获得方法的信息,例如
● getName:获得方法名字
● getParameterTypes:获得方法参数类型
2.除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法
● invoke(Object obj, Object... args) :使用obj调用该方法,参数为args

8.反射案例

1.演示通过属性的get和set方法,对类中的私有属性进行取值,操作。
User类:
public class Test3 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

        //使用反射机制时,只知道类的名称(包名+类名)
        String classname="com.ffyc.javaReflect.User";
        /* String classname="com.ffyc.javaReflect.Car";*/

//        1.通过类名获得到类的Class对象
       Class clazz= Class.forName(classname);

//        2.通过类的Class对象,创建对象
         Object object=clazz.newInstance()
       
        /*模拟从数据库拿到的数据*/
        HashMap<String,String> map=new HashMap<>();
        map.put("account", "admin");
        map.put("password", "111");
           Field[] fields=clazz.getDeclaredFields();//获得类中所有成员变量
        for(Field field:fields){
            field.setAccessible(true);//允许访问操作私有的属性
         field.set(object,map.get(field.getName()) );

        }
        System.out.println(object);
    }
}

2.自定义java对象转json工具类

类同上

public class JsonUtil {
    public  static String objectToJson(Object object) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
     // 获取到类的Class对象
        Class clazz=object.getClass();
String json="{";
//获取类中所有属性
        Field[] declaredFields =clazz.getDeclaredFields();
        for(Field field:declaredFields){
//生成属性get方法名字
            String getmethod = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
          //获得方法对象
            Method method=clazz.getMethod(getmethod);
//            调用方法
      String value=(String)method.invoke(object);
//      把属性名称和和值拼接成键值
            json+=field.getName()+":"+value+",";
        }
        json=json.substring(0,json.length()-1);
json+="}";

return json;
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        User user=new User();
        user.setAccount("admin");
        user.setPassword("111");

        Car car=new Car();
        car.setName("bbb");
        car.setColor("red");

        System.out.println(JsonUtil.objectToJson(user));
        System.out.println(JsonUtil.objectToJson(car));
    }
}

9.反射机制的优缺点

优点:

 1. 增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
 2.提高代码的复用率,比如动态代理
 3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用
缺点:
 1. 反射会涉及到动态类型的解析,导致性能要比非反射调用更低
 2. 使用反射技术通常要在一个没有安全限制的程序运行 .
 3. 反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象 性

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

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

相关文章

电控专业课程已开放

凌鸥学园旨在为电机控制爱好者提供学习交流成长平台&#xff0c;缓解电控行业人才缺口扩大趋势&#xff0c;共同打造繁荣行业生态。我们将全面整合LKS MCU相关资料&#xff0c;包括开发环境、应用笔记、教学视频、学习指导等&#xff0c;并设有专业课程。 通过凌鸥学园的专业体…

【RabbitMQ】快速上手

目 录 一. RabbitMQ 安装二. RabbitMQ 核心概念2.1 Producer 和 Consumer2.2 Connection 和 Channel2.3 Virtual host2.4 Queue2.5 Exchange2.6 RabbitMQ 工作流程 三. AMQP四. web界面操作4.1 用户相关操作4.2 虚拟主机相关操作 五. RabbitMQ 快速入门5.1 引入依赖5.2 编写生产…

简单的jar包解压class文件修改再编译成jar包

简单的jar包解压class文件修改再编译成jar包 1. 需求 我们公司有一个项目演示的环境&#xff0c;这个环境是我们公司其他组的项目&#xff0c;我们组只有这个项目的前端&#xff0c;jar&#xff0c;以及部分数据库结构表信息&#xff0c;现在我们已经启动服务可以正常访问&am…

Python中PDF文件的编辑与创建

目录 安装必要的库 编辑现有PDF文件 合并PDF文件 拆分PDF文件 添加水印 注意 创建新的PDF文件 使用reportlab创建PDF 使用Spire.PDF for Python创建PDF 结论 在数字化办公和学习环境中&#xff0c;PDF&#xff08;Portable Document Format&#xff09;文件因其跨平台…

【免费分享】1982-2015华北平原农田蒸散发数据集

华北平原是中国最重要的产粮基地之一&#xff0c;然而该地区水资源缺乏、供需矛盾突出。 在全球气候变化及用水需求日益增加的背景下&#xff0c; 该地区水循环过程变得愈加脆弱。 因此如何准确估算蒸散发、 掌握蒸散发的时空变化规律&#xff0c; 进而合理配置水资源、提高农业…

Lua收集请求日志

Kafka搭建 单机版的kafka搭建非常简单&#xff0c;不过我们今天采用Docker搭建kafka。Kafka使用Zookeeper存储Consumer、Broker信息&#xff0c;安装kafak的时候&#xff0c;需要先安装Zookeeper。 Zookeeper安装&#xff1a; docker run -d --name zookeeper -p 3181:3181 …

《网络安全自学指南》

《网络安全自学教程》 《网络安全自学》 1、网络协议安全1.1、OSI七层模型1.2、TCP/IP协议栈1.3、Wireshark使用1.4、802.1x协议1.5、ARP协议1.6、ARP欺骗1.7、IP协议1.8、ICMP协议1.9、TCP协议1.10、SYN Flood1.11、SSL协议1.12、HTTP协议1.13、DHCP协议 2、操作系统安全2.1、…

<数据集>TACO垃圾识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;6004张 标注数量(xml文件个数)&#xff1a;6004 标注数量(txt文件个数)&#xff1a;6004 标注类别数&#xff1a;18 标注类别名称&#xff1a;[Crankshaft, Centrifugal_body, Washer_container, Circlip_containe…

保存和加载工作区变量

目录 保存工作区变量 加载工作区变量 查看 MAT 文件的内容 在 MATLAB 会话之间并不保留工作区。退出 MATLAB 时&#xff0c;工作区清除。但是&#xff0c;您可以将当前工作区中的任何或所有变量保存到 MAT 文件(.mat)中。之后&#xff0c;只需加载保存的 MAT 文件&#xff0…

工业设备定位激光器在工业领域的应用

在日新月异的工业制造领域&#xff0c;技术的每一次飞跃都深刻影响着生产效率和产品质量的双重提升。其中&#xff0c;工业设备定位激光器作为现代工业自动化的核心元件之一&#xff0c;正以其高精度、高效率和广泛的应用范围&#xff0c;引领着制造业的智能化转型。接下来给大…

<PLC><算法>使用汇川eazy521系列PLC,如何使用LiteST语言对乱序数组进行排序?(冒泡法)

前言 本系列是关于PLC相关的博文&#xff0c;包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌&#xff0c;汇川、信捷等国内品牌。 除了PLC为主要内容外&#xff0c;PLC相关元器件如触摸屏…

NS4054H 40V 高耐压线性锂离子电池充电管理 IC

1 特性  最大输入电压&#xff1a; 40V  输入过压保护电压&#xff1a; 6V  内置输入过流保护&#xff1a; 1A  支持 0V 电池电压充电  充电电流可编程  4.2V 充电浮充阈值电压  电池待机电流&#xff1c; 1uA  内置 C/10 充满截止功能 …

数据结构-manacher算法

第一种情况: 以t为中心&#xff0c;他的回文串为abedeks, 同时i’的回文为ede&#xff0c;那么i的回文也是ede。 第二种情况:以s为中心的回文串为 tabkdedk,而以i’为中心的回文串为abkde&#xff0c;已不再L和R之间。此时以i为中心的回文串就为kdedk. 第三种情况: 以t为中心…

书生大模型实战营第三期基础岛第六课——OpenCompass 评测 InternLM-1.8B 实践

OpenCompass 评测 InternLM-1.8B 实践 基础作业:创建虚拟环境下载并安装opencompass安装相关依赖复制测评数据集到当前目录下并解压测评前环境变量配置使用命令行配置参数法进行评测 基础作业: 使用 OpenCompass 评测 internlm2-chat-1.8b 模型在 ceval 数据集上的性能&#x…

强化学习,第 4 部分:蒙特卡洛控制

目录 一、介绍 1.1 强化学习 2.1 关于此文章 三、ε贪婪策略 四、蒙特卡洛控制 4.1 基本原理 4.2 举个例子 五、On-policy & off-policy 方法 六、重要性采样 6.1 赋予动机 6.2 想法 6.3 应用 七、增量实施 7.1 增量的理论 7.2 常α MC 八、结论 一、介绍 …

Livekit本地部署Egress录制服务

Livekit本地部署Egress录制服务 Egress官方推荐使用Docker方式部署。官方文档 创建Egress配置文件 新建config文件 vim config.yamlconfig.yaml文件内容 log_level: debug# api_key 参考livekit 部署 配置的 api_key: 2yJimTMFeF9h15PHEv api_secret: Mvi9ZgqGJ3LqwEAcTV…

项目管理的七大核心要素

项目管理不仅涉及一系列复杂的活动&#xff0c;还涵盖了多个关键要素&#xff0c;这些要素相互交织&#xff0c;共同构成了项目成功的基石。 项目管理七大要素&#xff1a; 1、明确的项目目标&#xff1a; 项目管理的起点是确立清晰、具体、可衡量的项目目标。这些目标不仅为…

新手网络爬虫利器介绍 之 移动蜂窝网络代理

移动蜂窝代理对接说明 在爬虫与反爬虫斗争愈演愈烈的情况下&#xff0c;各大网站和 App 的风控检测越来越强&#xff0c;其中一项就是 IP 封禁。 为了解决 IP 封禁的困扰&#xff0c;一个有效的方式就是设置代理&#xff0c;设置代理之后&#xff0c;爬虫可以借助代理的 IP 来…

IntelliJ IDEA 自定义字体大小

常用编程软件自定义字体大全首页 文章目录 前言具体操作1. 打开设置对话框2. 设置编辑器字体3. 设置编译软件整体字体 前言 IntelliJ IDEA 自定义字体大小&#xff0c;统一设置为 JetBrains Mono 具体操作 【File】>【Settings...】>【Editor】>【Font】 统一设置…

关于git报错please clean your repository working tree

在vscode中使用git拉取代码提示&#xff1a;在签出前&#xff0c;请清理存储库工作树。有时候在写代码前未更新远程代码&#xff0c;会出现代码冲突。 1.git stash 先将本地修改存储在暂存区2.git pull 拉取远程代码3.git stash pop 释放暂存区内容