欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis多表關聯(lián)查詢的實現(xiàn)示例

 更新時間:2023年03月30日 08:33:27   作者:Java Fans  
本文主要介紹了MyBatis多表關聯(lián)查詢的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一對多查詢

一對多關聯(lián)查詢是指在查詢一方對象的時候,同時將其所關聯(lián)的多方對象也都查詢出來。下面以班級 Classes 與學生 Student 間的一對多關系為例進行演示。一個班級有多個學生,一個學生只屬于一個班級。數(shù)據(jù)庫 student 表里面有個字段 classno 是外鍵,對應主鍵表 Class 的主鍵 cid。

項目案例:查詢班級號為 1801 的班級,同時遍歷該班級的所有的學生信息

實現(xiàn)步驟:

【1】在 MySQL 中創(chuàng)建數(shù)據(jù)庫 studentdb,創(chuàng)建表 studentclasses,并添加若干測試用的數(shù)據(jù)記錄,SQL 語句如下:

CREATE DATABASE studentdb;
USE  studentdb ;
DROP TABLE IF EXISTS  student ;
CREATE TABLE  student  (
   id  INT(11) NOT NULL,
   studentname  VARCHAR(20) DEFAULT NULL,
   gender  CHAR(2) DEFAULT NULL,
   age  INT(11) DEFAULT NULL,
   classno VARCHAR(10),
   PRIMARY KEY ( id )
) 
INSERT  INTO  student ( id , studentname , gender , age , classno ) VALUES (1,'張飛','男',18,'201801'),(2,'李白','男',20,'201801'),(3,'張無忌','男',19,'201801'),(4,'趙敏','女',17,'201801');


CREATE TABLE classes (
	cid VARCHAR (30),
	cname VARCHAR (60)
); 
INSERT INTO classes (cid, cname) VALUES('201801','計算機軟件1班');
INSERT INTO classes (cid, cname) VALUES('201802','計算機軟件2班');

【2】創(chuàng)建實體類 ClassesStudent

Student 類如下:

package cn.kgc.my01.entity;

import lombok.Data;

@Data
public class Student {
    private String sid;
    private String sname;
    private String sex;
    private Integer age;

    //添加額外屬性:所在班級
    private  Classes classes;

    public String show(){
        return "學生編號:"+getSid()+",學生姓名:"+getSname()+",學生性別:"+getSex()+",學生年齡:"+getAge();
    }
}

Classes 類如下:

package cn.kgc.my01.entity;

import lombok.Data;

import java.util.List;

@Data
public class Classes {
    private String cid;
    private String cname;

    //添加額外屬性
    private List<Student> students;

    public String show(){
        return "班級編號:"+getCid()+",班級名稱:"+getCname()+",班級學生:";
    }
}

【3】創(chuàng)建 ClassesMapper.java 接口,并添加 findClassesById 方法

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Classes;

public interface ClassesMapper {
    Classes findClassesById(String id);
}

【4】創(chuàng)建 ClassesMapper.xml 映射文件,有以下兩種方式:

方式一:多表連接查詢方式

這種方式只用到1條 SQL 語句,代碼如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.my01.mapper.ClassesMapper">
    <!--方式一:多表連接查詢方式,只用到 1條SQL語句-->
    <resultMap id="classResultMap" type="classes">
        <id property="cid" column="cid"/>
        <result property="cname" column="cname"/>
        <!--關聯(lián)屬性的映射關系-->
        <collection property="students" ofType="Student">
            <id property="sid" column="id"/>
            <result property="sname" column="studentname"/>
            <result property="sex" column="gender"/>
            <result property="age" column="age"/>
        </collection>
    </resultMap>
    <select id="findClassesById" resultMap="classResultMap">
        select cid,cname,id,studentname,gender,age from classes,student
        where classes.cid=student.classno and classes.cid=#{cid}
    </select>
</mapper>

注意:<resultMap/> 中,如果字段名與屬性名相同時,可以在 <resultMap/> 中添加 autoMapping=“true” 來開啟自動映射。

