F005MyBatis学习笔记-MyBatis的多表关联查询
一、 概述
1、一对一
举例:身份证号对人,一个身份证好只能对应一个人,一个人也只能对应一个身份证号,这就是一对一;
特例:Mybatis将多对一看做是一对一;
2、多对多
举例:学生对老师,一个老师可以教多个学生,一个学生也可以被多个老师教,这就是多对多;
二、一对多案例演示
1、需求
用户和账户:
一个用户可以有多个账户;
一个账户只能属于一个用户(多个账户也可以属于同一个用户);
2、步骤
第一步:建立两张表:用户表、账户表;
让用户表和账户表之间具备一对多的关系,需要在账户表中添加外键;
第二步:建立两个实体类:用户实体类和账户实体类;
让用户和账户的实体类体现出一对多的关系;
第三步:建立两个配置文件:用户的配置文件、账户的配置文件;
第四步:实现配置:当我们查询用户时,可以同时得到用户下所包含账户的信息;当我们查询账户时,可以得到账户所属用户的信息;
3、一对多代码演示
SQL语句:
CREATE TABLE `account` (`ID` int(11) NOT NULL COMMENT '编号',`UID` int(11) default NULL COMMENT '用户编号',`MONEY` double default NULL COMMENT '金额',PRIMARY KEY (`ID`),KEY `FK_Reference_8` (`UID`),CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `account`(`ID`,`UID`,`MONEY`) values (1,46,1000),(2,45,1000),(3,46,2000);
pom.xml:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mybatis0203</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.3</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13-beta-3</version><scope>test</scope></dependency></dependencies></project>
IAccountDao:
package com.zibo.mybatis_crud.dao;import com.zibo.mybatis_crud.domain.Account;
import com.zibo.mybatis_crud.domain.AccountUser;import java.util.List;public interface IAccountDao {//查询所有账户List<Account> findAll();//查询所有账户带user的用户名和地址信息List<AccountUser> findAllAccount();
}
IUserDao:
package com.zibo.mybatis_crud.dao;import com.zibo.mybatis_crud.domain.User;import java.util.List;public interface IUserDao {//查询所有,同时获取到用户所有的账户信息List<User> findAll();//根据id查询一条数据User findById(Integer userId);
}
Account:
package com.zibo.mybatis_crud.domain;public class Account {private Integer id;private Integer uid;private double money;private User user;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}public double getMoney() {return money;}public void setMoney(double money) {this.money = money;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Overridepublic String toString() {return "Account{" +"id=" + id +", uid=" + uid +", money=" + money +'}';}
}
AccountUser:
package com.zibo.mybatis_crud.domain;public class AccountUser extends Account {private String username;private String address;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return super.toString() + " AccountUser{" +"username='" + username + '\'' +", address='" + address + '\'' +'}';}
}
User:
package com.zibo.mybatis_crud.domain;import java.io.Serializable;
import java.util.Date;
import java.util.List;public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;//一对多关系映射:主表实体应该包含从表实体的集合引用private List<Account> accounts;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public List<Account> getAccounts() {return accounts;}public void setAccounts(List<Account> accounts) {this.accounts = accounts;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}
}
IAccountDao.xml:
<?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.zibo.mybatis_crud.dao.IAccountDao"><!-- 定义封装account和user的resultMap--><resultMap id="accountUserMap" type="account"><id property="id" column="aid"/><result property="uid" column="uid"/><result property="money" column="money"/><!-- 一对一关系映射,配置封装user的内容--><association property="user" column="uid" javaType="user"><id property="id" column="id"/><result property="username" column="username"/><result property="address" column="address"/><result property="sex" column="sex"/><result property="birthday" column="birthday"/></association></resultMap><!--配置查询所有--><select id="findAll" resultMap="accountUserMap">select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id = a.uid;</select><!--查询一条数据--><select id="findAllAccount" resultType="accountUser">select a.*,u.username,u.address from account a,user u where u.id = a.uid;</select>
</mapper>
IUserDao.xml:
<?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.zibo.mybatis_crud.dao.IUserDao"><!-- 定义User的resultMap--><resultMap id="userAccountMap" type="user"><id property="id" column="id"/><result property="username" column="username"/><result property="address" column="address"/><result property="sex" column="sex"/><result property="birthday" column="birthday"/><!-- 配置user对象中accounts集合的映射 --><collection property="accounts" ofType="account"><id column="aid" property="id"/><result column="uid" property="uid"/><result column="money" property="money"/></collection></resultMap><!-- 查询所有 --><select id="findAll" resultMap="userAccountMap">select * from user u left outer join account a on u.id = a.uid</select><!--查询一条数据--><select id="findById" parameterType="Integer" resultType="user">select * from user where id = #{随便写};</select>
</mapper>
log4j.properties:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
SqlMapConfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 在 SqlMapConfig.xml 中配置: --><typeAliases><!-- 单个别名定义 -->
<!-- <typeAlias alias="user" type="com.itheima.domain.User"/>--><!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) --><package name="com.zibo.mybatis_crud.domain"/></typeAliases><!-- 配置环境--><environments default="mysql">
<!-- mysql的配置--><environment id="mysql">
<!-- 配置事务的类型--><transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池)--><dataSource type="POOLED">
<!-- 配置数据库的4个基本信息--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/zibo?serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="zibo15239417242"/></dataSource></environment></environments>
<!-- 指定映射配置文件的位置--><mappers>
<!-- <mapper resource="com/zibo/mybatis_crud/dao/IUserDao.xml"/>-->
<!-- 注册指定包下的所有 mapper 接口--><package name="com.zibo.mybatis_crud.dao"/></mappers>
</configuration>
Main:
package com.zibo.mybatis_crud;import com.zibo.mybatis_crud.dao.IAccountDao;
import com.zibo.mybatis_crud.dao.IUserDao;
import com.zibo.mybatis_crud.domain.Account;
import com.zibo.mybatis_crud.domain.AccountUser;
import com.zibo.mybatis_crud.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class Main {private InputStream in;private SqlSession sqlSession;private IUserDao iUserDao;private IAccountDao iAccountDao;/*** 初始化*/@Beforepublic void init() throws IOException {//1、读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2、创建SqlSessionFactory工厂SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(in);//3、通过SqlSessionFactory工厂生产SqlSession对象sqlSession = factory.openSession(true);//4、使用SqlSession创建Dao接口的代理对象iUserDao = sqlSession.getMapper(IUserDao.class);iAccountDao = sqlSession.getMapper(IAccountDao.class);}@Afterpublic void end() throws IOException {//6、释放资源sqlSession.close();in.close();}/*** 测试查询所有*/@Testpublic void testFindAll(){//5、使用代理对象执行方法List<User> users = iUserDao.findAll();for (User user : users) {System.out.println(user);System.out.println(user.getAccounts());}}@Testpublic void testFindById(){//5、使用代理对象执行方法User user = iUserDao.findById(45);System.out.println(user);}@Testpublic void testFindAll_A(){//5、使用代理对象执行方法List<Account> accounts = iAccountDao.findAll();for (Account account : accounts) {System.out.println(account);System.out.println(account.getUser());}}@Testpublic void testFindAllAccount_A(){//5、使用代理对象执行方法List<AccountUser> accounts = iAccountDao.findAllAccount();for (AccountUser account : accounts) {System.out.println(account);}}
}
文件位置结构图:
三、多对多案例演示
1、需求
示例:用户和角色
一个用户可以有多个角色;
一个角色可以赋予多个用户;
2、步骤
第一步:建立两张表:用户表、角色表;
让用户表和角色表具有多对多的关系,需要使用中间表,中间表中包含各自的主键,在中间表中是外键;
第二步:建立两个实体类:用户实体类和角色实体类;
让用户和角色的实体类体现出多对多的关系;
各自包含对方一个集合;
第三步:建立两个配置文件:用户的配置文件、角色的配置文件;
第四步:实现配置:当我们查询用户时,可以同时得到用户下所包含角色的信息;当我们查询角色时,可以得到账户所属用户的信息;
3、代码演示
SQL:
CREATE TABLE `user` (`id` int(11) NOT NULL auto_increment,`username` varchar(32) NOT NULL COMMENT '用户名称',`birthday` datetime default NULL COMMENT '生日',`sex` char(1) default NULL COMMENT '性别',`address` varchar(256) default NULL COMMENT '地址',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');CREATE TABLE `role` (`ID` int(11) NOT NULL COMMENT '编号',`ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',`ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');CREATE TABLE `user_role` (`UID` int(11) NOT NULL COMMENT '用户编号',`RID` int(11) NOT NULL COMMENT '角色编号',PRIMARY KEY (`UID`,`RID`),KEY `FK_Reference_10` (`RID`),CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
IRoleDao:
package com.zibo.mybatis_crud.dao;import com.zibo.mybatis_crud.domain.Role;import java.util.List;public interface IRoleDao {//查询所有,同时获取到角色所有的用户信息List<Role> findAll();
}
IUserDao:
package com.zibo.mybatis_crud.dao;import com.zibo.mybatis_crud.domain.User;import java.util.List;public interface IUserDao {//查询所有,同时获取到用户所有的角色信息List<User> findAll();
}
Role:
package com.zibo.mybatis_crud.domain;import java.io.Serializable;
import java.util.List;public class Role implements Serializable {private Integer roleId;private String roleName;private String roleDesc;//多对多关系映射private List<User> users;public Integer getRoleId() {return roleId;}public void setRoleId(Integer roleId) {this.roleId = roleId;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}public String getRoleDesc() {return roleDesc;}public void setRoleDesc(String roleDesc) {this.roleDesc = roleDesc;}public List<User> getUsers() {return users;}public void setUsers(List<User> users) {this.users = users;}@Overridepublic String toString() {return "Role{" +"roleId=" + roleId +", roleName='" + roleName + '\'' +", roleDesc='" + roleDesc + '\'' +'}';}
}
User:
package com.zibo.mybatis_crud.domain;import java.io.Serializable;
import java.util.Date;
import java.util.List;public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;//多对多private List<Role> roles;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public List<Role> getRoles() {return roles;}public void setRoles(List<Role> roles) {this.roles = roles;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}}
IRoleDao.xml:
<?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.zibo.mybatis_crud.dao.IRoleDao"><!-- 定义User的resultMap--><resultMap id="RoleMap" type="role"><id property="roleId" column="rid"/><result property="roleName" column="role_name"/><result property="roleDesc" column="role_desc"/><collection property="users" ofType="user"><id property="id" column="id"/><result property="username" column="username"/><result property="address" column="address"/><result property="sex" column="sex"/><result property="birthday" column="birthday"/></collection></resultMap><!-- 查询所有 --><select id="findAll" resultMap="RoleMap">select u.*,r.id as rid,r.role_name,r.role_desc from role rleft outer join user_role ur on r.ID = ur.ridleft outer join user u on u.id = ur.uid;</select>
</mapper>
IUserDao.xml:
<?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.zibo.mybatis_crud.dao.IUserDao"><!-- 定义User的resultMap--><resultMap id="userMap" type="user"><id property="id" column="id"/><result property="username" column="username"/><result property="address" column="address"/><result property="sex" column="sex"/><result property="birthday" column="birthday"/><!-- 配置user对象中accounts集合的映射 --><collection property="roles" ofType="role"><id property="roleId" column="rid"/><result property="roleName" column="role_name"/><result property="roleDesc" column="role_desc"/></collection></resultMap><!-- 查询所有 --><select id="findAll" resultMap="userMap">select u.*,r.id as rid,r.role_name,r.role_desc from user uleft outer join user_role ur on u.id = ur.UIDleft outer join role r on ur.RID = r.ID;</select>
</mapper>
Main:
package com.zibo.mybatis_crud;import com.zibo.mybatis_crud.dao.IRoleDao;
import com.zibo.mybatis_crud.dao.IUserDao;
import com.zibo.mybatis_crud.domain.Role;
import com.zibo.mybatis_crud.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class Main {private InputStream in;private SqlSession sqlSession;private IUserDao iUserDao;private IRoleDao iRoleDao;/*** 初始化*/@Beforepublic void init() throws IOException {//1、读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");//2、创建SqlSessionFactory工厂SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(in);//3、通过SqlSessionFactory工厂生产SqlSession对象sqlSession = factory.openSession(true);//4、使用SqlSession创建Dao接口的代理对象iUserDao = sqlSession.getMapper(IUserDao.class);iRoleDao = sqlSession.getMapper(IRoleDao.class);}@Afterpublic void end() throws IOException {//6、释放资源sqlSession.close();in.close();}/*** 测试查询所有*/@Testpublic void testFindAll(){//5、使用代理对象执行方法List<User> users = iUserDao.findAll();for (User user : users) {System.out.println(user);System.out.println(user.getRoles());}}@Testpublic void testFindAll_R(){//5、使用代理对象执行方法List<Role> roles = iRoleDao.findAll();for (Role role : roles) {System.out.println(role);System.out.println(role.getUsers());}}
}
其他配置文件等,见一对多代码演示;
F005MyBatis学习笔记-MyBatis的多表关联查询相关推荐
- MyBatis实现中间表关联查询
MyBatis实现中间表关联查询 通常构建数据多对多模型的关系时,我们需要再建立一张中间表来关联另外两张表. 下面介绍一下,怎么用MyBatis来实现中间表关联查询并封装到实体类对象中. 现在有三张表 ...
- Mybatis的多表关联查询(多对多)
Mybatis的多表关联查询(多对多) 项目目录结构 实现 Role 到 User 多对多 业务要求 用户与角色的关系模型 编写角色实体类 编写 Role 持久层接口 实现的 SQL 语句 编写映射文 ...
- asp多表查询并显示_SpringBoot系列(五):SpringBoot整合Mybatis实现多表关联查询
本文我们将继续分享介绍Spring Boot在整合Mybatis开发企业级应用时其他典型的业务场景,即Mybatis是如何实现多表关联查询时将查询结果集与对象进行映射的,主要的内容包含"一对 ...
- SQLServer学习笔记八:多表连接查询
学习目标 掌握多表连接查询的概念 学会使用内连接查询数据 学会使用外连接查询数据 学会使用UNION合并查询结果 前面学习的内容都是基于单个数据库表的查询,下面将学习涉及多个表的数据查询. 多表连接查 ...
- mybatis学习五-mybatis的多表联合查询
1. 一对一的关系 首先先看数据库 tb_user tb_orders 执行这条sql: 也就是查询所有的订单, 并每一个订单都联系上用户数据, 并再一次附上订单的id 也就是说, 从后面看, 就是每 ...
- MyBatis之两表关联查询
1. 数据库表 学生表: 教师表: 2. 需求 要求查询所有教师的信息, 包括他的学生信息. 查询结果样式: 3. 代码 实体类 pojo包下: Student.java package com.xx ...
- 《SQL高级应用和数据仓库基础(MySQL版)》学习笔记 ·009【多表连接查询】
文章目录 一.多表连接 1.应用场景 2.等值连接 3.非等值连接 4.自连接 5.标准连接 (1).交叉连接 (2).自然连接 (3).using子句连接 (4).on子句连接 (5).外连接 二. ...
- 【EF学习笔记07】----------加载关联表的数据 贪婪加载
[EF学习笔记07]----------加载关联表的数据 贪婪加载 讲解之前,先来看一下我们的数据库结构:班级表 学生表 贪婪加载 //贪婪加载 using (var db = new Entitie ...
- (探讨)MyBatis中的N+1问题,多表关联查询效率高点还是多次单表查询效率高
MySQL多表关联查询效率高点还是多次单表查询效率高,为什么? https://blog.csdn.net/weixin_33869377/article/details/86265527 MyBat ...
最新文章
- Vue 组件库 heyui@1.18.0 发布,新增地址选择、图片预览组件
- Oracle 10g与安装Perl环境时的冲突以及解决方法
- shaderlab学习一
- python小游戏源码-python21点小游戏源码免费下载
- codevs 1958 刺激
- windows批量创建用户
- java 问题排查_JAVA问题排查笔记
- 字符串处理(POJ1782)
- CPNDet:Corner Proposal Network for Anchor-free, Two-stage Object Detection
- MySQL 5.5 主从复制异步、半同步以及注意事项详解
- unity3d自动寻路教程
- Linux打印cups API及代码范例链接
- linux终端黑客帝国代码雨效果
- VMware安装和卸载时出现无法访问你试图使用的功能所在的网络位置该怎么办(Windows Installer CleanUp)
- 电脑快捷方式图标变白解决方案
- Linux设置root权限
- 解决联想小新笔记本电脑触摸板失灵
- 批处理使用WinRAR压缩某类型的文件,一个文件压缩成一个压缩包,压缩后名称与原文件同名,压缩后删除原文件
- 报错:<ly-tab> - did you register the component correctly? For recursive components, make sure to provi
- 2019.4.3个人赛