[Primavera] — SQL dinâmico: mapeamento de associação MyBatis

Mapeamento de associação de MyBatis

Em aplicações práticas, o funcionamento do banco de dados envolverá tabelas múltiplas, o que envolve o relacionamento entre objetos na orientação a objetos. Para a operação entre várias tabelas, o MyBatis fornece mapeamento de associação, que lida com o relacionamento de associação entre objetos por meio do mapeamento de associação.

1. Visão geral do relacionamento

Em um banco de dados relacional, existem três tipos de associações entre tabelas múltiplas, ou seja, um-para-um, um-para-muitos e muitos-para-muitos.

  • Um-para-um: introduza a chave primária da outra parte como uma chave estrangeira em ambos os lados.
  • Um-para-muitos: adicione a chave primária do lado "um" ao lado "muitos" como uma chave estrangeira.
  • Muitos para muitos: gere uma tabela relacional intermediária, introduza a chave primária das duas tabelas como uma chave estrangeira e transforme as duas chaves primárias em uma chave primária conjunta ou use um novo campo como chave primária.

Existem também três tipos de associações entre objetos.

  • Relacionamento um-para-um: define objetos do outro tipo nesta classe, como definir o atributo b do tipo B na classe A e definir o atributo a do tipo A na classe B.
  • Relacionamento um-para-muitos: no caso em que um tipo de classe A corresponde a vários tipos de classe B, é necessário introduzir objetos do tipo classe B na classe A como uma coleção e definir o atributo a do tipo classe A na classe B .
  • Relacionamento muitos-para-muitos: defina uma coleção do tipo B na classe A e defina uma coleção do tipo A na classe B.

2. Relacionamentos no MyBatis

2.1 Um a um

Na vida real, relacionamentos um-para-um são muito comuns. Por exemplo, um aluno tem apenas um cartão de estudante e um cartão de estudante corresponde a apenas um aluno.

Então, como o MyBatis lida com esse relacionamento um-para-um?O <resultMap>elemento aprendido anteriormente contém um <association>subelemento por meio do qual MyBatis lida com o relacionamento um-para-um.

Em <association>um elemento, os seguintes atributos geralmente podem ser configurados.

  • propriedade: especifica o atributo do objeto da classe entidade para o qual está mapeado, e corresponde aos campos da tabela um a um.
  • coluna: Especifica o campo correspondente na tabela.
  • javaType: Especifica o tipo mapeado para o atributo do objeto entidade.
  • select: Especifica a instrução sub-SQL que apresenta a consulta aninhada, que é usada para a consulta aninhada no mapa de associação.
  • fetchType: especifica se o carregamento lento deve ser ativado durante a consulta de associação. Existem dois valores de atributo, lento e ansioso, e o valor padrão é lento (carregamento lento de mapeamento de associação padrão).

<association>Os elementos podem ser configurados das duas maneiras a seguir.

insira a descrição da imagem aqui

Observe que
MyBatis carrega objetos de relacionamento no arquivo de mapeamento principalmente de duas maneiras: consultas aninhadas e resultados aninhados .

Uma consulta aninhada é aquela que retorna o tipo complexo esperado executando outra instrução de mapeamento SQL; um
resultado aninhado é um subconjunto de um resultado unido que usa um mapa de resultados aninhados para manipular a repetição.

[Exemplo 9] Em seguida, tome como exemplo a relação um-para-um entre alunos e IDs de alunos.

Para consultar os alunos e suas informações de ID do aluno associadas, primeiro obtenha as informações do aluno consultando a chave primária na tabela do aluno e, em seguida, obtenha as informações do número de ID do aluno na tabela de ID do aluno por meio da chave estrangeira na tabela. Suas etapas específicas de implementação são as seguintes.

Passo 01 Crie uma tabela de dados. Crie tabelas de dados denominadas tb_studentidcard e tb_student no banco de dados db_mybatis e insira vários dados antecipadamente. A instrução SQL executada por ele é a seguinte.

