day50_mybatis

news2025/6/22 12:17:04

今日内容

0 复习昨日
一、分页插件
二、ORM映射【重点】
三、多表联查 【重点】
四、动态SQL 【重点】
五、$和#

零、复习昨日

mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心
思考MyBatis到底帮你省了哪些事情?
jdbc第四步sql自己编写之外,其他mybatis都做了…
接口文件和映射文件如何关联?
namespace
接口文件中方法又是如何和映射文件中的语句关联?
接口的方法名与映射文件标签的id一致
语句执行时入参都可以有哪些?有什么注意事项?
基本类型,String,Map,List,POJO(javabean/对象)
语句执行后返回的有哪些类型?(出参)
基本类型,字符串,对象

BUG:

1 idea中resuorces和test文件不识别

手动设置标记

image-20230607092633522

2 编码格式

控制台错误提示:

MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。

解决方案,在pom文件中加入配置

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

补充: mapper文件位置

mapper映射文件放置位置有两个

  • resources(推荐)
  • java
    • 如果使用这种,还需再pom文件加入build设置,让idea加载java下的xml文件

myabtis-config.xml文件加载映射文件时也要两种方案

  • 使用<mapper resource="com/qf/mapper/UserMapper.xml"/>
    但是这种写法,会随着项目模块的增多,这个地方也会随之配置增多

  • 使用<package name="com.qf.mapper"/>

    这种写法可以一次加载一个包下的所有映射文件,但是包结构要与接口文件包结构一致

总结,以后就按照以下写法配置:

  • 映射文件全部放在resources
  • resources下放映射文件包结构要与java放接口文件包结构一致
  • 文件名要一致

一、分页插件

现在我们要学习使用一个常用的mybatis的插件 --> 分页插件-PageHelper

最早: findAll() ---> 查全部
后来要分页: findAll(pageNo,pageSize) ---> 改动SQL 加上 limit x,y
还行count(*)来计数

使用分页插件之后,只编写正常的查询SQL即可,关于分页的操作插件会自动完成.

引入依赖

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.0</version>
        </dependency>

全局配置文件使用插件

    <!-- 插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
    </plugins>

在查询时使用分页功能

public interface UserMapper {
    List<User> findAll();
}


<select id="findAll" resultType="User">
    select * from tb_user
</select>

@Test
public void findAll() {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 【在执行查询前设置】
    // 参数1: 当前页
    // 参数2: 每页大小
    PageHelper.startPage(2,2);

    List<User> all = mapper.findAll( );
    for (User user : all) {
        System.out.println(user );
    }
}

image-20221215152540842

mybatis插件是对运行时某一点进行拦截

pagehelper插件是拦截运行时发出的SQL,自动在SQL后面拼接关键词


后续还可以获得更新消息的分页数据,比如共多少条数据?共多少页?当前页?下一页?目前是不是第一页?

    @Test
    public void findAll() {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        // 【在执行查询前设置】
        // 参数1: 当前页
        // 参数2: 每页大小
        PageHelper.startPage(2,2);

        // 执行查询全部
        List<User> userList = mapper.findAll( );

        // 后续可以获得更详细的信息
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        System.out.println(pageInfo );
        // 获得总条数
        System.out.println(pageInfo.getTotal() );
        // 获得总页数
        System.out.println(pageInfo.getPages() );
        // 获得总数据(当前页中的总数据)
        System.out.println(pageInfo.getList() );
    }

ps: 可以看源码,中国人开发,注释非常好理解

二、ORM映射


2.1 MyBatis自动ORM失效

MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。

自动ORM失效
image-20230601164912980

2.2 方案一:列的别名

在SQL中使用 as 为查询字段添加列别名,以匹配属性名。

<mapper namespace="com.qf.mapper.UserMapper">
    <select id="findUserById" resultType="User">
		select id as idd,username,password,phone,create_time,sex,money from tb_user where id = #{id}
    </select>
</mapper>

2.3 方案二:结果映射(ResultMap - 查询结果的封装规则)

通过< resultMap id=“” type=“” >映射,匹配列名与属性名。

<mapper namespace="com.qf.mapper.UserMapper">

    <!--定义resultMap标签-->
    <resultMap id="findUserByIdResultMap" type="user">
      	<!--关联主键与列名-->
        <id property="idd" column="id" />
    </resultMap>
  
     <!--使用resultMap作为ORM映射依据-->
    <select id="findUserById" resultMap="findUserByIdResultMap">
        select id,username,password,phone,create_time,sex,money from tb_user where id = #{id}
    </select>
</mapper>

三、 多表联查 【重点】

表关系: 一对一,一对多,多对多

多表联查的SQL

3.1 OneToOne

需求: 实现一对一查询,查询订单以及对应的用户信息

数据: tb_user表, tb_order表

关系:

用户 —> 订单 (1 VS N) 一个用户有多个订单
订单 —> 用户 (1 VS 1) 一个订单只会属于一个人

tb_user表

CREATE TABLE `tb_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(10) DEFAULT NULL COMMENT '用户名',
  `password` varchar(10) DEFAULT NULL COMMENT '密码',
  `phone` varchar(11) DEFAULT NULL COMMENT '手机号',
  `create_time` date DEFAULT NULL COMMENT '注册时间',
  `money` double(10,2) DEFAULT NULL COMMENT '账户余额'
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;

tb_order表

CREATE TABLE `tb_order` (
  `oid` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单编号',
  `order_time` datetime DEFAULT NULL COMMENT '订单时间',
  `order_desc` varchar(255) DEFAULT NULL COMMENT '订单详情',
  `uid` int(11) DEFAULT NULL COMMENT '关联用户id',
  PRIMARY KEY (`oid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `tb_order` VALUES (1, '2022-11-17 15:06:29', '笔记本电脑', 1);
INSERT INTO `tb_order` VALUES (2, '2022-12-16 11:00:41', 'Cherry键盘', 1);
INSERT INTO `tb_order` VALUES (3, '2022-12-16 11:01:23', 'Logi鼠标', 2);

实体类

public class Order {

    private int oid;
    private Date orderTime;
    private String orderDesc;
    private int uid;
 	// set get...   
}

但是上面的实体类,只有订单信息,我们要查询的是订单和用户! 上面的类就无法展现全部数据,所以需要扩展类

public class OrderVO extends Order {
    private User user;
    // set get
}

OrderMapper.java接口文件

public interface OrderMapper {
    OrderVO findOrderWithUserById(int oid);
}

OrderMapper.xml映射文件

    <resultMap id="orderWithUserResultMap" type="OrderVO">
        <!-- 封装查询主体Order: -->
        <id column="oid" property="oid"/>
        <result column="order_time" property="orderTime"/>
        <result column="order_desc" property="orderDesc"/>
        <result column="uid" property="uid"/>
        <!-- 一对一映射,需要封装关联的User对象 -->
        <!-- 一对一映射,需要特殊标签 association-->
        <!-- property="user" 是OrderVO类中的属性,javaType是user属性的类型 -->
        <association property="user" javaType="com.qf.model.User">
            <!-- 下面正常的列和属性 一一映射 -->
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
            <result column="phone" property="phone"/>
            <result column="create_time" property="createTime"/>
            <result column="money" property="money"/>
        </association>
    </resultMap>

    <!-- 多表联查,直接返回resultType无法封装关联的那个对象,就使用使用resultMap手动映射 -->
    <select id="findOrderWithUserById" resultMap="orderWithUserResultMap">
        SELECT
            o.*,
            u.*
        FROM
            tb_order o,
            tb_user u
        WHERE
            o.uid = u.id
        AND o.oid = 1
    </select>

测试

    @Test
    public void findOrderWithUserById() {
        OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
        OrderVO orderVO = mapper.findOrderWithUserById(1);

        // 获得订单信息
        int oid = orderVO.getOid( );
        System.out.println("oid = " + oid);
        Date orderTime = orderVO.getOrderTime( );
        System.out.println("orderTime = " + orderTime);
        String orderDesc = orderVO.getOrderDesc( );
        System.out.println("orderDesc = " + orderDesc);
    
        // 获得订单一家关联的用户信息
        User user = orderVO.getUser( );
        System.out.println(user );
    }

3.2 OneToMore

需求: 一对多,查询用户关联查询出所有的订单

SELECT
	* 
FROM
	tb_user u
LEFT JOIN tb_order o ON u.id = o.uid 
WHERE
	u.id = 3

目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List<Order>

User扩展实体类

public class UserVO extends User{

    private List<Order> orderList;

    @Override
    public String toString() {
        String s = super.toString( );
        return s +" \r\n UserVO{" +
                "orderList=" + orderList +
                '}';
    }

    public List<Order> getOrderList() {
        return orderList;
    }

    public void setOrderList(List<Order> orderList) {
        this.orderList = orderList;
    }
}

UserMapper.java接口

public interface UserMapper {
    UserVO findUserWithOrdersById(int id);
}

