初学MyBatis(三)

实现关联表查询

一、一对一关联
需求
根据班级id查询班级信息(带老师的信息)

  1. 创建表和数据(一张老师表一直班级表,假设一个老师只负责一个班)
CREATE TABLE teacher(   //老师表
    t_id INT PRIMARY KEY AUTO_INCREMENT, 
    t_name VARCHAR(20)
);
     CREATE TABLE class(    //班级表
     c_id INT PRIMARY KEY AUTO_INCREMENT, 
     c_name VARCHAR(20), 
     teacher_id INT
  );
ALTER TABLE class ADD CONSTRAINT fk_teacher_id  //添加主外键关系
FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);

班级表里的teacher_id关联老师表里的t_id*

INSERT INTO teacher(t_name) VALUES('teacher1');
INSERT INTO teacher(t_name) VALUES('teacher2');
//为老师表和班级表添加数据
INSERT INTO class(c_name, teacher_id) VALUES('class_a', 1);
INSERT INTO class(c_name, teacher_id) VALUES('class_b', 2);
  1. 2

    定义班级表和老师表所对应的实体类

public class classes {
    private  int id;
    private  String name;
    private  Teacher teacher;
    private List<student> students;

    public List<student> getStudents() {
        return students;
    }

    public void setStudents(List<student> students) {
        this.students = students;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "classes{" + "id=" + id + ", name='" + name + '\'' + ", teacher=" + teacher + ", students=" + students + '}';
    }
}
public class Teacher {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Teacher{" + "id=" + id + ", name='" + name + '\'' + '}';
    }
}

2.定义sql映射文件classMapper.xml并在主配置文件config.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="mapping.classMapper">
    <!--根据班级id查询班级信息(带老师的信息)-->
    <!-- 
     方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
              封装联表查询的数据(去除重复的数据)
          select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
      -->
    <select id="getClass" parameterType="int"
    resultMap="ClassResultMap">
  SELECT *FROM  class C ,teacher t WHERE c.teacher_id=t.t_id AND c.c_id=#{id}
    </select>
    <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->

    <resultMap id="getClass" type="entity.classes">
        <id property="id" column="c_id"></id>
        <result property="name" column="c_name"></result>
        <association property="teacher" javaType="entity.Teacher">
            <id property="id" column="t_id"></id>
            <result property="name" column="t_name"></result>
        </association>
    </resultMap>

    <!-- 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
        SELECT * FROM class WHERE c_id=1;
        SELECT * FROM teacher WHERE t_id=1   //1 是上一个查询得到的teacher_id的值 -->

    <select id="getClass2" parameterType="int" resultMap="CalssResultMap2">
      SELECT * FROM class WHERE c_id=#{id}
    </select>
    <!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->

    <resultMap id="CalssResultMap2" type="entity.classes">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" parameterType="int" resultType="entity.Teacher">
        SELECT t_id id,t_name name FROM  teacher WHERE t_id=#{id}
    </select>

</mapper>
<mapper resource="mapping/classMapper.xml"/>   //此代码在config中注册classMapper.xml

3.编写测试类
方法一:

 @Test
    public void testGetClass1(){
        SqlSession session = UserMapperUtil.getSqlSession();
        String statement="mapping.classMapper.getClass1";
        classes classes =session.selectOne(statement,1);
        session.close();
        System.out.println(classes);
    }

方法二:

 @Test
    public void testGetClass2(){
        SqlSession session = UserMapperUtil.getSqlSession();
        String statement="mapping.classMapper.getClass2";
        classes classes =session.selectOne(statement,1);
        session.close();
        System.out.println(classes);
    }

一对一关联查询总结
 *MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:
property:对象属性的名称
javaType:对象属性的类型
column:所对应的外键字段名称
select:使用另一个查询封装的结果*

二、一对多关联
需求
根据classId查询对应的班级信息,包括学生,老师

  1. 创建学生表并添加数据