#使用数据库db mybatis
USE db_mybatis;
#创建一个名称为tb_studentidcard的表
CREATE TABLE IF NOT EXISTS tb_studentidcard( 
		id INT PRIMARY KEY AUTO_INCREMENT,
		CODE VARCHAR(8)
);
#插入两条数据
INSERT INTO tb_studentidcard(CODE) VALUES('18030128');
INSERT INTO tb_studentidcard(CODE) VALUES('18030135');
#创建一个名称为tb_student的表(暂时添加少量字段)
CREATE TABLE tb_student(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(32),
	sex CHAR(1),
	card_id INT UNIQUE,
	FOREIGN KEY (card_id) REFERENCES tb_studentidcard(id)
);
#插入两条数据
INSERT INTO tb_student (name,sex,card_id) VALUES ('limin','f',1);
INSERT INTO tb_student (name,sex,card_id) VALUES ('jack','m',2);

Etapa 02 Crie um projeto da Web denominado capítulo09 e importe pacotes JAR relacionados, classes de ferramentas MybatisUtils e arquivos de configuração principal mybatis-config.xml.

Passo 03 Crie classes persistentes no pacote com.ssm.po do projeto: classe de ID do aluno StudentIdCard e classe de aluno Student.

//StudentIdCard.java

package com.ssm.po;

/**
 * 功能描述
 *
 * @author: 衍生星球
 * @date: 2023年06月08日 17:40
 */

public class StudentIdCard {
    
    
    private Integer id;
    private String code;

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getCode() {
    
    
        return code;
    }

    public void setCode(String code) {
    
    
        this.code = code;
    }

    @Override
    public String toString() {
    
    
        return "StudentIdCard [id=" + id + ", code= " + code + "]";
    }
}
//Student.java

package com.ssm.po;

/**
 * 功能描述
 *
 * @author: 衍生星球
 * @date: 2023年06月08日 17:41
 */

public class Student {
    
    
    private Integer id;
    private String name;
    private String sex;
    private StudentIdCard studentIdCard;

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getSex() {
    
    
        return sex;
    }

    public void setSex(String sex) {
    
    
        this.sex = sex;
    }

    public StudentIdCard getStudentIdCard() {
    
    
        return studentIdCard;
    }

    public void setStudentIdCard(StudentIdCard studentIdCard) {
    
    
        this.studentIdCard = studentIdCard;
    }

    @Override
    public String toString() {
    
    
        return "Student[id=" + id + ", name=" + name + ", sex=" + sex + ", studentIdCard=" + studentIdCard +"]";
    }
}

Etapa 04 Crie um arquivo de mapeamento de carteira de estudante StudentIdCardMapper.xml e um arquivo de mapeamento de estudante StudentMapper.xml no pacote com.ssm.mapper e grave informações de configuração para consultas de mapeamento de associação um-para-um nos dois arquivos de mapeamento.

StudentIdCardMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.StudentIdCardMapper">
<!--    根据学生id获取学生证信息-->
    <select id="findStudentIdCardById" parameterType="com.ssm.po.StudentIdCard" resultType="com.ssm.po.StudentIdCard">
        select * from tb_studentidcard where id = #{
    
    id}
    </select>

</mapper>
StudentMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.StudentMapper">
    <!--    根据学生id获取学生证信息-->
    <select id="findStudentById" parameterType="com.ssm.po.Student" resultMap="CardId">
        select * from tb_student where id = #{
    
    id}
    </select>
    <resultMap id="CardId" type="Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <!--        一对一,association使用select属性引入另一条SQL语句 -->
        <association property="studentIdCard" column="card_id" javaType="StudentIdCard"
                     select="com.ssm.mapper.StudentIdCardMapper.findStudentIdCardById"/>
    </resultMap>
</mapper>

