MyBatis-Plus —— 初窥门径
前言
在前面的文章中荔枝梳理了MyBatis及相关的操作,作为MyBatis的增强工具,MyBatis-Plus无需再在xml中写sql语句,在这篇文章中荔枝将梳理MyBatis-Plus的基础知识并基于SpringBoot梳理MyBatis-Plus给出的两个接口:BaseMapper和IServer。希望对有需要的小伙伴有帮助。
文章目录
前言
一、基本概念
1.1 特性
1.2 支持数据库
1.3 结构
二、SpringBoot整合MP简单使用
2.1 基础环境配置
2.2 简单测试
2.3 自定义功能
三、通用Service
3.1 批量添加功能
3.2 常用注解
@TableName
@TableId
@TableField
@TableLogic 逻辑删除
3.3 雪花算法
总结
一、基本概念
MyBatis-PIus简称MP,是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatis-Plus提供了通用的mapper和service,可以在不编写任何SQL语句的情况下,快速的实现对单表的CRUD、批量、逻辑删除、分页等操作。MyBatis-Plus官方是这么描述的:我们的愿景是成为 MyBatis 最好的搭档,就像魂斗罗中的 1P、2P,基友搭配,效率翻倍。说白了,MP只是作为MyBatis开发中的一种增强工具,提高开发效率。
1.1 特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.2 支持数据库
任何能使用MyBatis进行 CRUD, 并且支持标准 SQL 的数据库都可以使用MyBatis-Plus。
1.3 结构
MyBatis-Plus实现功能是从扫描实体类开始,通过反射提取实体类中的属性并分析实体类属性和数据库表中对应字段之间的关系,并根据当前调用的方法生成相对应的SQL语句,再把生成的SQL语句注入到MyBatis容器中。
二、SpringBoot整合MP简单使用
2.1 基础环境配置
pom.xml
这里mysql版本使用是SpringBoot的内置版本,SpringBoot版本这里使用的是3.1.3。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.crj</groupId><artifactId>mybatisplus</artifactId><version>0.0.1-SNAPSHOT</version><name>mybatisplus</name><description>mybatisplus</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--mybatis plus启动器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><!--lombok用于简化实体类开发--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--mysql驱动器--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
配置数据库连接信息,在SpringBoot中一般配置文件是通过application.xml或application.properties来配置数据源信息
application.xml
spring:
# 配置数据源信息datasource:#配置数据源类型type: com.zaxxer.hikari.HikariDataSource#配置连接数据库的各个信息driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&userSSL=falseusername: rootpassword: 123456#配置日志功能
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
这里的mapper-location默认是在resource下的mapper目录下,如果不进行配置就必须按照要求存放mapper配置文件。
2.2 简单测试
UserMapper.java
package com.crj.mybatisplus_test.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.crj.mybatisplus_test.pojo.User;
import org.springframework.stereotype.Repository;@Repository
//继承MyBatis-Plus的BaseMapper接口
public interface UserMapper extends BaseMapper<User> {}
测试类
package com.crj.mybatisplus_test;import com.crj.mybatisplus_test.mapper.UserMapper;
import com.crj.mybatisplus_test.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
public class MyBatisPlusTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelect(){//通过MyBatis提供的一个条件构造器查询一个list集合,若没有条件则可以设置为nullList<User> list = userMapper.selectList(null);list.forEach(System.out::println);}
}
在主入口中开启mapper扫描功能
package com.crj.mybatisplus_test;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
//用来扫描指定包下的mapper接口
@MapperScan("com.crj.mybatisplus_test.mapper")
public class MyBatisPlusTestApplication {public static void main(String[] args) {SpringApplication.run(MyBatisPlusTestApplication.class, args);}}
BaseMapper是MyBati-Plus中提供的一个接口,通过继承该接口得到相应条件构造器,提供了大量操作数据库的方法。
2.3 自定义功能
MyBatis-Plus作为MyBatis的一个增强工具,除了其提供的操作数据库的方法之外,还允许我们自定义SQL操作,即允许我们使用MyBatis的方式来自定义操作数据库。
package com.crj.mybatisplus_test.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.crj.mybatisplus_test.pojo.User;
import org.springframework.stereotype.Repository;import java.util.Map;
import java.util.Objects;@Repository
//继承MyBatis-Plus的BaseMapper接口
public interface UserMapper extends BaseMapper<User> {Map<String, Objects> selectMapById(Long id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.crj.mybatisplus_test.mapper.UserMapper"><!-- Map<String, Objects> selectMapById(Long id);--><select id="selectMapById" resultType="map">select * from user where id = #{id}</select>
</mapper>
package com.crj.mybatisplus_test;import com.crj.mybatisplus_test.mapper.UserMapper;
import com.crj.mybatisplus_test.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;
import java.util.Map;
import java.util.Objects;@SpringBootTest
public class MyBatisPlusTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testSelect(){Map<String, Objects> map = userMapper.selectMapById(1L);System.out.println(map);}
}
三、通用Service
3.1 批量添加功能
前面我们通过继承BaseMapper接口来使用MyBatis-Plus进而操作数据,但是我们查看insert会发现没有批量添加的功能,对此其实MyBatis-Plus提供了另一个API接口给我们使用 —— IService。通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行、remove 删除、list 查询集合、page 分页,前缀命名方式区分 Mapper 层避免混淆。
继承IService接口
package com.crj.mybatisplus_test.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.crj.mybatisplus_test.pojo.User;
import org.springframework.stereotype.Service;@Service
public interface UserService extends IService<User> {}
自定义接口实现
package com.crj.mybatisplus_test.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crj.mybatisplus_test.mapper.UserMapper;
import com.crj.mybatisplus_test.pojo.User;
import com.crj.mybatisplus_test.service.UserService;public class UserServerImpl extends ServiceImpl<UserMapper, User> implements UserService {}
测试类
package com.crj.mybatisplus_test;import com.crj.mybatisplus_test.pojo.User;
import com.crj.mybatisplus_test.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;
import java.util.List;@SpringBootTest
public class MyBatisPlusServiceTest {@Autowiredprivate UserService userService;@Testpublic void testInsertAll(){List<User> list = new ArrayList<>();for (int i = 1;i<10;i++){User user = new User();user.setName("lzddl"+i);list.add(user);}userService.saveBatch(list);}
}
3.2 常用注解
@TableName
当实体类和数据库表中的表名不一致时,可以通过该注解来指定该实体类映射的数据库表的名字
package com.crj.mybatisplus_test.pojo;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;//使用Lombok简化开发加上无参构造方法、有参构造@Data
@TableName("t_user")
public class User {private Long id;private String name;private String age;private String email;
}
当然了,解决该需求还可以通过全局配置的方式来实现,table-prefix可以用来设置实体类所对应表的统一前缀。
#配置日志功能
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:table-prefix: t_
@TableId
该注解可以将属性所对应的字段设置为主键,从而在MyBatis-Plus中默认使用雪花算法来自动生成赋值。
value属性
而当属性名和字段名无法对应,我们应该在TableId中通过设置value属性值来添加映射关系。比如当数据表中的字段是uid,而属性设置为id时,我们就可以借助该注解来实现映射关系。
@TableId("uid")
private Long id;
type属性
@TableId(value = "uid",type = IdType.AUTO)
private Long id;
属性值(主键生成策略):
- AUTO:主键自动递增,前提是数据库中的字段必须设置为自增;
- ASSIGN_ID:默认值,使用的是MyBatis-Plus内置的雪花算法
主键生成策略的全局配置
@TableField
@TableField可以用来指定属性所对应的字段名,和@TableId的区别是@TableId指定的是和属性名不一致主键字段,而@TableField指定的是与实体类属性名不一致的普通字段。
@TableLogic 逻辑删除
- 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据。
- 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍引旧能看到此条数据记录
- 使用场景:可以进行数据恢复
@TableLogic
private Integer isDeleted;
当使用了逻辑删除之后,不会直接删除,而是变成一个修改的操作,将当前注解的字段由0变成1,标记的是删除状态。
3.3 雪花算法
雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性,比较适合用在分布式架构里面。
核心思想:
- 长度共64bit(一个long型)。
- 首先是一个符号位,1bit标识,由于刊ong基本类型在va中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。
- 41bit时间截(毫秒级),存储的是时间截的差值(当前时间截-开始时间截),结果约等于69.73年。
- 10bit作为机器的1D(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。
- 12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID)。
优点:
整体上按照时间自增排序,在整个分布式系统中不会产生ID碰撞。
总结
简单了解了MyBatis-Plus的两个接口和基本环境搭建和使用,在接下来的文章中荔枝将会继续梳理有关接口和条件构造器的内容,继续输出~~~
今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,麻烦举起小爪爪点个赞吧哈哈哈~~~ 比心心♥~~~
相关文章:

MyBatis-Plus —— 初窥门径
前言 在前面的文章中荔枝梳理了MyBatis及相关的操作,作为MyBatis的增强工具,MyBatis-Plus无需再在xml中写sql语句,在这篇文章中荔枝将梳理MyBatis-Plus的基础知识并基于SpringBoot梳理MyBatis-Plus给出的两个接口:BaseMapper和ISe…...

音频——I2S 标准模式(二)
I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 I2S format时序图逻辑分析仪抓包 I2S format 飞利浦 (I2S) 标准模式 数据在跟随 LRCLK 传输的 BCLK 的第二个上升沿时传输 MSB,其他位一直到 LSB 按顺序传传输依…...

Python语音识别处理详解
概要 人们对智能语音助手的需求不断提高,语音识别技术也随之迅速发展。在这篇文章中,我们将介绍如何使用Python的SpeechRecognition和pydub等库来实现语音识别和处理,从而打造属于自己的智能语音助手。 1. 什么是语音识别? 语音…...

【小吉送书—第一期】Kali Linux高级渗透测试
文章目录 🍔前言🛸读者对象🎈本书资源🎄彩蛋 🍔前言 对于企业网络安全建设工作的质量保障,业界普遍遵循PDCA(计划(Plan)、实施(Do)、检查&#x…...

服务器允许ssh登录root
用vim打开/etc/ssh/sshd_config sudo vim /etc/ssh/sshd_config将sshd_config中的PermitRootLogin属性改为yes ... PermitRootLogin yes ...重启sshd服务 sudo service sshd restart...

【微服务部署】三、Jenkins+Maven插件Jib一键打包部署SpringBoot应用Docker镜像步骤详解
前面我们介绍了K8SDockerMaven插件打包部署SpringCloud微服务项目,在实际应用过程中,很多项目没有用到K8S和微服务,但是用到了Docker和SpringBoot,所以,我们这边介绍,如果使用Jenkinsjib-maven-plugin插件打…...

Ansible学习笔记9
yum_repository模块: yum_repository模块用于配置yum仓库的。 测试下: [rootlocalhost ~]# ansible group1 -m yum_repository -a "namelocal descriptionlocalyum baseurlfile:///mnt/ enabledyes gpgcheckno" 192.168.17.106 | CHANGED &g…...

Ubuntu22.04安装Mongodb7.0
Ubuntu安装Mongodb 1.平台支持2.安装MongoDB社区版2.1导入包管理系统使用的公钥2.2为MongoDB创建列表文件2.3重新加载本地包数据库2.4安装MongoDB包1.安装最新版MongoDB2.安装指定版MongoDB 3.运行MongoDB社区版1.目录2.配置文件3.初始化系统4.启动MongoDB5.验证MongoDB是否成功…...

Oracle中序列删除的正确语句(oracle删除序列语句)
Oracle中序列删除的正确语句 Oracle 是由世界上最大的软件公司 Oracle Corporation 提供的关系型数据库管理系统,拥有广泛的应用和功能,如存储过程、触发器、视图、序列以及其他的复杂的特性,能够满足丰富的业务需求。本文主要研究Oracle中序…...

ChatGPT AI在线免费体验
🤖 与ChatGPT亲密接触 🤖 ChatGPT!它就是一款强大的聊天型人工智能模型,可以与你进行各种有趣的对话,就像我们在这里一样。不论你想聊天、提问、寻求建议,还是只是想找个伙伴一起闲聊,ChatGPT都…...

CSS中如何实现文字渐变色效果(Text Gradient Color)?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 文字渐变色效果(Text Gradient Color)⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这…...

尚硅谷SpringMVC (1-4)
一、SpringMVC简介 1、什么是MVC MVC 是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M : Model ,模型层,指工程中的 JavaBean ,作用是处理数据 JavaBean 分为两类: 一类称为实体类Bean&am…...

独家首发!openEuler 主线集成 LuaJIT RISC-V JIT 技术
RISC-V SIG 预期随主线发布的 openEuler 23.09 创新版本会集成 LuaJIT RISC-V 支持。本次发版将提供带有完整 LuaJIT 支持的 RISC-V 环境并带有相关软件如 openResty 等软件的支持。 随着 RISC-V SIG 主线推动工作的进展,LuaJIT 和相关软件在 RISC-V 架构下的支持也…...

在Mac 上安装flutter 遇到的问题
准备工作 1、升级Macos系统为最新系统 2、安装最新的Xcode 3、电脑上面需要安装brew https://brew.sh/ 4、安装chrome浏览器(开发web用) 下载Flutter、配置Flutter环境变量、配置Flutter镜像 下载Flutter SDK https://docs.flutter.dev/release/archive?tabmacos 根据自己…...

一个月能做什么?成长感悟分享
一个月做了什么? 八月做了些什么? 单词打卡 第一件事情就是单词打卡 英语很差的我,一样继续打卡,今天是第736天 当你还在纠结扇贝和不背、可可英语哪一个好的时候,别人已经同时使用了 当你还在咨询学编程、敲代码需…...

网络编程
1. 网络编程入门 1.1 网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统…...

ip route get ip地址 应用案例
应用场景 在做虚拟化实验用的虚拟机和实际的ECS云主机一般都会有多个网卡,网络的联通性是经常碰到的问题。比如在一个VM上有3个网卡,分别为ens160(和寄主机进行桥接的网卡10.0.0.128)、ens224(连接仅主机网络10.0.0.0/24的网卡10.0.0.128&…...

Windows下Redis的安装和配置
文章目录 一,Redis介绍二,Redis下载三,Redis安装-解压四,Redis配置五,Redis启动和关闭(通过terminal操作)六,Redis连接七,Redis使用 一,Redis介绍 远程字典服务,一个开源的,键值对形式的在线服务框架,值支持多数据结构,本文介绍windows下Redis的安装,配置相关,官网默认下载的是…...

【sgTransfer】自定义组件:带有翻页、页码、分页器的穿梭框组件,支持大批量数据的穿梭显示。
特性: 表格宽度可以自定义翻页器显示控件可以自定义列配置项可以设置显示字段列名称、宽度、字段名可以配置搜索框提示文本,支持搜索过滤穿梭框顶部标题可以自定义左右箭头按钮文本可以设置 sgTransfer源码 <template><div :class"$opti…...

分布式爬虫与SOCKS5代理池的组合优势
在数据驱动的时代,网络爬虫成为了获取大量信息的重要工具。然而,随着网站反爬策略的升级,传统的单机爬虫面临着速度慢、易被封禁等问题。为了应对这些挑战,我们可以尝试将分布式爬虫与SOCKS5代理池相结合,提高爬虫的性…...

京东获得JD商品详情 API 接口文档(含请求代码)
item_get-获得JD商品详情 API测试工具 注册开通 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_sea…...

linux开启端口
目录 1.查看防火墙状态 1.1 开启防火墙 1.2 再次查看防火墙状态 2.开启指定端口 3. 重启防火墙 4.重新加载防火墙 5.查看已经开启的端口 1.查看防火墙状态 firewall-cmd --state 如果返回的是 not running,那么需要先开启防火墙, 1.1 开启防火…...

聚合多个电商API接口平台
API接口测试(点击免费测试) 随着数字化商业时代的到来,API接口已成为电商资源连接利器,也是全球传统互联网企业转型的基础。 2021年 Google Cloud 研究显示,全球互联网企业近3/4的企业持续投入数字化转型,…...

4.2 实现基于栈的表达式求值计算器(难度4/10)
本作业主要考察:解释器模式的实现思想/栈结构在表达式求值方面的绝对优势 C数据结构与算法夯实基础作业列表 通过栈的应用,理解特定领域设计的关键作用,给大家眼前一亮的感觉。深刻理解计算机语言和人类语言完美结合的杰作。是作业中的上等…...

持续性能优化:确保应用保持高性能
在当今数字化时代,应用程序的性能已经成为用户体验和业务成功的关键因素之一。无论是Web应用、移动应用还是企业级软件,用户对于速度和响应性的要求越来越高。因此,持续性能优化已经成为保证应用在竞争激烈的市场中脱颖而出的重要策略。 什么…...

Jupyter installation Tutorial
文章目录 1. 面向的系统2. 什么是Jupyter?3. 安装Python环境4. 安装Jupyter notebook5. Jupyter的启动和配置6. Jupyter的使用技巧7. conclusion参考文献 1. 面向的系统 Windows安装 2. 什么是Jupyter? Jupyter Notebook是一个开源的Web应用程序&…...

css-定位position 理论
1.1网页常见布局方式 1.标准流 1.块级元素独占一行直布局 2.行内元素/行内块元素一行显示多个 ------>水平布局 2.浮动 1. 可以让原本垂直布局的 块级元素变成水平布局 3.定位 1. 可以让元素自由的摆放在网页的任意位置 2. 一般用于 盒子之间的层叠情况 1.2使用定位的步骤…...

软件测试规范
1、概述 本规范是对项目软件测试的一份指导性文件,对软件测试过程中所涉及到的测试理论、测试类型、测试方法、测试标准、测试流程以及软件产品开发单位所承担的职责进行总体规范,以有效保证软件产品的质量。 2、测试目的 测试的目的就是在软件交付前…...

Volatile 关键字提供的可见性
/*** 类说明:演示Volatile的提供的可见性*/ public class VolatileCase {// 说明:当ready没有volatile修饰时,执行结果是PrintThread线程一直处于被挂起状态,子线程感知不到主线程中的变量// 当ready被volatile修饰时,…...

Vue学习(三)
一、列表渲染 v-for指令 用于展示列表数据 语法<li v-for"(item, index) in items" :key"index"></li>key可以是index,最好是遍历对象的唯一标识 可遍历:数组、对象 <!DOCTYPE html> <html lang"en">&l…...