Mybatis多表实战案例

2022年05月13日 阅读数:6
这篇文章主要向大家介绍Mybatis多表实战案例,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

前言

花了一点时间整理了SQL的一些查询操做,包括分组查询、排序查询、case函数、自链接、内链接、外链接等,结合Mybatis完成了一个个的案例。java

1、创建数据库

该数据库包含五张表,每张表都有多个字段,博主已经上传了数据库的相关资源。在正式开始前,博主须要交代几点。在mybatis中,不管你指定仍是不指定返回类型,mybatis都会默认地先将查询完成后返回的值放入一个HashMap中(若是返回的值不止一条,就会放入一个包含HashMap的list集合中)。指定与不指定的区别在于,若是你指定了返回类型,mybatis将会根据返回类型的实体类来从HashMap中获取值并set到这个实体类中。若是不指定就默认返回HashMap<Object,Object>(List<HashMap<Object,Object>>)。在查询时,你是否遇到查询表中的某些字段,会显示该表的全部信息?如何输出特定字段呢?大概有三种方法:mysql

一、建立一些本身要用到的实体类,类中写本身要输出的字段,对应好便可sql

二、若是嫌写实体类麻烦,也能够不写,不写实体类系统就会自动建立HashMap来为你封装数据,咱们就直接拿到这个map就能够了,能够用List<Map<Object,Object>>这种通用对象来接收Mybatis的查询结果。这种方法能够偷懒,我就是用这种方法偷的懒,但在博主实践的过程当中,字段为null的时候好像不会输出,因此不是很推荐。这种不用写实体类的SQL操做,适用于字段和表名都是程序运行时产生的,实际上不少灵活性和扩展性要求比较高的应用,表的结构不可以肯定,甚至连表名字都不肯定,因此SQL语句和实体类映射字段不能被写死。数据库

三、Mybatis plus提供了条件构造器,其中的queryWrapper能够实现查找指定字段。mybatis

2、案例实战

注:由于mysql不区分字段大小写,因此字段名每每会带下划线,若是要将数据库字段名与实体类对应上就须要在mybatis配置文件中开启驼峰命名app

<settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

一、查询工资在10000到20000之间的员工名、工资以及奖金,并按工资从高到低排序ide

List<Map<Object, Object>> querySalary();
 <select id="querySalary" resultType="map">
        select first_name, salary, commission_pct
        from myemployees.employees
        where salary between 10000 and 20000
        order by salary desc
    </select>

结果: 从结果就能够看出来用List<Map<Object,Object>>的弊端了,没有奖金的员工不显示出他的奖金率。函数

二、 查询员工号为176的员工的姓名和部门号和年薪this

Map<Object, Object> queryByID(@Param("id") int employee_id);
<select id="queryByID" resultType="map">
        SELECT CONCAT(first_name,last_name) 姓名,
               department_id 部门号,
               salary * 12 * (1 + IFNULL(commission_pct, 0)) 年薪
        FROM myemployees.employees
        WHERE employee_id = #{id};
    </select>

结果: 3d

三、查询没有奖金,且工资小于18000员工的salary,first_name,并按工资从高到低排序

 注:Mybatis中使用小于号须要用转义字符,"<","&lt;"

 <select id="queryNoPct" resultType="map">
        select first_name 名字,salary 薪水
        from myemployees.employees
        where commission_pct is null and salary &lt;18000 order by salary desc
    </select>

结果: 

 四、案例以下:

/*现公司出台一个政策,即要给员工的工资进行一个评级,评级情况以下:
 *      工资大于20000的,评级为A级别
 *      工资大于15000的,评级为B级别
 *      工资大于10000的,评级为C级别
 *      工资小于10000的,均评级为D级别
 *      要求:输出员工的姓名,工资和工资评级情况,按工资高到低输出
 * */
<select id="queryByRank" resultType="map">
        select CONCAT(first_name,' ',last_name) 姓名,salary 工资,
            CASE
                    when salary>20000 then 'A级别'
                    when salary>15000 then 'B级别'
                    when salary>10000 then 'C级别'
                    else 'D级别' end as 工资级别
        from myemployees.employees
        order by salary desc
    </select>

结果: 107条记录仍是挺多的哈,截不全请见谅!

五、案例以下:

/*查询每一个工种有奖金的员工的最高工资>12000的工种编号和最高工资
* 思路:该需求用到分组查询
* 一、先查询每一个工种有奖金的员工的最高工资
* 二、根据1的结果继续筛选,选择最高工资>12000;
* */
<select id="queryByGroup" resultType="map">
        select job_id 工种编号,max(salary) 最高工资
        from myemployees.employees
        where commission_pct is not null
        GROUP BY job_id
       having 最高工资 > 12000
    </select>

 结果:

六、案例以下:

/*查询员工姓名、部门名和所在城市,城市名以s开头
* 思路:员工名出如今员工表employees中,部门名出如今departments表中,而城市名出如今       locations表中
* 此案例涉及到了三表查询,根据employees表的外键department_id链接到departments表,而后根据departments表的
* 外键location_id链接到locations表
* */
<select id="queryMoreTables" resultType="map">
        select concat(first_name,' ',last_name) 姓名,department_name 部门名,city 城市名
        from myemployees.employees e,myemployees.departments d,myemployees.locations l
        where e.department_id=d.department_id and d.location_id=l.location_id and
              city like 's%'
        order by department_name desc
    </select>