Nos dois arquivos de mapeamento acima, o método de consulta aninhada em MyBatis é usado para consultar os alunos e suas informações de cartão de identificação do aluno associado, porque o objeto aluno retornado tem um atributo studentIdCard associado além dos atributos básicos, portanto, ele precisa ser escrito manualmente Mapeamento de resultados. <association>Como pode ser visto no arquivo de mapeamento StudentMapper.xml, o método de consulta aninhada é executar primeiro uma instrução SQL simples e, em seguida , usar o atributo select do objeto associado no elemento para executar outra instrução SQL ao executar o mapeamento de resultados (StudentIdCardMapper. xmlSQL).

Passo 05 Introduza o arquivo de mapeamento do Mapper e defina um alias no arquivo de configuração principal mybatis-config.xml, conforme mostrado abaixo.

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    引入数据库连接配置文件-->
<!--    <properties resource="db.properties"/>-->
<!--    使用扫描包的形式定义别名-->
    <typeAliases>
        <package name="com.ssm.po"/>
    </typeAliases>
    <environments default="mysql">
<!--        1.2 配置id为mysql 的数据库环境-->
        <environment id="mysql">
<!--            使用JDBC的事务管理-->
            <transactionManager type="JDBC" />
<!--            数据库连接池-->
            <dataSource type="POOLED">
<!--                数据库驱动-->
                <property name="driver" value="com.mysql.jdbc.Driver" />
<!--                连接数据库的url-->
                <property name="url" value="jdbc:mysql://localhost:3306/db_mybatis" />
<!--                连接数据库的用户名-->
                <property name="username" value="root" />
<!--                连接数据库的用户名-->
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
<!--2.配置 Mapper的位置-->
    <mappers>
        <mapper resource="com/ssm/mapper/UserMapper.xml" />
        <mapper resource="com/ssm/mapper/StudentMapper.xml" />
        <mapper resource="com/ssm/mapper/StudentIdCardMapper.xml" />
    </mappers>
</configuration>


No arquivo de configuração principal acima, o arquivo de configuração de conexão do banco de dados é introduzido primeiro, depois o alias é personalizado na forma de um pacote de varredura e, em seguida, o ambiente é configurado e, finalmente, as informações de localização do arquivo de mapeamento Mapper são configuradas.

Passo 06 Crie a classe de teste MybatisAssociatedTest no pacote com.ssm.test, e escreva o método de teste findStudentByIdTest() na classe, conforme mostrado no arquivo.

//MybatisAssociatedTest.java

package com.ssm.test;

import com.ssm.po.Student;
import com.ssm.po.User;
import com.ssm.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class MybatisAssociatedTest {
    
    
    /*
     *嵌套查询
     */
    @Test
    public void findStudentByIdTest() {
    
    
        //通过工具类生成SqlSession对象
        SqlSession sqlSession = MybatisUtil.getSession();
        //执行SqlSession的查询办法,返回结果集
        Student student =
                sqlSession.selectOne("com.ssm.mapper.StudentMapper.findStudentById",1);
        System.out.println(student.toString());
        sqlSession.close();
    }
}

No método findStudentByIdTest(), primeiro obtenha o objeto SqlSession por meio da classe de ferramentas MybatisUtils, depois obtenha as informações do aluno por meio do método selectOne() do objeto SqlSession e, finalmente, feche o SqlSession. Após executar o método, o resultado de saída do console é mostrado na figura. Use a consulta aninhada MyBatis para consultar os alunos e suas informações de ID de aluno associadas, que é a consulta de associação um-para-um em MyBatis.

insira a descrição da imagem aqui

Embora o método de uso de consulta aninhada seja relativamente simples, o método de consulta aninhada precisa executar várias instruções SQL, o que não é muito bom para grandes coleções de dados e exibição de lista, porque pode fazer com que centenas ou até milhares de instruções SOL associadas sejam excluído.Execução, que consome muito o desempenho do banco de dados e reduz a eficiência da consulta. Para esse fim, o MyBatis fornece uma maneira de aninhar resultados para consultas associadas.