UserMapper.xml映射文件

    <!-- 一对多 -->
    <resultMap id="userWithOrdersResultMap" type="UserVO">
        <!-- 封装User对象 -->
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="phone" property="phone"/>
        <result column="create_time" property="createTime"/>
        <result column="money" property="money"/>
        <!-- 一对多关联映射使用collection标签 -->
        <!-- property是UserVO类中关联的属性 -->
        <!-- 不是javaType,是ofType,是指定集合中存储的数据类型 -->
        <collection property="orderList" ofType="com.qf.model.Order">
            <id column="oid" property="oid"/>
            <result column="order_time" property="orderTime"/>
            <result column="order_desc" property="orderDesc"/>
            <result column="uid" property="uid"/>
        </collection>
    </resultMap>

    <!-- 多表联查,另外的属性不会自动封装,需要使用resultMap -->
    <select id="findUserWithOrdersById" resultMap="userWithOrdersResultMap">
        SELECT
        *
        FROM
        tb_user u
        LEFT JOIN tb_order o ON u.id = o.uid
        WHERE
        u.id = #{id}
    </select>

3.3 关联查询总结

正常封装使用resultMap

一对一封装使用association

一对多封装使用collection

四、动态SQL【重点】

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。


自己话理解: 帮助我们拼接SQL

常见的动态SQL语法

  • SQL片段(官方不是在动态SQL章节)
  • where , if
  • set
  • trim
  • foreach

4.1 SQL片段

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。

自己的话: 减少代码重复,主要用于抽取字段,表名等

    <!-- 将重复的SQL代码抽取成SQL片段,以供复用 -->
    <sql id="userField">
        id,
        username,
        password,
        phone,
        create_time,
        money,
        sex
    </sql>

    <select id="findAll" resultType="User">
        select
            <!-- 引入片段 -->
            <include refid="userField"/>
        from
            tb_user
    </select>

4.2 if

if就是用来判断,主要用于判断要不要拼接对应的条件语句

-- 需求:查询用户,条件是money=1000,如果密码不为空,也根据密码查
select * from tb_user where money = 1000
select * from tb_user where money = 1000 and password= '123456'

UserMapper.java接口方法

public interface UserMapper {
    /**
     * 演示if动态sql
     */
    List<User> findByMap(HashMap<String,Object> map);

}

UserMapper.xml

    <select id="findByMap" resultMap="userResultMap">
        select
            <include refid="userField"/>
        from
            tb_user
        where
            money = #{money}
        <if test="password != null and password != ''">
            and password = #{password}
        </if>
    </select>

测试

/**
     * if动态sql
     */
@Test
public void showIf() {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    HashMap<String, Object> map = new HashMap<>( );
    map.put("money",1000);
    List<User> list = userMapper.findByMap(map);
    for (User user : list) {
        System.out.println(user );
    }
}

4.3 where

如果说只有if,可能会出现这么一种情况

SELECT * FROM tb_user WHERE

多出一个where关键词!!


所以我们需要一个智能的,有条件时帮我们拼接where关键词,没有条件查询时,不拼接where

    <!-- 测试if的缺点 -->
    <select id="findUserBySex2" resultType="User">
        select
            <include refid="userField"/>
        from
            tb_user
        <where>
            <if test="sex != null">
                sex = #{sex}
            </if>
        </where>
    </select>

所以一般会where和if一起用

4.4 set

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列。

UserMapper.java接口方法

public interface UserMapper {
    int updateUser(User user);
}

UserMapper.xml

    <!-- set完成动态更新 -->
    <update id="updateUser">
        update tb_user
        <!-- set标签自动拼接SET关键词 -->
        <set>
            <!-- 会自动过滤最后一个, -->
            <!-- 特别注意,因为判断条件是!=null,基本不可能为null,所以将基本类型变为包装类 -->
            <if test="username != null">username = #{username},</if>
            <if test="password != null">password = #{password},</if>
            <if test="phone != null">phone = #{phone},</if>
            <if test="createTime != null">create_time = #{createTime},</if>
            <if test="money != null">money = #{money},</if>
            <if test="sex != null">sex = #{sex},</if>
        </set>
        where id = #{id}
    </update>

测试

    @Test
    public void testUpdate(){
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = new User( );
        user.setId(1);
        // 只更新这个2字段,其他字段不动
        user.setUsername("QF");
        user.setPassword("qf666");

        int i = mapper.updateUser(user);
        System.out.println(i > 0?"OK":"ERR" );
        // 增删改要提交
        sqlSession.commit();
    }

4.5 foreach

场景: 批量删除

delete from tb_user where id in (1,2,3,...);
String sql = "delete from tb_user where id in (";
int iMax = idsArr.length - 1;// 最大下标
for (int i = 0; i < idsArr.length; i++) {
    int id = idsArr[i];
    sql += id;
    if (i != iMax) {
        sql += ",";
    } else {
        sql += ")";
    }
}

UserMapper.java

public interface UserMapper {
    // 为了演示动态sql foreach
    int deleteBatch(List<Integer> ids);
}

UserMapper.xml

    <!-- 动态sql foreach -->
    <delete id="deleteBatch">
        delete from tb_user
        where id in
        <!--
           <foreach>开始循环,取出集合中的数据
           collection,要遍历的集合,此处必须写list (或者可以写collection,arg0,不能写别的)
           item , 遍历得到结果,命名任意,但是下面#{}内的名字要和这里一致
        -->
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}  
        </foreach>
    </delete>

测试

   /**
     * 测试foreach
     */
    @Test
    public void testForeach(){
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        ArrayList<Integer> list = new ArrayList<>( );
        list.add(31);
        list.add(32);
        list.add(33);
        int i = mapper.deleteBatch(list);
        System.out.println("i = " + i);
        System.out.println(i > 0?"OK":"ERR" );
        // 增删改要提交
        sqlSession.commit();
    }

任务

使用项目中的表,重复1遍
合同加房屋实现多表联查
做笔记,写注释,画图标记
使用项目中的表,重复1遍
合同加房屋实现多表联查
做笔记,写注释,画图标记

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

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

相关文章

C++标准库模板(STL)-输入/输出库

C 包含两个输入/输出库&#xff1a;现代的、基于流的 I/O 库和 C 风格 I/O 函数的标准集合。 基于流的 I/O 基于流的输入/输出库围绕抽象的输入/输出设备组织。这些抽象设备允许相同代码处理对文件、内存流或随即进行任意操作&#xff08;例如压缩&#xff09;的自定义适配器…

编译原理 | 课程设计 — PL/0编译程序语法分析

1、任务描述 基于第二章的词法分析程序&#xff0c;使用C/C语言编写PL/0编译程序的语法分析程序。 2、编程要求 完成上述编程任务&#xff0c;将C/C语言源程序复制粘贴到右侧代码编辑器&#xff0c;点击“评测”按钮&#xff0c;运行程序&#xff0c;系统会自动进行结果对比。 …

CoreDX DDS应用开发指南(4)DDS实体h和主题

6 DDS实体 DDS标准定义了一个体系结构,该体系结构表示构成DDS API实体的面向对象模型。这些实体充当中间件和应用软件之间的接口。为了开发支持DDS的应用程序,开发人员必须创建、交互并销毁这些DDS实体。 本章概述了DDS实体和相关概念。 6.1 DDS实体层次结构 构成DDS API的主…

马斯克最大的挑战是什么?

“硅谷钢铁侠”马斯克&#xff0c;最大的挑战是什么&#xff1f; 有纠错反馈循环&#xff0c;并保持这个循环 我们常说的“迭代”&#xff0c;就是打造“反馈系统” 趣讲大白话&#xff1a;需要一面不扭曲的镜子 【趣讲信息科技192期】 **************************** 2017年&a…

通过浏览器,将webp格式图片转jpg格式

概述 我们网络上下载的图片&#xff0c;很多的是webp格式的图片&#xff0c;而目前支持这种图片格式的软件较少&#xff0c;比如Windows 照片查看器&#xff0c;是不能直接打开图片的。安装其他专业图像软件又麻烦。 因此&#xff0c;本文介绍利用电脑常用的软件&#xff0c;…

运营-20.产品社区化和内容化

产品社区化和内容化 为什么现在很多产品都在往社区化、内容化发展&#xff1f; 1.拓展产品线&#xff0c;满足用户的多元需求 分享、交流、炫耀、虚荣&#xff0c;这些是人类永恒的情感需求&#xff0c;社区是一个能很好的满足这些需求的工具&#xff1b; 2.打造归属感&…

TiDB亿级数据亚秒响应查询Dashboard使用

目录 1 集群概况1.1 QPS1.1.1 延迟1.1.2 Top SQL 语句1.1.3 最近的慢查询 2 集群信息2.1 实例列表2.1.1 表格列解释2.1.2 实例状态解释 2.2 主机列表2.2.1 表格列解释 2.3 SQL语句分析2.3.1 执行列表页2.3.2 执行详情页面 2.4 慢查询2.4.1 慢查询列表页2.4.2 查看执行详情 2.5 …

