mybatis05_对应关系

一、一对一关系

以身份证和人为例

1、resultType实现

​ 使用resultType实现,将所需要的属性放到一个实体类中。

⬇️创建数据表

copy
CREATE TABLE `id_card` ( `id` int NOT NULL AUTO_INCREMENT, `card_num` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `person_id` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `person` ( `id` int NOT NULL AUTO_INCREMENT, `person_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

⬇️实体类 Person

copy
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class Person { private Integer id; private String personName; }

⬇️实体类 IdCard 继承自 Person 使 IdCard 中可以获得 Person中的对象信息;重写 toString 调用父类Person的方法获得 personName。

copy
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class IdCard extends Person{ private Integer id; private String cardNum; @Override public String toString() { return "IdCard{" + "cardNum='" + cardNum + '\'' + "personName=" + super.getPersonName() + '}'; } }

⬇️mapper映射

copy
<select id="list" resultType="com.ls.pojo.IdCard"> select card_num cardNum,person_name personName from id_card join person on id_card.id = person.id </select>

⬇️测试

copy
private static void testList() { SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); IdCardMapper idCardMapper = sqlSession.getMapper(IdCardMapper.class); List<IdCard> cardList = idCardMapper.list(); cardList.stream().forEach(System.out::println); } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) {sqlSession.close();} } }

⬇️编译后的sql语句和结果

image-20230316100004281

2、resultMap实现

​ 使用 resultType 实现的方式,无非就是将要获取的信息数据字段,都对应到一个扩展 Bean 中,同时还要保持字段名与列名保持一致。这里我们让 IdCardExtends 来获得 IdCard2 的信息(继承),并重写 IdCard 的 toString方法让其能够表现出父类(super)的属性。

copy
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class IdCard2 { private Integer id; private String cardNum; } import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class IdCardExtends extends IdCard2{ Person person; @Override public String toString() { return "IdCardExtends{" + "person=" + person + "super:"+super.toString()+ '}'; } }

⬇️定义 resultMap 和 sql 语句

​ 注意指明是哪张表的 id 不然会有Column 'id' in field list is ambiguous。(顺便问一句万能的网友为什么把这个 id_card.id 属性列去掉筛选出来的就全是 null 呢)

使用 association 映射关联查询单个对象的信息

​ property 属性:要将关联查询的对象信息映射到 person 对象的哪个属性上

​ javaType 属性:要将关联查询的对象信息映射成哪种 Java 类

copy
<resultMap id="IdCardMap" type="com.ls.pojo.IdCardExtends"> <id property="id" column="id"></id> <result property="cardNum" column="card_num"></result> <association property="person" javaType="com.ls.pojo.Person"> <id column="id" property="id"></id> <result column="person_name" property="personName"></result> </association> </resultMap> <select id="list2" resultMap="IdCardMap"> select id_card.id,card_num cardNum, person_name personName from id_card join person on id_card.id = person.id </select>

⬇️测试程序

copy
private static void testList2() { SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); IdCardMapper idCardMapper = sqlSession.getMapper(IdCardMapper.class); List<IdCardExtends> cardListExtends = idCardMapper.list2(); cardListExtends.stream().forEach(System.out::println); } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) {sqlSession.close();} } }

⬇️

image-20230316155422413

二、一对多关系

​ 以部门与员工之间的关系为例

​ 如果不使用框架进行一对多的联合查询则需要:先调用 dao 层查询部门表,然后再根据部门表与员工表的主外键关联字段,再调用员工表的 dao 再查询员工表数据,最终完成数据组装。

⬇️使用到的数据库如下

copy
CREATE TABLE `emp` ( `emp_id` bigint NOT NULL AUTO_INCREMENT, `emp_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `email` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, `dept_id` bigint DEFAULT NULL, PRIMARY KEY (`emp_id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; CREATE TABLE `dept` ( `dept_id` bigint NOT NULL AUTO_INCREMENT, `dept_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, `location` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`dept_id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

⬇️实体类有部门和员工两个,其中部门中应有一个List的员工列表作为其属性

copy
import lombok.Data; import lombok.experimental.Accessors; import java.util.List; @Data @Accessors(chain = true) public class Dept { private Long deptId; private String deptName; private String location; //一个部门多个员工 private List<Emp> empList; }
copy
import lombok.Data; import lombok.experimental.Accessors; import java.util.Date; @Data @Accessors(chain = true) public class Emp { private Long empId; private String empName; private String address; private String email; private Date createTime; private Date updateTime; private Long deptId; }

⬇️mapper映射文件,配置关联查询 Orders 信息的映射,使用 collection 映射关联查询多个对象的信息

​ property 属性:要将关联查询的对象信息映射到 ordersUser 对象的哪个属性上

​ ofType 属性:要将关联查询的对象信息映射成哪种 Java 类

copy
import com.ls.pojo.Dept; import com.ls.pojo.Emp; import java.util.List; public interface DeptMapper { /** * 根据部门id查部门的信息 * 包括部门的员工的信息 * @param deptId * @return */ List<Dept> findById(Long deptId); }
copy
<resultMap id="DeptMap" type="com.ls.pojo.Dept"> <id property="deptId" column="dept_id"></id> <result property="deptName" column="dept_name"></result> <result property="location" column="location"></result> <collection property="empList" ofType="com.ls.pojo.Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="address" property="address"></result> <result column="create_tiem" property="createTime"></result> <result column="update_time" property="updateTime"></result> </collection> </resultMap> <select id="findById" resultMap="DeptMap"> select emp.*,dept.* from dept join emp on dept.dept_id = emp.dept_id where dept.dept_id = #{deptId} </select>

⬇️测试

​ 这里以根据 id 查询部门信息为例,部门信息中应该包含所有员工的信息

copy
private static void testFindById() { SqlSession sqlSession = null; try { sqlSession = MybatisUtil.getSqlSession(); DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class); List<Dept> deptList = deptMapper.findById(1L); deptList.stream().forEach(System.out::println); } catch (Exception e) { e.printStackTrace(); } finally { if (sqlSession != null) {sqlSession.close();} } }

⬇️测试结果

image-20230321191548885

三、多对多关系

​ 暂时略,毕竟联合查询降低性能,日后面试题补上。

posted @   Purearc  阅读(37)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
🚀