Em StudentMapper.xml, use os resultados aninhados do MyBatis para consultar os alunos e suas informações de ID de aluno associadas, e o código adicionado é o seguinte.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.StudentMapper">
    <!--    嵌套结果,通过嵌套结果映射来处理重复的联合结果的子集-->
    <select id="findStudentById2" parameterType="Integer" resultMap="CardId2">
        select s.* ,sidcard.code
        from tb_student s,tb_studentidcard sidcard
        where s.card_id = sidcard.id and s.id=#{
    
    id}
    </select>
    <resultMap id="CardId2" type="Student">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <!--        一对一,association使用select属性引入另一条SQL语句 -->
        <association property="studentIdCard" javaType="StudentIdCard">
            <id property="id" column="card_id"/>
            <result property="code" column="code"/>
        </association>
    </resultMap>
</mapper>

Como pode ser visto no código acima, MyBatis apenas grava uma instrução SQL complexa associada a várias tabelas na forma de resultados de aninhamento e continua a usar <association>subelementos relacionados no elemento para executar o mapeamento um-para-um entre os campos da tabela do banco de dados e atributos de classe de entidade. Os resultados da execução são os mesmos, mas apenas uma instrução SQL é executada usando os resultados aninhados do MyBatis.

Perceber

Ao usar o método de consulta aninhada MyBatis para mapeamento de consulta associada, o uso do carregamento lento do MyBatis pode reduzir o consumo de execução e melhorar a eficiência da consulta até certo ponto.

O MyBatis não habilita o carregamento lento por padrão. Ele precisa ser <settings>configurado nos elementos do arquivo de configuração central mybatis-config.xml. O método de configuração específico é o seguinte.

insira a descrição da imagem aqui
No arquivo de mapeamento, <association>os elementos e <collection>elementos do mapeamento de associação MyBatis foram configurados com atributos de carregamento lento por padrão, ou seja, o atributo padrão fetchType="lazy" (o atributo fetchType="eager" significa carregamento imediato), portanto habilite carregamento lento no arquivo de configuração Depois disso, não há necessidade de configurar no arquivo de mapeamento.

2.2 Um-para-muitos

Em aplicações práticas, a aplicação de mais associações é um-para-muitos (ou muitos-para-um). Por exemplo, uma turma tem vários alunos, ou seja, vários alunos pertencem a uma turma. Como o MyBatis lida com esse relacionamento um-para-muitos? O elemento aprendido anteriormente <resultMap>contém um <collection>subelemento por meio do qual MyBatis manipula o relacionamento um-para-muitos . <collection>A maioria dos atributos do elemento filho <collection>são os mesmos do elemento, mas também contém um atributo especial - ofType. O atributo ofType corresponde ao atributo javaType e é usado para especificar o tipo de elemento contido no atributo de classe de coleção no objeto de entidade.

<collection>Os elementos podem ser configurados com referência aos dois exemplos a seguir, e o código específico é o seguinte.

insira a descrição da imagem aqui

[ Exemplo ] Depois de entender os elementos e as formas como o MyBatis lida com relacionamentos um-para-muitos, use o relacionamento um-para-muitos entre classes e alunos como um exemplo para aprender como lidar com relacionamentos um-para-muitos no MyBatis, especificamente Proceed as segue.

Passo 01 Crie duas tabelas de dados no banco de dados db_mybatis: tb_banji e tb_student, e pré-insira vários dados na tabela ao mesmo tempo.A instrução SQL executada é a seguinte.