结果: 

 七、案例以下:

/*案例:查询全部的部门里面员工个数大于3的部门名以及具体的员工数量,查询结果按员工数量降序排序,
* 这里用内链接(天然链接或普通链接)去实现,内链接:就是两张表只显示符合链接条件的行(能够理解为取两张表的交集)
* 因此内链接可能会丢失信息
* */
<select id="queryInner" resultType="map">
        SELECT department_name,COUNT(*)
        FROM myemployees.departments d
        inner join myemployees.employees e
        on d.department_id=e.department_id
        GROUP BY department_name
        HAVING COUNT(*)>3
        ORDER BY  COUNT(*) desc;
    </select>

结果: 

八、 案例以下:

/*查询姓名中包含字符K的员工的名字及其上级的名字
 由于员工表中既包含打工仔和打工仔的boss,因此,能够经过员工的manager_id找到employee_id,进          而找到boss的name
* 当表中的某一个字段和这张表中另外字段相关时,能够用自链接,因此此查询使用自链接
* */
<select id="querySelfJoin" resultType="map">
        SELECT e.first_name 员工名,m.first_name 老板名
        from myemployees.employees e
                 join myemployees.employees m
                      on m.employee_id=e.manager_id
        WHERE e.first_name like '%k%';
    </select>

结果: 

 九、 案例以下:

/*查询哪一个部门没有员工
* 这里只需将部门的信息所有输出而且employee_id=null便可,因此这里用的是左外链接
* 左外链接(右边的表不加限制),以左表为基准,查询出左表全部的数据和右表中链接字段相等的记录,
  若是右表中没有对应数据,则显示为空(NULL)
* 右外链接(右边的表不加限制),以右表为基准,查询出右表全部的数据和左表中链接字段相等的记录,
  若是左表中没有对应数据,则显示为空(NULL)
* 全外链接(左右两表都不加限制),左右两表的全部字段名均列出(且各只出现一次)
  不符合on表达式的字段为null
* */
 <select id="queryNoEmployees1" resultType="map">
        SELECT d.*,e.employee_id
        FROM myemployees.departments d
            LEFT JOIN myemployees.employees e
                on d.department_id=e.department_id
        WHERE e.employee_id is NULL;
    </select>
    <select id="queryNoEmployees2" resultType="map">
        SELECT d.*,e.employee_id
        FROM myemployees.employees e
                 right JOIN myemployees.departments d
                           on d.department_id=e.department_id
        WHERE e.employee_id is NULL;
    </select>

结果: 

十、 案例以下:用的是实体类查询指定字段,本身也能够给出本身喜欢的输出格式,但不是很方便。

/*指定返回类型为实体类,Sql查询到的内容就映射到相关实体类的属性中,
* 须要用多对一来实现三表查询
* 案例:查询员工姓名、部门名和所在城市,城市名以s开头
* 分析:多个员工可能位于同一个部门,可能位于同一城市
* 也就是说多个员工关联一个部门,一个城市
*/
Employees.java
package com.pojo;

public class Employees {
    private String firstName;
    private String lastName;
    private Departments departments;
    private Locations locations;

    public Employees() {
    }

    public Employees(String firstName, String lastName, Departments departments, Locations locations) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.departments = departments;
        this.locations = locations;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Departments getDepartments() {
        return departments;
    }

    public void setDepartments(Departments departments) {
        this.departments = departments;
    }

    public Locations getLocations() {
        return locations;
    }

    public void setLocations(Locations locations) {
        this.locations = locations;
    }

    @Override
    public String toString() {
        return "姓名:" + firstName + " " + lastName +" "+ departments+" "+locations;
    }
}
Departments.java
package com.pojo;

public class Departments {
    private String departmentName;

    public Departments(){

    }

    public Departments( String departmentName) {
        this.departmentName = departmentName;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    @Override
    public String toString() {
        return " 部门名:" + departmentName ;
    }
}
Locations.java
package com.pojo;

public class Locations {
    private String city;

    public Locations(){

    }

    public Locations(String city) {
        this.city = city;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "城市名:" + city ;
    }
}
<select id="queryByGroup2" resultMap="toDepartments">
        select last_name 姓,first_name 名字,department_name 部门名,city 城市名
        from myemployees.employees e,myemployees.departments d,myemployees.locations l
        where e.department_id=d.department_id and d.location_id=l.location_id
        and city like 's%'
        order by department_name desc
    </select>
    <resultMap id="toDepartments" type="Employees" >
        <result property="lastName" column="姓"/>
        <result property="firstName" column="名字"/>
        <association property="departments" javaType="Departments">
            <result property="departmentName" column="部门名"/>
        </association>
        <association property="locations" javaType="Locations">
            <result property="city" column="城市名"/>
        </association>
    </resultMap>

 结果: