Mybatis多表实战案例

前言

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

一、建立数据库

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

1、创建一些自己要用到的实体类,类中写自己要输出的字段,对应好即可

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

3、Mybatis plus提供了条件构造器,其中的queryWrapper可以实现查找指定字段。

二、案例实战

注:因为mysql不区分字段大小写,所以字段名往往会带下划线,如果要将数据库字段名与实体类对应上就需要在mybatis配置文件中开启驼峰命名

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

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

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>>的弊端了,没有奖金的员工不显示出他的奖金率。

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

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>

结果: 

扫描二维码关注公众号,回复: 14132702 查看本文章

3、查询没有奖金,且工资小于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>

结果: 

 4、案例如下:

/*现公司出台一个政策,即要给员工的工资进行一个评级,评级状况如下:
 *      工资大于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条记录还是挺多的哈,截不全请见谅!

5、案例如下:

/*查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
* 思路:该需求用到分组查询
* 1、先查询每个工种有奖金的员工的最高工资
* 2、根据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>

 结果:

6、案例如下:

/*查询员工姓名、部门名和所在城市,城市名以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>

结果: 

 7、案例如下:

/*案例:查询所有的部门里面员工个数大于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>

结果: 

8、 案例如下:

/*查询姓名中包含字符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>

结果: 

 9、 案例如下:

/*查询哪个部门没有员工
* 这里只需将部门的信息全部输出并且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>

结果: 

10、 案例如下:用的是实体类查询指定字段,自己也可以给出自己喜欢的输出格式,但不是很方便。

/*指定返回类型为实体类,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>

 结果:

猜你喜欢

转载自blog.csdn.net/qq_53860947/article/details/123810325