Mybatis之多表查询

Mybatis之多表查询

一对一的查询(<assocation>)

创建Java类

  • 创建User类(用户类)
public class User implements Serializable {
    private static final long serialVersionUID = 6716332190979093860L;
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Department department;   //Department对象
    
​
    public Department getDepartment() {
        return department;
    }
​
    public void setDepartment(Department department) {
        this.department = department;
    }
​
    public Integer getAge() {
        return age;
    }
​
    public void setAge(Integer age) {
        this.age = age;
    }
​
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public String getPassword() {
        return password;
    }
​
    public void setPassword(String password) {
        this.password = password;
    }
​
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result
                + ((department == null) ? 0 : department.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result
                + ((password == null) ? 0 : password.hashCode());
        result = prime * result
                + ((username == null) ? 0 : username.hashCode());
        return result;
    }
​
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        User other = (User) obj;
        if (age == null) {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (department == null) {
            if (other.department != null)
                return false;
        } else if (!department.equals(other.department))
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (password == null) {
            if (other.password != null)
                return false;
        } else if (!password.equals(other.password))
            return false;
        if (username == null) {
            if (other.username != null)
                return false;
        } else if (!username.equals(other.username))
            return false;
        return true;
    }
​
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password="
                + password + ", age=" + age + ", department=" + department
                + "]";
    }
}
  • 创建Department类(部门类)
public class Department {
    private Integer id;
    private String name;
​
    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;
    }
​
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
​
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Department other = (Department) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
​
    @Override
    public String toString() {
        return "Department [id=" + id + ", name=" + name + "]";
    }
}

分析

  • 我们知道一个用户只能属于一个部门,因此这里在User类中只是使用了Department对象,而不是个集合
  • 那么我们想要查询所有的用户信息和其所在的部门信息,此时的sql语句为:select * from user u left join department d on u.department_id=d.id;。但是我们在mybaits中如果使用这条语句查询,那么返回的结果类型是什么呢?如果是User类型的,那么查询结果返回的还有Department类型的数据,那么肯定会对应不上的。
  • 我们可以使用resultMap解决对应问题

实现

  • 使用resultMap解决查询结果的对应问题
    • 这里一定要在resultMap将每一个字段和查询结果返回的字段对应上,否则此时的结果就为null
<!-- 定义resultMap -->
<resultMap type="cn.tedu.spring.entity.User" id="UserDepartment">
    <!-- 配置id的对应 -->
    <id column="id" property="id"/>
    
    <!-- 配置其他字段的对应关系
        column: 查询结果中的列名字,如果没有起别名,那么就是表中的字段名
        property: java类中的属性名称
     -->
    <result column="password" property="password"/>
    <result column="age" property="age"/>
    <result column="username" property="username"/>
    
    <!-- 配置对1的数据类型,即User类中的Department对象是单一的具体类型
        property: 这个是在User类中的字段名称
        javaType: 这个是java类的全名,是Department类的全名
     -->
    <association property="department" javaType="cn.tedu.spring.entity.Department">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
    </association>
    
</resultMap>
​
<!-- 
    User findUserAndDepartment();
    resultMap: 指定上面resultMap的id的值
 -->
 <select id="findUserAndDepartment" resultMap="UserDepartment">
    select *  from user u left join department d on u.department_id=d.id
 </select>
  • 测试方法
@Test
    public void testFindUserAndDepartment() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        List<User> users=userMapper.findUserAndDepartment();
        for (User user : users) {
            System.out.println(user);
        }
        ac.close();
    }

一对多的查询(<collection>)

  • 一个宿舍可以住多个学生,那么我们通过宿舍查询学生,那么就是一对多查询

创建Java

  • 创建Student
public class Student implements Serializable {
    private static final long serialVersionUID = 8673238196042278929L;
    private Integer id;
    private String name;
    private Integer age;
    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 Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age == null) {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
    
}
​
  • 创建Dormitory
    • 其中有一个Set<Student>集合用来存储学生对象
public class Dormitory implements Serializable{
    private static final long serialVersionUID = 1359749532219773083L;
    private Integer id;
    private String number;  //编号
    private Set<Student> students;  //学生集合,一个宿舍可以住多个学生
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((number == null) ? 0 : number.hashCode());
        result = prime * result
                + ((students == null) ? 0 : students.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Dormitory other = (Dormitory) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (number == null) {
            if (other.number != null)
                return false;
        } else if (!number.equals(other.number))
            return false;
        if (students == null) {
            if (other.students != null)
                return false;
        } else if (!students.equals(other.students))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Dormitory [id=" + id + ", number=" + number + ", students="
                + students + "]";
    }
}

创建表