另外,在 “一方” 的映射文件中使用 <collection/> 標簽體現(xiàn)出兩個實體對象間的關聯(lián)關系。其兩個屬性的解釋如下:

  • property:指定關聯(lián)屬性,即 Class 類中的集合屬性 students。
  • ofType:集合屬性的泛型類型,即 Student。

方式二:多表單獨查詢方式

多表連接查詢方式是將多張表進行連接,連為一張表后進行查詢。其查詢的本質(zhì)是一張表。而多表單獨查詢方式是多張表各自查詢各自的相關內(nèi)容,需要多張表的聯(lián)合數(shù)據(jù),再將主表的查詢結果聯(lián)合其它表的查詢結果,封裝為一個對象。

多個查詢是可以跨越多個映射文件的,即是可以跨越多個namespace 的。在使用其它 namespace 的查詢時,添加上其所在的 namespace 即可。這種方式要用到2條 SQL 語句,代碼如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.my01.mapper.ClassesMapper">
   <!--方式二:多表單獨查詢方式,也就是分步查詢-->
    <resultMap id="classResultMap2" type="classes">
        <id property="cid" column="cid"/>
        <result property="cname" column="cname"/>
        <!--關聯(lián)屬性的映射關系-->
        <collection property="students" ofType="Student">
            <id property="sid" column="id"/>
            <result property="sname" column="studentname"/>
            <result property="sex" column="gender"/>
            <result property="age" column="age"/>
        </collection>
    </resultMap>
    <!-- 以下注釋部分屬于方式二: 多表單獨查詢方式 -->
    <resultMap id="studentResultMap" type="student">
        <id property="sid" column="id" />
        <result property="sname" column="studentname" />
        <result property="sex" column="gender" />
        <result property="age" column="age" />
    </resultMap>
    <resultMap id="classesResultMap" type="classes">
        <id property="cid" column="cid" />
        <result property="cname" column="cname" />
    <!-- 關聯(lián)屬性的映射關系 -->
    <!-- 集合的數(shù)據(jù)來自指定的select查詢,該select查詢的動態(tài)參數(shù)來自column指定的字段值 -->
        <collection property="students" ofType="Student" select="selectStudentsByClasses" column="cid"/>
    </resultMap>
    <!-- 多表單獨查詢,查多方的表 -->
    <select id="selectStudentsByClasses" resultMap="studentResultMap">
        select * from student where calssno=#{cid}
    </select>

    <!-- 多表單獨查詢,查一方的表 -->
     <select id="findClassesById" parameterType="String" resultMap="classesResultMap">
        select cid,cname from classes
        where cid=#{cid}
    </select>
</mapper>

【5】創(chuàng)建 ClassesMapperTest 測試類,并添加如下方法:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Classes;
import cn.kgc.my01.entity.Student;
import junit.framework.TestCase;
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.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class ClassesMapperTest{
    SqlSessionFactory factory=null;
    @Before
    public void init(){
        try {
            System.out.println("########");
            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");

            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    @Test
    public void testFindClassesById() {
        SqlSession sqlSession = factory.openSession(true);
        ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
        Classes classesById = mapper.findClassesById("201801");
        System.out.println(classesById.show());
        List<Student> students = classesById.getStudents();

        for (Student student : students) {
            System.out.println(student.show());
        }
    }
}

方式一:多表連接查詢方式測試結果:

DEBUG [main] - ==>  Preparing: select cid,cname,id,studentname,gender,age from 
 classes,student where classes.cid=student.classno and classes.cid=?
DEBUG [main] - ==> Parameters: 201801(String)
DEBUG [main] - <==      Total: 4
班級編號:201801,班級名稱:計算機軟件1班,班級學生:
學生編號:1,學生姓名:張飛,學生性別:男,學生年齡:18
學生編號:2,學生姓名:李白,學生性別:男,學生年齡:20
學生編號:3,學生姓名:張無忌,學生性別:男,學生年齡:19
學生編號:4,學生姓名:趙敏,學生性別:女,學生年齡:17

可以發(fā)現(xiàn),只有一條 SQL 語句,并且是多表聯(lián)查。

方式二:多表單獨查詢方式測試結果:

2023-02-15 10:56:49,965 [main] DEBUG DEBUG [main] - ==>  Preparing: select cid,cname from classes where cid=?
DEBUG [main] - ==> Parameters: 201801(String)
DEBUG [main] - ====>  Preparing: select * from student where classno=?
DEBUG [main] - ====> Parameters: 201801(String)
DEBUG [main] - <====      Total: 4
DEBUG [main] - <==      Total: 1
班級編號:201801,班級名稱:計算機軟件1班,班級學生:
學生編號:1,學生姓名:張飛,學生性別:男,學生年齡:18
學生編號:2,學生姓名:李白,學生性別:男,學生年齡:20
學生編號:3,學生姓名:張無忌,學生性別:男,學生年齡:19
學生編號:4,學生姓名:趙敏,學生性別:女,學生年齡:17

可以發(fā)現(xiàn),其 SQL 語句是兩條,即各查各的,共用同一個參數(shù)。第 1 條先查一方的表,第 2 條再查多方的表。

多對一查詢

多對一關聯(lián)查詢是指在查詢多方對象的時候,同時將其所關聯(lián)的一方對象也查詢出來。

由于在查詢多方對象時也是一個一個查詢,所以多對一關聯(lián)查詢,其實就是一對一關聯(lián)查詢。即一對一關聯(lián)查詢的實現(xiàn)方式與多對一的實現(xiàn)方式是相同的。 配置多對一關聯(lián)的重點在于“多方”的映射文件要有 <association> 屬性關聯(lián)“一方”。

項目案例: 查詢學號為1的學生,同時獲取他所在班級的完整信息

實現(xiàn)步驟:

【1】創(chuàng)建 StudentMapper.java 接口,并添加方法 searchStudentsById(int id) 如下:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Student;

public interface StudentMapper {
    public Student searchStudentsById(int id);
}

【2】創(chuàng)建 StudentMapper.xml 映射文件,有以下兩種方式:

方式一:多表聯(lián)合查詢。

 <!-- 多表聯(lián)合查詢 -->
    <resultMap id="studentResultMapper" type="student">
        <id property="sid" column="id" />
        <result property="sname" column="studentname" />
        <result property="sex" column="gender" />
        <result property="age" column="age" />
        <!-- 關聯(lián)屬性 -->
        <association property="classes" javaType="classes">
            <id property="cid" column="cid" />
            <result property="cname" column="cname" />
        </association>
    </resultMap>
    <!-- 多表連接查詢 -->
    <select id="searchStudentsById" parameterType="int" resultMap="studentResultMapper">
        select cid,cname,id,studentname,gender,age from classes,student
        where classes.cid=student.classno
        and student.id=#{id}
    </select>

方式二:多表單獨查詢。

    <!-- 以下注釋的是方式二:多表單獨查詢 -->
    <resultMap id="studentResultMap2" type="student">
        <id property="sid" column="id" />
        <result property="sname" column="studentname" />
        <result property="sex" column="gender" />
        <result property="age" column="age" />	
        <!-- 關聯(lián)屬性 -->
        <association property="classes" javaType="classes" select="findClassesById" column="classno"/>
    </resultMap>
    <select id="searchStudentsById" resultMap="studentResultMap2">
        select id,studentname,gender,age,classno from student where id=#{id}
    </select>
    <select id="findClassesById" parameterType="String" resultType="classes">
        select cid,cname from classes where cid=#{cid}
    </select> 

【3】創(chuàng)建 StudentMapperTest 測試類,并添加如下方法:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Classes;
import cn.kgc.my01.entity.Student;
import junit.framework.TestCase;
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.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class StudentMapperTest {
    SqlSessionFactory factory=null;
    @Before
    public void init(){
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");

            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testSearchStudentsById() {
        SqlSession sqlSession = factory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.searchStudentsById(1);
        System.out.println(student.show());

        System.out.println("所在班級:");
        Classes classes=student.getClasses();
        System.out.println(classes.toString());
    }
}

方式一:多表聯(lián)合查詢方式測試結果:

DEBUG [main] - ==>  Preparing: select cid,cname,id,studentname,gender,age from 
     classes,student where classes.cid=student.classno and student.id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
學生編號:1,學生姓名:張飛,學生性別:男,學生年齡:18
所在班級:
Classes(cid=201801, cname=計算機軟件1班, students=null)

可以發(fā)現(xiàn),它發(fā)出的 SQL 語句是多表查詢。

方式一:多表單獨查詢方式測試結果:

DEBUG [main] - ==>  Preparing: select id,studentname,gender,age,classno from student where id=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - ====>  Preparing: select cid,cname from classes where cid=?
DEBUG [main] - ====> Parameters: 201801(String)
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 1
學生編號:1,學生姓名:張飛,學生性別:男,學生年齡:18
所在班級:
Classes(cid=201801, cname=計算機軟件1班, students=null)

可以發(fā)現(xiàn),它發(fā)出的 SQL 語句是兩條,即各查各的,共用同一個參數(shù)。

自連接查詢

自連接的查詢可以用一對多來處理,也可以用多對一來處理。例如,員工表,每個員工都有一個上司,但上司同時也是員工表的一條記錄,這種情況可用自連接查詢出每個員工對應的上司信息,也可以查出每個上司有哪些下屬員工。

使用多對一的方式實現(xiàn)自連接

項目案例:查詢員工的信息及對應的上司信息。

思路分析: 可將員工當做多方,上司當做一方。

實現(xiàn)步驟:

【1】修改數(shù)據(jù)庫。

添加一個表 employee 并插入測試數(shù)據(jù),具體如下:

create table employee (
	empid double ,
	empname varchar (60),
	job varchar (60),
	leader double 
); 
insert into employee (empid, empname, job, leader) values('1','jack','clerk','3');
insert into employee (empid, empname, job, leader) values('2','mike','salesman','3');
insert into employee (empid, empname, job, leader) values('3','john','manager','4');
insert into employee (empid, empname, job, leader) values('4','smith','president',NULL);
insert into employee (empid, empname, job, leader) values('5','rose','salesman','3');

【2】創(chuàng)建實體類 Employee,代碼如下:

package cn.kgc.my01.entity;

public class Employee {
	private int empid;
	private String empname;
	private String job;
	private Employee leader;
	public int getEmpid() {
		return empid;
	}
	public void setEmpid(int empid) {
		this.empid = empid;
	}
	public String getEmpname() {
		return empname;
	}
	public void setEmpname(String empname) {
		this.empname = empname;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Employee getLeader() {
		return leader;
	}
	public void setLeader(Employee leader) {
		this.leader = leader;
	}	
	public String toString(){
		return "員工編號:"+getEmpid()+",員工姓名:"+getEmpname()+",員工職位:"+getJob();
	}
}

可以發(fā)現(xiàn),里面存在著嵌套,Employee 里面的一個屬性 leader 本身就是 Employee 類型。

【3】創(chuàng)建 EmployeeMapper.java 接口,添加 findEmployeeAndLeaderById 方法如下:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Employee;

public interface EmployeeMapper {
    Employee findEmployeeAndLeaderById(int id);
}

【4】創(chuàng)建 EmployeeMapper.xml 映射文件,代碼如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.my01.mapper.EmployeeMapper">

    <resultMap id="empResultMap" type="employee">
        <id property="empid" column="empid" />
        <result property="empname" column="empname" />
        <result property="job" column="job" />
        <association property="leader" javaType="Employee"
                     select="findEmployeeAndLeaderById" column="leader"/>
    </resultMap>
    <select id="findEmployeeAndLeaderById" parameterType="int" resultMap="empResultMap">
        select * from employee where empid=#{empid}
    </select>
</mapper>

【5】創(chuàng)建 EmployeeMapperTest.java 測試類

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Classes;
import cn.kgc.my01.entity.Employee;
import cn.kgc.my01.entity.Student;
import junit.framework.TestCase;
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.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;

public class EmployeeMapperTest {
    SqlSessionFactory factory=null;
    @Before
    public void init(){
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");

            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testFindEmployeeAndLeaderById() {
        SqlSession sqlSession = factory.openSession(true);
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        Employee employee=mapper.findEmployeeAndLeaderById(1);
        Employee leader=employee.getLeader();
        System.out.println(employee.toString());
        System.out.println("他的上司是:"+leader.toString());
        //System.out.println("他的上司的上司是:"+leader.getLeader().toString());
    }
}

測試結果: 查詢員工

DEBUG [main] - ==>  Preparing: select * from employee where empid=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - ====>  Preparing: select * from employee where empid=?
DEBUG [main] - ====> Parameters: 3(Integer)
DEBUG [main] - ======>  Preparing: select * from employee where empid=?
DEBUG [main] - ======> Parameters: 4(Integer)
DEBUG [main] - <======      Total: 1
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 1
員工編號:1,員工姓名:jack,員工職位:clerk
他的上司是:員工編號:3,員工姓名:john,員工職位:manager

從上面的 SQL 語句中發(fā)現(xiàn),出現(xiàn)了 3 條 SQL 語句,這個查詢存在嵌套,先查員工1,然后查他的直接上司3,再查上司的上司4。這種情況不影響什么,甚至可以實現(xiàn)直接輸出上司的上司,但要注意輸出語句不要出現(xiàn)地柜,即輸出語句不要出現(xiàn)輸出上司。

要同時查上司的上司,只需要在上面的測試類中多加一條語句:

System.out.println("他的上司的上司是:"+leader.getLeader().toString());

使用一對多的方式實現(xiàn)自連接

項目案例:查詢某位領導及其直接下屬員工。

思路分析: 可用一對多的方式來實現(xiàn),員工(領導)當作一方,員工(下屬)當作多方。

實現(xiàn)步驟:

【1】修改實體類 Employee,代碼如下:

package cn.kgc.my01.entity;

import java.util.List;

public class Employee {
	private int empid;
	private String empname;
	private String job;
	//員工的上司
	private Employee leader;

	//員工的下屬
	private List<Employee> employees;
	public List<Employee> getEmployees() {
		return employees;
	}
	public void setEmployees(List<Employee> employees) {
		this.employees = employees;
	}
	public int getEmpid() {
		return empid;
	}
	public void setEmpid(int empid) {
		this.empid = empid;
	}
	public String getEmpname() {
		return empname;
	}
	public void setEmpname(String empname) {
		this.empname = empname;
	}
	public String getJob() {
		return job;
	}
	public void setJob(String job) {
		this.job = job;
	}
	public Employee getLeader() {
		return leader;
	}
	public void setLeader(Employee leader) {
		this.leader = leader;
	}
	public String toString(){
		return "員工編號:"+getEmpid()+",員工姓名:"+getEmpname()+",員工職位:"+getJob();
	}
}

【2】在 EmployeeMapper.java 接口中,添加 findLeaderAndEmployeesById 方法如下:

Employee findLeaderAndEmployeesById(int id);

【3】在 EmployeeMapper.xml 映射文件中,添加 findEmployeeAndLeaderById 的映射方法內(nèi)容如下:

    <!-- 一對多的方式實現(xiàn)自連接 -->
    <resultMap id="empResultMap2" type="employee">
        <id property="empid" column="empid" />
        <result property="empname" column="empname" />
        <result property="job" column="job" />
        <!-- 關聯(lián)屬性的映射關系
        集合的數(shù)據(jù)來自指定的select查詢,該select查詢的動態(tài)參數(shù)來自column指定的字段值 -->
        <collection property="employees" ofType="employee"
                    select="selectEmployeesByLeader" column="empid"/>
    </resultMap>
    <select id="selectEmployeesByLeader" resultType="employee">
        select * from employee where leader=#{empid}
    </select>
    <select id="findLeaderAndEmployeesById" parameterType="int" resultMap="empResultMap2">
        select * from employee where empid=#{empid}
    </select>

【4】在 EmployeeMapperTest.java 測試類中,添加如下內(nèi)容:

    @Test
    public void testTestFindLeaderAndEmployeesById() {
        SqlSession sqlSession = factory.openSession(true);
        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        Employee leader=mapper.findLeaderAndEmployeesById(4);
        List<Employee> employees = leader.getEmployees();
        System.out.println(leader.toString());
        System.out.println("他的直接下屬有:");
        for (Employee employee : employees) {
            System.out.println(employee.toString());
        }
    }

測試結果: 查詢經(jīng)理

DEBUG [main] - ==>  Preparing: select * from employee where empid=?
DEBUG [main] - ==> Parameters: 4(Integer)
DEBUG [main] - ====>  Preparing: select * from employee where leader=?
DEBUG [main] - ====> Parameters: 4.0(Double)
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 1
員工編號:4,員工姓名:smith,員工職位:president
他的直接下屬有:
員工編號:3,員工姓名:john,員工職位:manager

多對多查詢

原理: 多對多可以分拆成兩個一對多來處理,需要一個中間表,各自與中間表實現(xiàn)一對多的關系。

項目案例:一個學生可以選人修多門課程,一門課程可以給多個學生選修,課程與學生之間是典型的多對多。實現(xiàn)查詢一個學生信息,同時查出他的所有選修課,還有實現(xiàn)查詢一門課程信息,同時查出所有的選修了該課程的學生信息。

思路分析: 多對多需要第三表來體現(xiàn),數(shù)據(jù)庫中除了課程表,學生表,還需要學生課程表。

實現(xiàn)步驟:

【1】修改數(shù)據(jù)庫,代碼如下:

CREATE DATABASE studentdb;
USE  studentdb ;
DROP TABLE IF EXISTS  student ;
CREATE TABLE  student  (
   id  INT(11) NOT NULL,
   studentname  VARCHAR(20) DEFAULT NULL,
   gender  CHAR(2) DEFAULT NULL,
   age  INT(11) DEFAULT NULL,
   classno VARCHAR(10),
   PRIMARY KEY ( id )
) 
INSERT  INTO  student ( id , studentname , gender , age , classno ) VALUES (1,'張飛','男',18,'201801'),(2,'李白','男',20,'201801'),(3,'張無忌','男',19,'201801'),(4,'趙敏','女',17,'201801');


CREATE TABLE classes (
	cid VARCHAR (30),
	cname VARCHAR (60)
); 
INSERT INTO classes (cid, cname) VALUES('201801','計算機軟件1班');
INSERT INTO classes (cid, cname) VALUES('201802','計算機軟件2班');

CREATE TABLE employee (
	empid DOUBLE ,
	empname VARCHAR (60),
	job VARCHAR (60),
	leader DOUBLE 
); 
INSERT INTO employee (empid, empname, job, leader) VALUES('1','jack','clerk','3');
INSERT INTO employee (empid, empname, job, leader) VALUES('2','mike','salesman','3');
INSERT INTO employee (empid, empname, job, leader) VALUES('3','john','manager','4');
INSERT INTO employee (empid, empname, job, leader) VALUES('4','smith','president',NULL);
INSERT INTO employee (empid, empname, job, leader) VALUES('5','rose','salesman','3');


CREATE TABLE course (
	courseid DOUBLE ,
	coursename VARCHAR (90)
); 
INSERT INTO course (courseid, coursename) VALUES('1','java');
INSERT INTO course (courseid, coursename) VALUES('2','android');
INSERT INTO course (courseid, coursename) VALUES('3','PHP');

CREATE TABLE studentcourse (
	id DOUBLE ,
	studentid DOUBLE ,
	courseid DOUBLE 
); 
INSERT INTO studentcourse (id, studentid, courseid) VALUES('1','1','1');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('2','1','2');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('3','2','1');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('4','2','2');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('5','3','1');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('6','3','2');
INSERT INTO studentcourse (id, studentid, courseid) VALUES('7','1','3');

【2】新增實體類 Course 和修改實體類 Student 。

Course 類如下:

package cn.kgc.my01.entity;

import lombok.Data;

import java.util.List;

@Data
public class Course {
    private int courseid;
    private String coursename;
    private List<Student> students;

    public String toString(){
        return "課程編號:"+getCourseid()+",課程名稱:"+getCoursename();
    }
}

Student類如下,添加一個屬性courses和getter,setter方法。

    private List<Course> courses;
    public List<Course> getCourses() {
        return courses;
    }
    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }

【3】新建 StudentMapper.java 接口,并添加一個方法如下:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Student;

public interface StudentMapper {
    public Student searchStudentById(int id);
}

【4】配置對應的 StudentMapper.xml 映射,代碼如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.my01.mapper.StudentMapper">
    <resultMap id="studentMap2" type="student">
        <id property="sid" column="id" />
        <result property="sname" column="studentname" />
        <result property="sex" column="gender" />
        <result property="age" column="age" />

        <!-- 關聯(lián)屬性的映射關系 -->
        <collection property="courses" ofType="Course">
            <id property="courseid" column="courseid" />
            <result property="coursename" column="coursename" />
        </collection>
    </resultMap>
    <!-- 多表連接查詢 -->
    <select id="searchStudentById" parameterType="int" resultMap="studentMap2">
        select student.id,studentname,gender,age,course.courseid,coursename from course,student,studentcourse
        where course.courseid=studentcourse.courseid
        and student.id=studentcourse.studentid and student.id=#{id}
    </select>
</mapper>

【5】創(chuàng)建測試類 StudentMapperTest 類

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Classes;
import cn.kgc.my01.entity.Course;
import cn.kgc.my01.entity.Student;
import junit.framework.TestCase;
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.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentMapperTest {
    SqlSessionFactory factory=null;
    @Before
    public void init(){
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");

            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testSearchStudentsById() {
        SqlSession sqlSession = factory.openSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.searchStudentById(1);
        System.out.println(student.show());

        System.out.println("-----該生選修了以下課程:-----------");
        List<Course> courses=student.getCourses();
        for(Course course:courses){
            System.out.println(course.toString());
        }
    }
}

測試結果:

【6】新建 CourseMapper.java 接口,并添加一個方法如下:

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Course;

public interface CourseMapper {
    //根據(jù)id查找課程,即時獲取選個性該課程的學生
    public Course searchCourseById(int id);
}

【7】配置對應的 CourseMapper.xml 映射,代碼如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.my01.mapper.CourseMapper">
  <resultMap id="courseMap" type="course">
    <id property="courseid" column="courseid" />
    <result property="coursename" column="coursename" />
    <!-- 關聯(lián)屬性的映射關系 -->
    <collection property="students" ofType="Student">
      <id property="sid" column="id" />
      <result property="sname" column="studentname" />
      <result property="sex" column="gender" />
      <result property="age" column="age" />
    </collection>
  </resultMap>

  <!-- 多表連接查詢 -->
  <select id="searchCourseById" parameterType="int" resultMap="courseMap">
    select student.id,studentname,gender,age,course.courseid,coursename from course,student,studentcourse
    where course.courseid=studentcourse.courseid
    and student.id=studentcourse.studentid and course.courseid=#{courseid}
  </select>
</mapper>

【8】創(chuàng)建測試類 CourseMapperTest 類

package cn.kgc.my01.mapper;

import cn.kgc.my01.entity.Course;
import cn.kgc.my01.entity.Employee;
import cn.kgc.my01.entity.Student;
import junit.framework.TestCase;
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.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class CourseMapperTest{
    SqlSessionFactory factory=null;
    @Before
    public void init(){
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");

            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void testSearchCourseById() {
        SqlSession sqlSession = factory.openSession(true);
        CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
        Course course = mapper.searchCourseById(1);
        System.out.println(course.toString());
        System.out.println("-------該課程有以下學生選修:------");
        List<Student> students=course.getStudents();
        for(Student student:students){
            System.out.println(student.show());
        }
    }
}

測試效果:

到此這篇關于MyBatis多表關聯(lián)查詢的實現(xiàn)示例的文章就介紹到這了,更多相關MyBatis多表關聯(lián)查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot發(fā)送短信驗證碼的實例

    SpringBoot發(fā)送短信驗證碼的實例

    第三方短信發(fā)送平臺有很多種,各個平臺有各自的優(yōu)缺點,在選擇的時候可以根據(jù)自己的具體實際情況定奪,本文主要介紹了SpringBoot發(fā)送短信驗證碼的實例,感興趣的可以了解一下
    2022-02-02
  • Java實現(xiàn)二叉樹的基本操作詳解

    Java實現(xiàn)二叉樹的基本操作詳解

    這篇文章主要為大家詳細介紹了Java數(shù)據(jù)結構與算法中二叉樹的基本操作,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的小伙伴可以了解一下
    2022-10-10
  • 關于spring依賴注入的方式以及優(yōu)缺點

    關于spring依賴注入的方式以及優(yōu)缺點

    這篇文章主要介紹了關于spring依賴注入的方式以及優(yōu)缺點,依賴注入,是IOC的一個方面,是個通常的概念,它有多種解釋,這概念是說你不用創(chuàng)建對象,而只需要描述它如何被創(chuàng)建,需要的朋友可以參考下
    2023-07-07
  • Java異常中toString()和getMessage()區(qū)別

    Java異常中toString()和getMessage()區(qū)別

    在java異常體系中,要打印異常信息,可以通過:e.getMessage() 、 e.toString() e.printStackTrace() 等方法打印,本文主要介紹了Java異常中toString()和getMessage()區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Java中HashMap和Hashtable的區(qū)別淺析

    Java中HashMap和Hashtable的區(qū)別淺析

    這篇文章主要介紹了Java中HashMap和Hashtable的區(qū)別淺析,本文總結了6條它們之間的不同之處,需要的朋友可以參考下
    2015-03-03
  • java 中數(shù)組初始化實例詳解

    java 中數(shù)組初始化實例詳解

    這篇文章主要介紹了 本文主要講數(shù)組的初始化方法、可變參數(shù)列表以及可變參數(shù)列表對函數(shù)重載的影響的相關資料,需要的朋友可以參考下
    2017-05-05
  • springmvc重定向?qū)崿F(xiàn)方法解析

    springmvc重定向?qū)崿F(xiàn)方法解析

    這篇文章主要介紹了springmvc重定向?qū)崿F(xiàn)方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Java利用MD5加鹽實現(xiàn)對密碼進行加密處理

    Java利用MD5加鹽實現(xiàn)對密碼進行加密處理

    在開發(fā)的時候,有一些敏感信息是不能直接通過明白直接保存到數(shù)據(jù)庫的。最經(jīng)典的就是密碼了。如果直接把密碼以明文的形式入庫,不僅會泄露用戶的隱私,對系統(tǒng)也是極其的不厲。本文就來和大家介紹一下如何對密碼進行加密處理,感興趣的可以了解一下
    2023-02-02
  • idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題

    idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題

    這篇文章主要介紹了idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題,具有很好的參考價值,希望對大家有所幫助,
    2023-11-11
  • java正則表達式之Pattern與Matcher類詳解

    java正則表達式之Pattern與Matcher類詳解

    這篇文章主要給大家介紹了關于java正則表達式之Pattern與Matcher類的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09

最新評論