Mybatis学习笔记(三)关联查询以及相关属性

这两天学习多表查询,真的很头痛,那些属性真的很烦人,敲了两天之后才有点感觉
几年主要讲一对一和一对多的关联查询以及查询语句中相关的属性

  • 一对一的多表查询
    首先以老师和班级为例,这里假设每个老师只负责一个班
    先创建相关的表,以及插入数据
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);    

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);

其次创建两个实体类分别为Teacher和Classes类

public class Teacher {

    //定义实体类的属性,与teacher表中的字段对应
    private int id;            //id===>t_id
    private String name;    //name===>t_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 + "]";
    }
}
public class Classes {

    //定义实体类的属性,与class表中的字段对应
    private int id;            //id===>c_id
    private String name;    //name===>c_name
    
    /**
     * class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
     * 用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
     */
    private Teacher teacher;
    private List<Student> 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;
    }
    public List<Student> getStudents()
    {
    	return students;
    }
    public void setStudents(List<Student> students)
    {
    	this.students=students;
    }
    @Override
    public String toString() {
    	 return "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher
    			                + ", students=" + students + "]";
    }
}

之后我们就来创建新的mapper文件来实现关联查询

<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 type="me.gacl.domain.Classes" id="ClassResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" javaType="me.gacl.domain.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
    </resultMap>

这里出现了新的元素就是association,这就是用来和其他表进行关联的标签
property表示的就是在数据库中与之相关联的表的名称
javaType则表示的是与该相关联的表所对应的类
左后就是测试类

public class Test3 {
    public static void testGetClass(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        /**
         * 映射sql的标识字符串,
         * me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
         * getClass是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
         */
        String statement = "me.gacl.mapping.classMapper.getClass";//映射sql的标识字符串
        //执行查询操作,将查询结果自动封装成Classes对象返回
        Classes clazz = sqlSession.selectOne(statement,1);//查询class表中id为1的记录
        //使用SqlSession执行完SQL之后需要关闭SqlSession
        sqlSession.close();
        System.out.println(clazz);//打印结果:Classes [id=1, name=class_a, teacher=Teacher [id=1, name=teacher1]]
    }
	public static void main(String[] args) {
		testGetClass();
	}
}
  • 一对多的关联查询
    这里还采用上面的例子,假设一个班有多个学生
    重新创建student表
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);

因为给class增添了新的属性,所以重新修改class类,主要就是加上List的各项方法
并且创建student类

public class Student {

    //定义属性,和student表中的字段对应
    private int id;            //id===>s_id
    private String name;    //name===>s_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 + "]";
    }
}

之后在之前创建的mapper文件中在加入新的查询方法

<select id="getClass3" parameterType="int" resultMap="ClassResultMap3">
        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=#{id}
    </select>
    <resultMap type="me.gacl.domain.Classes" id="ClassResultMap3">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" javaType="me.gacl.domain.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
        <!-- ofType指定students集合中的对象类型 -->
        <collection property="students" ofType="me.gacl.domain.Student">
            <id property="id" column="s_id"/>
            <result property="name" column="s_name"/>
        </collection>
    </resultMap>

这里我们可以发现有多了一个新的标签即collection
property仍旧是代表的数据库中的表
ofType则是该表所对应的实体类
之后就是测试方法

public class Test4 {
    public static void testGetClass3(){
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        /**
         * 映射sql的标识字符串,
         * me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
         * getClass3是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
         */
        String statement = "me.gacl.mapping.classMapper.getClass3";//映射sql的标识字符串
        //执行查询操作,将查询结果自动封装成Classes对象返回
        Classes clazz = sqlSession.selectOne(statement,1);//查询class表中id为1的记录
        //使用SqlSession执行完SQL之后需要关闭SqlSession
        sqlSession.close();
        //打印结果:Classes [id=1, name=class_a, teacher=Teacher [id=1, name=teacher1], students=[Student [id=1, name=student_A], Student [id=2, name=student_B], Student [id=3, name=student_C]]]
        System.out.println(clazz);
    }
    	public static void main(String[] args) {
		testGetClass3();
	}
}

猜你喜欢

转载自blog.csdn.net/lovely__RR/article/details/89190988