CREATE TABLE student(
    s_id INT PRIMARY KEY AUTO_INCREMENT, 
    s_name VARCHAR(20), 
    class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('student_A', 1);
INSERT INTO student(s_name, class_id) VALUES('student_B', 1);
INSERT INTO student(s_name, class_id) VALUES('student_C', 1);
INSERT INTO student(s_name, class_id) VALUES('student_D', 2);
INSERT INTO student(s_name, class_id) VALUES('student_E', 2);
INSERT INTO student(s_name, class_id) VALUES('student_F', 2);
  1. 定义实体类students并为classes类添加一个Lis students属性
public class student {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "student{" + "id=" + id + ", name='" + name + '\'' + '}';
    }
}
 private List<student> students; //classes添加的属性

3.修改classMapper.xml映射文件

 <!--
 根据classId查询对应的班级信息,包括学生,老师
           -->
       <!--
    方式一: 嵌套结果: 使用嵌套结果映射来处理重复的联合结果的子集
    SELECT * FROM class c, teacher t,student s WHERE c.teacher_id=t.t_id AND c.C_id=s.class_id AND  c.c_id=1 -->
 <select id="getClass3" parameterType="int" resultMap="ClassRusultMap3">
      SELECT * FROM class c,student s,teacher t WHERE c.teacher_id=t.t_id AND c.c_id=s.class_id AND c.c_id=#{id}
    </select>
    <resultMap id="ClassRusultMap3" type="classes">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" javaType="Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
         <!-- ofType指定students集合中的对象类型 -->
        <collection property="students" ofType="student">
            <id property="id" column="s_id"/>
            <result property="name" column="s_name"/>
        </collection>
    </resultMap>

4.编写测试类

 public static void main(String[] args) {
        SqlSession session = UserMapperUtil.getSqlSession();
        String statement="mapping.classMapper.getClass3";
        classes classes =session.selectOne(statement,1);
        session.close();
        System.out.println(classes);
    }

三、调用存储过程
查询得到男性或女性的数量, 如果传入的是0就女性否则是男性

  1. 创建表和存储过程
CREATE TABLE p_user(  
      id INT PRIMARY KEY AUTO_INCREMENT,  
      NAME VARCHAR(10),
      sex CHAR(2)
 ); 

 INSERT INTO p_user(NAME,sex) VALUES('A',"男");  
 INSERT INTO p_user(NAME,sex) VALUES('B',"女");  
 INSERT INTO p_user(NAME,sex) VALUES('C',"男");  

 -- 创建存储过程(查询得到男性或女性的数量, 如果传入的是0就女性否则是男性)
 DELIMITER $
 CREATE PROCEDURE mybatis.ges_user_count(IN sex_id INT, OUT user_count INT)
 BEGIN  
 IF sex_id=0 THEN
 SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='女' INTO user_count;
 ELSE
 SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='男' INTO user_count;
 END IF;
 END 
 $

 -- 调用存储过程
 DELIMITER ;
 SET @user_count = 0;
 CALL mybatis.ges_user_count(1, @user_count);
 SELECT @user_count;

2.为userMapper.xml添加配置

 <!-- 
          查询得到男性或女性的数量, 如果传入的是0就女性否则是男性
       -->
         <select id="getUserCount" parameterMap="getUserCountMap" statementType="CALLABLE">
             CALL mybatis.ges_user_count(?,?)
         </select>

        <!--
        parameterMap.put("sexid", 0);
        parameterMap.put("usercount", -1);
      -->
         <parameterMap type="java.util.Map" id="getUserCountMap">
            <parameter property="sexid" mode="IN" jdbcType="INTEGER"/>
         <parameter property="usercount" mode="OUT" jdbcType="INTEGER"/>
     </parameterMap>

3.编写测试类

 public static void main(String[] args) {
        SqlSession session = UserMapperUtil.getSqlSession();
        String statement="mapping.userMapper.getUserCount";
        Map<String,Integer> paramentMap = new HashMap<String,Integer>();
        paramentMap.put("sexid",1);
        paramentMap.put("usercount",-1);
        session.selectOne(statement,paramentMap);
        int result = paramentMap.get("usercount");
        System.out.println(result);
        session.close();
    }

猜你喜欢

转载自blog.csdn.net/qq_17773677/article/details/82588573