09【MyBatis多表关联查询】(1)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp {
private Integer id;
private String name;
private Integer age;
private String addr;
private Double salary;

// 一个员工属于一个部门
private Dept dept;

}


Dept实体类:



package com.dfbz.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* @author lscl
* @version 1.0
* @intro:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
private Integer id;
private String name;
private String location;

// 一个部门下有多个员工
private List<Emp> empList;

}


#### 3.2.2 需求分析


表关系:


![在这里插入图片描述](https://img-blog.csdnimg.cn/e10c361d6ea140be937fb762e59cc9bb.png#pic_center)


我们以前的理解是,部门和员工的关系是一对多,员工和部门的关系是多对一;


但是我们拿出单个员工来说,一个员工只属于一个部门,因此在MyBatis中,多对一的关系简化成了一对一;


案例需求:查询所有**员工信息**,关联查询所属部门信息;在查询过程中,即使有的员工还没有部门也需要查询这个员工的信息,此时在查询过程中,员工表应该是主表;


* 分析SQL语句:



select e.*,d.* from emp e left join dept d on e.dept_id=d.id


#### 3.2.3 dao接口


* EmpDao:



public interface EmpDao {
List findAll();
}


#### 3.2.3 mapper.xml



<?xml version="1.0" encoding="UTF-8"?>
<select id="findAll" resultType="emp">
    select e.*,d.* from emp e left join dept d on e.dept_id=d.id
</select>

#### 3.2.4 测试



package com.dfbz.test;

import com.dfbz.dao.EmpDao;
import com.dfbz.entity.Emp;
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;

/**
* @author lscl
* @version 1.0
* @intro:
*/
public class Demo01 {

private SqlSessionFactory factory;
private SqlSession session;
private EmpDao empDao;

@Before
public void before() throws IOException {
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    factory = builder.build(is);
    session = factory.openSession(true);
    empDao=session.getMapper(EmpDao.class);
}

@After
public void after() throws IOException {
    session.close();
}

@Test
public void test1() {
    List<Emp> empList = empDao.findAll();

    System.out.println(empList);
}

}


![在这里插入图片描述](https://img-blog.csdnimg.cn/9e3331c5ce8c4453bfdc45b88646f66c.png#pic_center)


#### 3.2.5 配置MyBatis一对一关系


* 更改SQL语句:



SELECT
e.id eId,
e.NAME empName,
e.age,
e.addr,
e.salary,
e.dept_id deptId,
d.NAME deptName,
d.location
FROM
emp e
left JOIN dept d ON e.dept_id = d.id


##### 1)传统映射:



<?xml version="1.0" encoding="UTF-8"?>
<resultMap id="empResultMap" type="emp">
    <id column="eId" property="id"></id>
    <result column="empName" property="name"></result>
    <result column="addr" property="addr"></result>
    <result column="salary" property="salary"></result>
    <result column="deptId" property="dept.id"></result>
    <result column="deptName" property="dept.name"></result>
    <result column="location" property="dept.location"></result>
</resultMap>
<select id="findAll" resultMap="empResultMap">
    SELECT
    e.id eId,
    e.NAME empName,
    e.addr,
    e.salary,
    e.dept_id deptId,
    d.name deptName,
    d.location
FROM
    emp e
    LEFT JOIN dept d ON e.dept_id = d.id
</select>

##### 2)使用`association`标签映射



<!--在使用关系映射时,即使查询出来的列明和实体类的属性名一致,也要手动映射-->
<result column="salary" property="salary"></result>
<association property="dept" javaType="com.dfbz.entity.Dept">
    <id column="deptId" property="id"></id>
    <result column="deptName" property="name"></result>
    <!--在使用关系映射时,即使查询出来的列明和实体类的属性名一致,也要手动映射-->
    <result column="location" property="location"></result>
</association>
SELECT e.id eId, e.NAME empName, e.addr, e.salary, d.id deptId, d.name deptName, d.location FROM emp e LEFT JOIN dept d ON e.dept_id = d.id


> 
> Tips:**映射多表关联的结果集时,即使查询出来的列名与属性名一致,也要建立手动映射关系,否则将会导致查询的值无法映射到对应的列;**
> 
> 
> 


### 3.3 一对多查询


#### 3.3.1 需求分析


需求:查询部门信息以及部门下面所属员工信息


分析:部门和员工的信息为一对多关系,并且查询过程中,如果有的部门没有员工,此时也需要将部门信息查询出来,因此在查询中,**部门表应该是主表;**


* 分析SQL语句:



SELECT
e.id eId,
e.NAME empName,
e.addr,
e.salary,
e.dept_id deptId,
d.NAME deptName,
d.location
FROM
emp e
right JOIN dept d ON e.dept_id = d.id


#### 3.3.2 dao接口



List findAll();


#### 3.3.3 mapper.xml



<?xml version="1.0" encoding="UTF-8"?>
<resultMap id="deptResultMap" type="dept">
    <id column="deptId" property="id"></id>
    <result column="deptName" property="name"></result>
    
    <!-- 在使用关系映射时,即使查询出来的列明和实体类的属性名一致,也要手动映射 -->
    <result column="location" property="location"></result>

    <!--

property: Dept对象中的属性
ofType:集合中的泛型类型
–>



        <!-- 在使用关系映射时,即使查询出来的列明和实体类的属性名一致,也要手动映射 -->
        <result column="salary" property="salary"></result>
    </collection>
</resultMap>
<select id="findAll" resultMap="deptResultMap">
    SELECT
        e.id eId,
        e.NAME empName,
        e.addr,
        e.salary,
        e.dept_id deptId,
        d.NAME deptName,
        d.location
    FROM
        emp e
        right JOIN dept d ON e.dept_id = d.id
</select>

#### 3.3.4 测试



@Test
public void test2() {
List deptList = deptDao.findAll();
System.out.println(deptList);
}


### 3.4 多对多关联


#### 3.4.1 需求分析


示例:用户和角色


​ 一个用户可以有多个角色


​ 一个角色可以赋予多个用户


步骤:


​ 1、建立两张表:用户表,角色表让用户表和角色表具有多对多的关系。需要使用中间表,中间表需要外键引用用户表、角色表。


​ 2、建立两个实体类:用户实体类和角色实体类让用户和角色的实体类能体现出来多对多的关系各自包含对方一个集合引用


​ 3、建立两个配置文件用户的配置文件角色的配置文件


​ 4、实现配置:


​ 当我们查询用户时,可以同时得到用户所包含的角色信息


​ 当我们查询角色时,可以同时得到角色的所赋予的用户信息


#### 3.4.2 建立表



DROP TABLE IF EXISTS role;
CREATE TABLE role (
id int(11) NOT NULL,
role\_name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
role\_desc varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE,
INDEX id(id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO role VALUES (1, ‘保洁’, ‘扫地’);
INSERT INTO role VALUES (2, ‘厨师’, ‘做饭’);
INSERT INTO role VALUES (3, ‘保安’, ‘维护治安’);

DROP TABLE IF EXISTS user;
CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
birthday date NULL DEFAULT NULL,
sex varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
address varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO user VALUES (1, ‘张三’, ‘1999-02-04’, ‘男’, ‘佛山’);
INSERT INTO user VALUES (2, ‘李四’, ‘1998-01-15’, ‘女’, ‘湛江’);

DROP TABLE IF EXISTS user\_role;
CREATE TABLE user\_role (
uid int(11) NOT NULL COMMENT ‘用户编号’,
rid int(11) NOT NULL COMMENT ‘角色编号’,
PRIMARY KEY (uid, rid) USING BTREE,
INDEX FK\_Reference\_10(rid) USING BTREE,
CONSTRAINT FK\_Reference\_10 FOREIGN KEY (rid) REFERENCES role (id) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT FK\_Reference\_9 FOREIGN KEY (uid) REFERENCES user (id) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO user\_role VALUES (1, 1);
INSERT INTO user\_role VALUES (2, 1);
INSERT INTO user\_role VALUES (1, 2);
INSERT INTO user\_role VALUES (2, 2);
INSERT INTO user\_role VALUES (2, 3);


#### 3.4.3 实体类


* User:



package com.dfbz.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.List;

/**
* @author lscl
* @version 1.0
* @intro:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;

// 一个用户,有多个角色
private List<Role> roles;

}


* Role:



package com.dfbz.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* @author lscl
* @version 1.0
* @intro:
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
private int roleId;
private String roleName;
private String roleDesc;

// 一个角色,对应多个用户
private List<User> users;

}


#### 3.4.4 dao


* UserDao:



public interface UserDao {
List findAll();
}


* RoleDao:



public interface RoleDao {
List findAll();
}


#### 3.4.5 实现User到Role的多对多


* SQL语句:



SELECT
u.*,
r.id rid,
r.role_name,
r.role_desc
FROM
USER u
LEFT JOIN user_role ur ON u.id = ur.uid
LEFT JOIN role r ON r.id = ur.rid


* mapper.xml:



<?xml version="1.0" encoding="UTF-8"?>
    <id property="id" column="id"></id>
    <result property="username" column="username"></result>
    <result property="birthday" column="birthday"></result>
    <result property="sex" column="sex"></result>
    <result property="address" column="address"></result>

    <collection property="roles" ofType="role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role\_name"></result>
        <result property="roleDesc" column="role\_desc"></result>
    </collection>
</resultMap>

本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。

最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。

最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

学习路线图

其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。

相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。

网络安全工具箱

当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。

项目实战

最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~

面试题

归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值