  • student
create table student(id int primary key auto_increment,name varchar(10) not null unique,age int,dormitory_id int);  
  • dormitory
create table dormitory(id int primary key auto_increment,number varchar(20) not null unique);

创建DormitoryMapper.java(接口)

public interface DormitoryMapper {
    //查询所有的宿舍信息
    List<Dormitory> findDormitories();
    //根据id查询宿舍信息
    Dormitory findDormitory(Integer id);
}
​

创建DormitoryMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
​
<!-- MyBatis的接口映射文件,根节点是mapper -->
<!-- 接口映射文件是与Java接口文件(interface)相对应的 -->
<!-- 根节点的namespace属性用于指定Java接口文件 -->
<mapper namespace="cn.tedu.spring.mapper.DormitoryMapper">
    
    <!-- 定义resultMap
     -->
    <resultMap type="cn.tedu.spring.entity.Dormitory" id="DormitoryStudentRs">
        <id column="id" property="id"/>
        <result column="number" property="number"/>
        
        <!-- 因为Dormitoy中的Student使用set集合存储的,因此这里使用collection标签
            property : Java类中的集合对象
            ofType: 集合对象的泛型类型
         -->
        <collection property="students" ofType="cn.tedu.spring.entity.Student">
            
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="age" property="age"/>
        </collection>
    </resultMap>
    
    
    <!--    List<Dormitory> findDormitories();
            查询所有的宿舍信息
            resultMap: 指定前面定义的resultMap
     -->
     
     <select id="findDormitories" resultMap="DormitoryStudentRs">
        select * from student s left join dormitory d on s.dormitory_id=d.id
     </select>
     
     <!-- 
        Dormitory findDormitory(Integer id);
      -->
      <select id="findDormitory" resultType="cn.tedu.spring.entity.Dormitory">
        select * from dormitory where id=#{id}
      </select>
</mapper>

spring配置文件中添加DormitoryMapper.xml文件

    <!-- 配置SqlSessionFactoryBean -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 配置数据源:如何连接数据库等 -->
        <property name="dataSource"
            ref="dataSource" />
        <!-- 配置XML文件的位置,其中的值是一个数组 -->
        <property name="mapperLocations">
                <array> 
                    <value>classpath:mappers/UserMapper.xml</value>
                    <value>classpath:mappers/DormitoryMapper.xml</value>
                </array>
            </property>
    </bean>

测试

    @Test
    public void testFindDormitory() {
        //加载Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        //获取DormitoryMapper对象
        DormitoryMapper dormitoryMapper=ac.getBean("dormitoryMapper",DormitoryMapper.class);
        
        //执行查询方法
        List<Dormitory> dormitories=dormitoryMapper.findDormitories();
        for (Dormitory dormitory : dormitories) {
            System.out.println(dormitory);
        }
        
        ac.close();
    }

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落影的专栏

Swift学习笔记

这是一篇学习swift的笔记 Objective-C是很好的语言,Runtime机制、消息机制等也是爱不释手。 Swift一直在更新,闲暇时间学一遍。学习的B...

45370
来自专栏Kirito的技术分享

使用spring validation完成数据后端校验

前言 数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。但是为了避免用户...

1.3K120
来自专栏AI科技大本营的专栏

先搞懂这八大基础概念,再谈机器学习入门!

翻译 | AI科技大本营 参与 | 林椿眄 准备好开始AI了吗?可能你已经开始了在机器学习领域的实践学习,但是依然想要扩展你的知识并进一步了解那些你听过却没有时...

42690
来自专栏cs

串匹配算法

问题:给定二个字符串S和T,在主串S中查找子串T的过程称之为字符串匹配问题(string matching,也称之为模式匹配)。在文本处理系统,操作系统,编译系...

373100
来自专栏cs

ASP.net数据库相关操作

这是asp一个web相关代码,包括exp1.aspx主文件,修改页面UserEdit.aspx,以及登陆界面login.aspx. 原始代码---百度云 任务...

500100
来自专栏cs

ASP.NET 数据库访问

新建数据,采用sql server数据库 use dflx; create table person --建立表 ( name char(12), ...

61760
来自专栏AI科技大本营的专栏

全文来了!打败DBA老炮,机器学习如何改变数据库管理系统

作者 | Dana Van Aken、Andy Pavlo、Geoff Gordon 编译 | AI100 数据库管理系统(DBMSs)是所有数据密集型应用的...

396120
来自专栏AI科技大本营的专栏

资源 | 我们从8800个机器学习开源项目中精选出Top30,推荐给你

最近,Mybridge发布了一篇文章,对比了过去一年中机器学习领域大约8800个开源项目后,选出30个2017年度优秀的开源项目,包含机器学习开源库、数据库以及...

36970
来自专栏AI科技大本营的专栏

周末大料|CMU研发数据库调优AI,水平超DBA老炮

这个周末,最不开心的应该是优秀的数据库管理员了。 这些优秀的数据库管理员(以下简称数据库管理员为DBA),原本可以靠自己的本事,享受高薪,可是,好景不长了,因为...

43960
来自专栏Kirito的技术分享

浅析项目中的并发(一)

前言 开头扯两句,最近项目略忙,一堆零散的东西要做,没那么多时间维护文章了。又迷上了吃鸡,大雾spring security系列投入了我不少时间,但总体收获也颇...

40790

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励