#创建一个名称为tb_banji的表(暂添加少量字段)
CREATE TABLE tb_banji(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(32)
);
#插入两条数据
INSERT INTO tb_banji VALUES(1, '16软件技术1班');
INSERT INTO tb_banji VALUES(2, '16软件技术2班');
#创建一个名称为tb_student的表(暂时添加少量字段)
CREATE TABLE tb_student(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(32),
	sex CHAR(1),
	banji_id INT,
	FOREIGN KEY (banji_id) REFERENCES tb_banji (id)
);
#插入3条数据
INSERT INTO tb_student VALUES(1,'孙蕙','m',1);
INSERT INTO tb_student VALUES(2,'刘梦奕','f',1);
INSERT INTO tb_student VALUES(3,'无为','m',2);

Passo 02 Crie classes persistentes no pacote com.ssm.po: classe classe Banji e classe aluno Aluno, e defina propriedades e métodos relacionados nas duas classes, conforme mostrado nos arquivos 9.7 e 9.8.

//Banji.java 

package com.ssm.po;
import java.util.List;

/**
 * 功能描述
 *
 * @author: 衍生星球
 * @date: 2023年06月09日 16:07
 */

public class Banji {
    
    
    private Integer id;
    private String name;
    private List<Student> studentList;

    public Integer getId() {
    
    
        return id;
    }
    public void setId(Integer id){
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public List<Student> getStudentList() {
    
    
        return studentList;
    }

    public void setStudentList(List<Student> studentList) {
    
    
        this.studentList = studentList;
    }

    public String toString() {
    
    
        return "Banji [id=" + id + ",name=" + name + ",studentList=" + studentList + "]";
    }

}
//StudentOne.java

package com.ssm.po;

/**
 * 功能描述
 *
 * @author: 衍生星球
 * @date: 2023年06月09日 16:14
 */

public class StudentOne {
    
    
    private Integer id;
    private String name;
    private String sex;

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getSex() {
    
    
        return sex;
    }

    public void setSex(String sex) {
    
    
        this.sex = sex;
    }

    @Override
    public String toString() {
    
    
        return "StudentOne [id=" + id + ", name=" + name + ", sex=" + sex + "]";
    }
}

Etapa 03 Crie o arquivo de mapeamento de entidade de classe BanjiMapper.xml no pacote com.ssm.mapper e escreva a configuração da consulta de mapeamento de associação um-para-muitos no arquivo, conforme mostrado no arquivo.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.BanjiMapper">
    <!--一对多,查看某一班级及其关联的学生信息
    注意:若关联查出的列名相同,则需要使用别名区分-->
    <select id="findBanjiWithStudent" parameterType="Integer" resultMap="BanjiWithStudentResult">
        select b.* ,s.id as student_id,s.name
        from tb_banji b,tb_student s
        where b.id = s.banji_id and b.id=#{
    
    id}
    </select>
    <resultMap id="BanjiWithStudentResult" type="Banji">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!--一对多关系映射:collection
        ofType表示属性集合中的元素的类型List<Student>属性,即Student-->
        <collection property="studentList" ofType="Student">
            <id property="id" column="student_id"/>
            <result property="name" column="name"/>
            <result property="sex" column="sex"/>
        </collection>
    </resultMap>
</mapper>

O uso dos resultados aninhados do MyBatis no arquivo define uma instrução select que consulta a turma e as informações do aluno associadas com base no ID da turma. Como o objeto de classe retornado contém as propriedades do objeto de coleção Student, você precisa gravar manualmente as informações de mapeamento do resultado.

Passo 04 Configure o caminho do arquivo de mapeamento BanjiMapper.xml para o arquivo de configuração principal mybatis-config.xml, e seu código é o seguinte.

<mapper resource="com/ssm/mapper/BanjiMapper.xml" />

Passo 05 Escreva o método de teste findBanjiTest() na classe de teste MyBatisAssociatedTest.

	@Test
    public void findStudentByIdTest() {
    
    
        //通过工具类生成SqlSession对象
        SqlSession sqlSession = MybatisUtil.getSession();
        //执行SqlSession的查询办法,返回结果集
        Banji banji =
                sqlSession.selectOne("com.ssm.mapper.BanjiMapper.findBanjiWithStudent",1);
        System.out.println(banji.toString());
        sqlSession.close();
    }

