【MyBatis】3、一文介绍如何用 MyBatis 进行多表级联查询

课程推荐

一、设置新插入记录的主键(id)到参数对象中

<insert id="insert01" parameterType="Student">
    INSERT INTO student (name, money) VALUES (#{name}, #{money})

    <selectKey resultType="long" keyProperty="id" order="AFTER">
        SELECT LAST_INSERT_ID()
    selectKey>
insert>

执行了两条 SQL 语句

 <insert id="insert02"
         useGeneratedKeys="true"
         keyProperty="id"
         parameterType="Student">
     INSERT INTO student (name, money) VALUES (#{name}, #{money})
 insert>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uc1waFQ7-1689741090766)(https://i0.wp.com/img-blog.csdnimg.cn/5ad5fee742d74dffa918158dc42a16d8.png)]

💜 只执行了一条 SQL 语句
💜 该写法需要数据库驱动支持(如:MySQL 支持,而 Oracle 不支持)

二、PageHelper 分页插件

💦 添加 MAVEN 依赖

<dependency>
  <groupId>com.github.pagehelpergroupId>
  <artifactId>pagehelperartifactId>
  <version>5.2.0version>
dependency>

💦 在 mybatis-config.xml 中配置插件

<plugins>

  <plugin interceptor="com.github.pagehelper.PageInterceptor">
    <property name="reasonable" value="true"/>
  plugin>
plugins>

reasonable 设置为 true:
① 当 pageNum <= 0< code> 的时候,会自动获取第一页的数据<br>② 当 <code>pageNum > pages(总页数)</code> 的时候,会自动获取最后一页的数据</=>

public class TestStudent {
	@Test
    public void testPage() {
        try (SqlSession sqlSession = MyBatisUtil.openSession(true)) {
            PageHelper.startPage(1, 5);

            List<Student> list = sqlSession.selectList("student.list");

            for (Student student : list) {
                System.out.println("testPage student: " + student);
            }
        }
    }
}
<mapper namespace="student">
    <sql id="sqlListAll">
        SELECT * FROM student
    sql>

    <resultMap id="resultMapStudent" type="com.pojo.po.Student">
        <id property="id" column="id"/>
        <result property="createTime" column="create_time"/>
    resultMap>
    <select id="list" resultMap="resultMapStudent">
        <include refid="sqlListAll"/>
    select>
mapper>

三、多表关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jyzxl1ch-1689741090767)(https://i0.wp.com/img-blog.csdnimg.cn/731031d0002c487da12b98e9bc4b1b32.png)]
一对多:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KF0vouJ0-1689741090768)(https://i0.wp.com/img-blog.csdnimg.cn/ccfd456b4bb548cc8a9174f5b3dea04f.png)]
一对一:

多对多:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vPa8Knya-1689741090769)(https://i0.wp.com/img-blog.csdnimg.cn/564004396b19449d99c54041d4ad5354.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CsSHe4Z8-1689741090770)(https://i0.wp.com/img-blog.csdnimg.cn/fd94c28d285d473984c4bbe4625cf756.png)]


DROP TABLE IF EXISTS bank_card;
DROP TABLE IF EXISTS id_card;
DROP TABLE IF EXISTS person_job;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS job;

CREATE TABLE person(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20) NOT NULL
);

CREATE TABLE bank_card(
	id INT PRIMARY KEY AUTO_INCREMENT,
	no VARCHAR(30) NOT NULL UNIQUE,
	amout DECIMAL(18, 2) NOT NULL,
	person_id INT NOT NULL,
	FOREIGN KEY (person_id) REFERENCES person(id)
);

CREATE TABLE id_card(
	id INT PRIMARY KEY AUTO_INCREMENT,
	no VARCHAR(30) NOT NULL UNIQUE,
	address VARCHAR(50) NOT NULL,
	person_id INT NOT NULL UNIQUE,
	FOREIGN KEY (person_id) REFERENCES person(id)
);

CREATE TABLE job(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20) NOT NULL UNIQUE,
	duty VARCHAR(50) NOT NULL
);

CREATE TABLE person_job(
	person_id INT,
	job_id INT,
	PRIMARY KEY (person_id, job_id),
	FOREIGN KEY (person_id) REFERENCES person(id),
	FOREIGN KEY (job_id) REFERENCES job(id)
);

INSERT INTO person(name) VALUES ('Jack'), ('Rose'), ('Larry'), ('Mike'), ('Tom'), ('James');

INSERT INTO id_card(no, address, person_id) VALUES
('9527', '北京', 4),
('8866', '广州', 1),
('2495', '上海', 5),
('4378', '成都', 2),
('5454', '杭州', 6),
('9923', '深圳', 3);

INSERT INTO bank_card(no, amout, person_id) VALUES
('6223', 0, 1),
('75556', 2098.56, 2),
('5345', 1010000.56, 1),
('87876', 534423.34, 3),
('654645', 432.45, 1),
('5434534', 234765.19, 4),
('76853', 98945.39, 4),
('6456867', 435534.78, 1),
('4324654', 874343.99, 4),
('53455', 5.20, 2);