2023-06-10 Untiy进阶 C#知识补充1——.Net介绍

文章目录 一、.Net 介绍二、.Net 跨语言的实现三、.Net 跨平台的实现&#xff08;一&#xff09;.Net Framework&#xff08;二&#xff09;.Net Core&#xff08;三&#xff09;Mono 四、总结 一、.Net 介绍 ​ 微软的 .Net 既不是编程语言也不是框架&#xff0c;是类似于互联…

Tomcat部署和优化

文章目录 Tomcat概述Tomcat的核心组件Tomcat的功能组件结构Container 结构分析Tomcat 请求过程&#xff1a; Tomcat 服务部署Tomcat 虚拟主机配置HTTP 请求过程 Tomcat优化常用的优化相关参数如下 Tomcat概述 Tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的…

Spring高手之路4——深度解析Spring内置作用域及其在实践中的应用

文章目录 1. Spring的内置作用域2. singleton作用域2.1 singleton作用域的定义和用途2.2 singleton作用域线程安全问题 3. prototype作用域3.1 prototype作用域的定义和用途3.2 prototype作用域在开发中的例子 4. request作用域&#xff08;了解&#xff09;5. session作用域&a…

002docker 安装

官网安装https://docs.docker.com/engine/install/ 系统要求 Centos7 Linux 内核&#xff1a;官方建议 3.10 以上查看Linux内核版本 用于打印当前系统的相关信息(内核版本号,硬件架构,主机名称和操作系统类型等 cat /proc/version uname -a 更新YUM源 生产环境中此步操作…

Spring Cloud Feign实战

概述 Feign是一种声明式、模板化的HTTP Client&#xff0c;目标是使编写Java HTTP Client变得更简单。Feign通过使用Jersey和CXF等工具实现一个HTTP Client&#xff0c;用于构建REST或SOAP的服务。Feign还支持用户基于常用的HTTP工具包&#xff08;OkHTTP、HTTPComponents&…

2023网安面试题170道,轻松应对面试

最近有不少小伙伴跑来咨询&#xff1a; 想找网络安全工作&#xff0c;应该要怎么进行技术面试准备&#xff1f; 工作不到 2 年&#xff0c;想跳槽看下机会&#xff0c;有没有相关的面试题呢&#xff1f; 为了更好地帮助大家高薪就业&#xff0c;今天就给大家分享两份网络安全工…

仙境传说ro:如何在地图上刷怪教程

仙境传说ro&#xff1a;如何在地图上刷怪教程 大家好我是艾西&#xff0c;在仙境传说这个游戏中我们知道了怎么创建NPC添加商品售卖后&#xff0c;那么对于游戏的怪肯定也得有自己的想法以及对游戏的设定以及理解&#xff0c;今天我跟大家分享的是怎么在地图中刷怪教程。 我们…

STL——string、vector、deque容器

初识STL **STL的基本概念****vector容器存放内置数据类型****vector容器中存放自定义数据类型****vector容器嵌套vector容器****string容器——构造函数****string容器——赋值操作****string容器——字符串拼接****string容器——字符串的查找和替换****string容器——字符串比…

人工智能该如何学习?详细的AI学习

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 1.TomChat 地址&#xff1a;https://www.ridderchat.com/ 该网站非常简介好看&#xff0c;界面看着很舒服&#xff0c;可以帮助你快速编写、编辑和讨论代码。 2.强大的AI辅助 链接…

模拟实现strstr函数,通俗易懂!!!

函数介绍 函数声明 函数声明&#xff1a;char *strstr(const char *str1, const char *str2) 头 文 件&#xff1a;#include <string.h> 返 回 值&#xff1a; 返回值为char * 类型&#xff08; 返回指向 str1 中第一次出现的 str2 的指针&#xff09;&#xff1b…

Webots R2021a教程

文章目录 Windows安装设置中文打开世界添加贴图 为外部控制器配置Anaconda解决报错&#xff1a;CondaSSLError: Encountered an SSL error. Most likely a certificate verification issue.调用Python API Windows 安装 进入下载页面 https://github.com/cyberbotics/webots/r…

CSS实现几种常见布局

CSS实现几种常见布局 两列左窄右宽型布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…

【面试题】2023前端面试系列-- Vue 篇

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 Vue 常见面试题总结 MVVM模型&#xff1f; MVVM&#xff0c;是Model-View-ViewModel的简写…