Depois de executar o método, os resultados da saída do console são mostrados na figura. Use os resultados aninhados do MyBatis para consultar a turma e suas informações de coleção de alunos associadas. Esta é a consulta de associação um-para-muitos do MyBati.

insira a descrição da imagem aqui
Perceber

O caso acima parte da perspectiva da turma, e existe uma relação um-para-muitos entre a turma e os alunos. No entanto, da perspectiva de um único aluno, um aluno só pode pertencer a uma turma, ou seja, uma relação um-para-um.

2.3 Muitos para muitos

No desenvolvimento real do projeto, os relacionamentos muitos-para-muitos são muito comuns. Tomando alunos e cursos como exemplo, um aluno pode fazer vários cursos e um curso pode ser feito por muitos alunos. Alunos e cursos pertencem ao relacionamento muitos-para-muitos.

No banco de dados, o relacionamento muitos-para-muitos geralmente é mantido usando uma tabela intermediária. O id do aluno (student_id) na tabela intermediária electiveCourse é usado como uma chave estrangeira para se referir ao id da tabela do aluno e ao id do curso (course_id) é usado como uma referência de chave estrangeira. O id do currículo. A relação entre as três tabelas é mostrada na figura.

insira a descrição da imagem aqui

[Exemplo] Depois de entender o relacionamento muitos-para-muitos entre a tabela do aluno e a tabela do currículo no banco de dados, vamos usar um caso específico para explicar como usar o MyBatis para lidar com esse relacionamento muitos-para-muitos. As etapas de implementação específicas são do seguinte modo.

Passo 01 Crie uma tabela de dados. Crie duas tabelas de dados denominadas tb_course e tb_electiveCourse no banco de dados mybatis (a tabela tb_student foi criada no caso anterior, que é diretamente referenciado aqui) e pré-insira vários dados na tabela. A instrução SQL executada por ele é a seguinte.

#创建一个名称为tb_course的表
CREATE TABLE tb_course (
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(32),
	code VARCHAR(32)
);
#插入两条数据
INSERT INTO tb_course VALUES (1, 'Java程序设计语言','08113226');
INSERT INTO tb_course VALUES (2, 'Javaweb程序开发入门','08113228');

#创建一个名称为tb_electiveCourse的中间表
CREATE TABLE tb_electiveCourse (
	id INT PRIMARY KEY AUTO_INCREMENT,
	student_id INT,
	course_id INT,
	FOREIGN KEY (student_id) REFERENCES tb_student(id),
	FOREIGN KEY (course_id) REFERENCES tb_course(id)
);
#插入3条数据
INSERT INTO tb_electiveCourse VALUES (1,1,1);
INSERT INTO tb_electiveCourse VALUES (2,1,2);
INSERT INTO tb_electiveCourse VALUES (3,2,2);

Passo 02 Crie uma classe de curso persistente Course no pacote com.ssm.po e defina atributos e métodos relacionados na classe, conforme mostrado no arquivo.

//Course.java

package com.ssm.po;

import java.util.List;

/**
 * 功能描述
 *
 * @author: 衍生星球
 * @date: 2023年06月11日 23:01
 */

public class Course {
    
    
    private Integer id;
    private String name;
    private String code;
    private List<Student> studentlist;//于学生集合的关联属性

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getCode() {
    
    
        return code;
    }

    public void setCode(String code) {
    
    
        this.code = code;
    }

    public List<Student> getStudentlist() {
    
    
        return studentlist;
    }

    public void setStudentlist(List<Student> studentlist) {
    
    
        this.studentlist = studentlist;
    }

    @Override
    public String toString() {
    
    
        return "Course[id=" + id + ", name=" + name + ", code=" + code + "}";
    }
}