INSERT INTO job(name, duty) VALUES
('程序员', '每一天都在写新的bug和修改昨天的bug'),
('保安', '公司全系统物理安全保障专员'),
('网管', '世界互联网信息终端及人类信息科技部信息集成应用导师'),
('厨师', '类口腔神经末梢感应实验中心及绿色环保邮寄肥转换加工基地负责人'),
('贴膜', '智能高端移动设备表面高化合物平面处理'),
('搬砖', '长方体混泥土瞬间移动师'),
('算命', '主观性逻辑推论及心理引导'),
('理发师', '人体无用副组织切除手术主刀');

INSERT INTO person_job(person_id, job_id) VALUES
(1, 1),
(1, 3),
(1, 5),
(1, 7),
(2, 5),
(3, 1),
(3, 2),
(5, 3),
(5, 5),
(5, 7);

四、一对一

(1) 查询 person 信息, 同时查询出 person 对应的 id_card 信息


SELECT
	p.*,
	c.id c_id,
	c.`no` c_no,
	c.address c_address
FROM
	person p
	LEFT JOIN id_card c ON p.id = c.person_id

💦 写法1

<mapper namespace="person">

    <select id="list1" resultType="Person">
        SELECT
        p.*,
        c.id `idCard.id`,
        c.no `idCard.no`,
        c.address `idCard.address`
        FROM
        person p
        LEFT JOIN id_card c ON p.id = c.person_id
    select>

mapper>

自动映射到 Person 的 idCard 属性的 id、no、address 属性上面去

💦 写法2

<mapper namespace="person">

    <resultMap id="rmList2" type="Person">
        <id property="id" column="id"/>
        <result property="name" column="name"/>

        <association property="idCard" javaType="IdCard">
            <id property="id" column="c_id"/>
            <result property="no" column="c_no"/>
            <result property="address" column="c_address"/>
        association>
    resultMap>
    <select id="list2" resultMap="rmList2">
        SELECT
        p.*,
        c.id c_id,
        c.`no` c_no,
        c.address c_address
        FROM
        person p
        LEFT JOIN id_card c ON p.id = c.person_id
    select>

mapper>

(2) 查询 id_card 信息, 同时查询出 id_card 对应的 person 信息


SELECT
	c.*,
	p.id p_id,
	p.NAME p_name
FROM
	id_card c
	LEFT JOIN person p ON p.id = c.person_id
<mapper namespace="idCard">

    <resultMap id="rmList" type="IdCard">
        <id property="id" column="id"/>
        <result property="no" column="no"/>
        <result property="address" column="address"/>

        <association property="person" javaType="Person">
            <id property="id" column="p_id"/>
            <result property="name" column="p_name"/>
        association>
    resultMap>
    <select id="list" resultMap="rmList">
        SELECT
        c.*,
        p.id p_id,
        p.NAME p_name
        FROM
        id_card c
        LEFT JOIN person p ON p.id = c.person_id
    select>

mapper>

五、一对多


SELECT
	p.*,
	b.id bankCard_id,
	b.no bankCard_no,
	b.amout bankCard_amount
FROM
	person p
	LEFT JOIN bank_card b ON b.person_id = p.id
<mapper namespace="person">

    <resultMap id="rmListWithBankCard" type="Person">
        <id property="id" column="id"/>
        <result property="name" column="name"/>

        <collection property="bankCards" ofType="BankCard">
            <id property="id" column="bankCard_id"/>
            <result property="no" column="bankCard_no"/>
            <result property="amount" column="bankCard_amount"/>
        collection>
    resultMap>
    <select id="listWithBankCard" resultMap="rmListWithBankCard">
        SELECT
        p.*,
        b.id bankCard_id,
        b.no bankCard_no,
        b.amount bankCard_amount
        FROM
        person p
        LEFT JOIN bank_card b ON b.person_id = p.id
    select>

mapper>

六、多对多

查询 person 信息, 同时查询出 job 信息:

SELECT
	p.*,
	j.id job_id,
	j.`name` job_name,
	j.duty job_duty
FROM
	person p
	LEFT JOIN person_job pj ON p.id = pj.person_id
	LEFT JOIN job j ON j.id = pj.job_id;
<mapper namespace="person">

    <resultMap id="rmListWithJob" type="Person">
        <id property="id" column="id"/>
        <result property="name" column="name"/>

        <collection property="jobs" ofType="Job">
            <id property="id" column="job_id"/>
            <result property="name" column="job_name"/>
            <result property="duty" column="job_duty"/>
        collection>
    resultMap>
    <select id="listWithJob" resultMap="rmListWithJob">
        SELECT
        p.*,
        j.id job_id,
        j.`name` job_name,
        j.duty job_duty
        FROM
        person p
        LEFT JOIN person_job pj ON p.id = pj.person_id
        LEFT JOIN job j ON j.id = pj.job_id
    select>

mapper>

查询 job 列表,同时查询出从事该 job 的 person 列表:

<mapper namespace="job">

    <resultMap id="rmListWithPerson" type="Job">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="duty" column="duty"/>

        <collection property="persons" ofType="Person">
            <id property="id" column="person_id"/>
            <result property="name" column="person_name"/>
        collection>
    resultMap>
    <select id="listWithPerson" resultMap="rmListWithPerson">
        SELECT
        j.*,
        p.id person_id,
        p.`name` person_name
        FROM
        job j
        LEFT JOIN person_job pj ON pj.job_id = j.id
        LEFT JOIN person p ON pj.person_id = p.id;
    select>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值