Além de adicionar as propriedades da coleção do aluno na classe de persistência do curso, também é necessário adicionar as propriedades da coleção do curso e seus métodos getter()/setter() correspondentes na classe de persistência do aluno (Student.java), e para a conveniência de visualizar Para exibir o resultado, você precisa reescrever toString(). O código adicionado na classe Aluno é mostrado abaixo.

insira a descrição da imagem aqui

Passo 03 Crie um arquivo de mapeamento da entidade do curso CourseMapper.xml e um arquivo de mapeamento da entidade do aluno StudentMapper.xml no pacote com.ssm.mapper Depois de editar os dois arquivos de mapeamento, os seguintes arquivos são mostrados.

//CourseMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.CourseMapper">
    <!--    多对多嵌套查询:通过执行一条SQL映射语句来返回预期的特殊类型-->
    <select id="findCourseWithStudent" parameterType="Integer" resultMap="CourseWithStudentResult">
        select * from tb_course where id = #{
    
    id}
    </select>
    <resultMap id="CourseWithStudentResult" type="Course">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="code" column="code"/>
        <collection property="studentlist" column="id" ofType="Student"
    select="com.ssm.mapper.StudentMapper.findStudentById">
        </collection>
    </resultMap>
</mapper>

Uma instrução select cuja id é findCourseWithStudent é definida por consulta aninhada para consultar cursos e suas informações de alunos associadas. <resultMap>O elemento é utilizado no elemento <collection>para mapear o relacionamento muitos-para-muitos, onde o atributo property indica o atributo course na classe de persistência do pedido, o atributo ofType indica que os dados da coleção são do tipo Aluno, e o atributo O valor da coluna será usado como parâmetro para executar o StudentMapper.O id definido no xml é a instrução de execução do findStudentById para consultar as informações do aluno no pedido.

//StudentMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssm.mapper.StudentMapper">
    <!--    嵌套结果,通过嵌套结果映射来处理重复的联合结果的子集-->
    <select id="findStudentById" parameterType="Integer" resultType="Student">
        select * from tb_student where id in (
        select student_id from tb_electivecourse where course_id=#{
    
    id}
        )
    </select>
</mapper>

Ele define uma instrução de execução cujo id é findStudentById, e o SQL na instrução de execução consultará as informações do aluno associadas ao curso de acordo com a id do curso. Como os cursos e os alunos estão em uma relação muitos-para-muitos, é necessário consultar as informações dos alunos por meio de uma tabela intermediária.

Etapa 04 Configure o caminho de arquivo dos arquivos de mapeamento recém-criados CourseMapper.xml e StudentMapper.xml para o arquivo de configuração principal mybatis-config.xml, o código é o seguinte.

<mapper resource="com/ssm/mapper/CourseMapper.xml" />
<mapper resource="com/ssm/mapper/StudentMapper.xml" />

Passo 05 Escreva o método de teste findCourseByIdTest() da consulta de associação muitos-para-muitos na classe de teste MyBatisAssociatedTest, e seu código é mostrado abaixo.

  /*
     *多对多嵌套查询
     */
    @Test
    public void findCourseByIdTest() {
    
    
        SqlSession sqlSession = MybatisUtil.getSession();
        //查询id为1的课程中的学生信息
        Course course =
                sqlSession.selectOne("com.ssm.mapper.CourseMapper.findCourseWithStudent",1);
        System.out.println(course);
        sqlSession.close();
    }

Use o método de consulta aninhada MyBatis para consultar os cursos e suas informações de alunos associadas. Esta é a consulta associada muitos-para-muitos MyBatis.

Se você estiver familiarizado com a instrução SQL da consulta de associação de várias tabelas, poderá usar o método de resultado aninhado em CourseMapper.xml e o código é o seguinte.

insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/weixin_45627039/article/details/131064773
Recomendado
Clasificación