Mybatis学习使用(二) —— 关联查询

来源:互联网 发布:有趣的淘宝收货人名字 编辑:程序博客网 时间:2024/05/17 02:53
  • resultMap
  • 分步查询
    • 懒加载
  • 关联查询
    • 一对一
    • 一对多

一、resultMap自定义结果映射规则

  • 1、在xxxMapper.xml 文件中自定义一个javaBean的封装规则

    <!--自定义某个javaBean的封装规则        type:自定义规则的Java类型        id:唯一id方便引用 --><resultMap type="com.fc.mybatis.bean.Employee" id="MySimpleEmp"><!--指定主键列的封装规则,id定义主键会底层有优化;        column:指定哪一列        property:指定对应的javaBean属性 -->    <id column="id" property="id"/>    <!-- 定义普通列封装规则 -->    <result column="last_name" property="lastName"/>    <!-- 其他不指定的列会自动封装:我们只要写resultMap就把全部的映射规则都写上。即下面的可省略 -->    <result column="email" property="email"/>    <result column="gender" property="gender"/></resultMap><!-- resultMap:自定义结果集映射规则;  --><!-- 对应EmployeeMapper.java接口的public Employee getEmpById(Integer id); --><select id="getEmpById"  resultMap="MySimpleEmp">    select * from tbl_employee where id=#{id}</select>

    总结:

  • 1、property对应javabean上的属性名
  • 2、column和查询数据库的列名一致(重命名后,要和重命名的名字一致)

二、数据库增改以满足关联查询

  • 一、场景一:
      查询Employee的同时查询员工对应的部门,每个员工有与之对应的部门信息;
    id last_name gender d_id did dept_name (private Department dept;)

    • 1、创建部门表tbl_dept
    • 2、在tbl_employee 员工表上增加部门id列d_id
    • 3、对tbl_employee 员工表增加约束; d_id 列关联上tbl_dept部门表的id

三、一对一查询

  • 1、联合查询:级联属性封装结果集
<!-- dept对应Employee中javabean的部门    private Department dept;--><resultMap type="com.fc.mybatis.bean.Employee" id="MyDifEmp">        <id column="id" property="id"/>        <result column="last_name" property="lastName"/>        <result column="gender" property="gender"/>        <result column="did" property="dept.id"/>        <result column="dept_name" property="dept.departmentName"/>    </resultMap>
  • 2、使用association定义关联的单个javaBean对象的封装规则
    • property="dept":指定哪个属性是联合的对象
    • javaType:指定这个属性对象的类型【不能省略】
<!--         使用association定义关联的单个对象的封装规则;     -->    <resultMap type="com.fc.mybatis.bean.Employee" id="MyDifEmp2">        <id column="id" property="id"/>        <result column="last_name" property="lastName"/>        <result column="gender" property="gender"/>        <!--  association可以指定联合的javaBean对象        property="dept":指定哪个属性是联合的对象        javaType:指定这个属性对象的类型[不能省略]        -->        <association property="dept" javaType="com.fc.mybatis.bean.Department">            <id column="did" property="id"/>            <result column="dept_name" property="departmentName"/>        </association>    </resultMap>
  • 3、xxxMapper.xml数据库语句
<!--  public Employee getEmpAndDept(Integer id);     MyDifEmp / MyDifEmp2-->    <select id="getEmpAndDept" resultMap="MyDifEmp">        SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,        d.id did,d.dept_name dept_name FROM tbl_employee e,tbl_dept d        WHERE e.d_id=d.id AND e.id=#{id}    </select>
  • 4、测试单元类
// 获取接口的实现类对象EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);System.out.println(mapper.getEmpAndDept(1));System.out.println(mapper.getEmpAndDept(1).getDept());
  • 5、使用association进行分步查询

    • 1)、先按照员工id查询员工信息
    • 2)、根据查询员工信息中的d_id值去部门表查出部门信息
    • 3)、部门设置到员工中;

    实现步骤

  • 1、在mybatis-config 配置中注册部门DepartmentMapper接口
<mapper class="com.fc.mybatis.dao.DepartmentMapper"/>
  • 2、DepartmentMapper.xml 实现select查询部门信息
<!--public Department getDeptById(Integer id);  --><select id="getDeptById" resultType="com.fc.mybatis.bean.Department">        select id,dept_name departmentName from tbl_dept where id=#{id}</select>
  • 3、EmployeeMapper.xml
      流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
    • select: 表明当前属性是调用select指定的方法查出的结果
    • column: 指定将员工表哪一列的值传到部门表中查询
    • d_id 是 tbl_employee员工表的关联部门表id的列
<!--  id  last_name  email   gender    d_id   --> <resultMap type="com.fc.mybatis.bean.Employee" id="MyEmpByStep">    <id column="id" property="id"/>    <result column="last_name" property="lastName"/>    <result column="email" property="email"/>    <result column="gender" property="gender"/>    <!-- association定义关联对象的封装规则        select:表明当前属性是调用select指定的方法查出的结果        column:指定将哪一列的值传给这个方法        流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性        d_id是tbl_employee员工表的关联部门表id的列     -->        <association property="dept"             select="com.fc.mybatis.dao.DepartmentMapper.getDeptById"            column="d_id">        </association>     </resultMap>     <!--  public Employee getEmpByIdStep(Integer id);-->     <select id="getEmpByIdStep" resultMap="MyEmpByStep">        select * from tbl_employee where id=#{id}     </select>
  • 分步查询的日志如下:
DEBUG 06-23 15:13:09,306 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:159) DEBUG 06-23 15:13:09,343 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) DEBUG 06-23 15:13:09,365 ====>  Preparing: select id,dept_name departmentName from tbl_dept where id=?   (BaseJdbcLogger.java:159) DEBUG 06-23 15:13:09,366 ====> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) DEBUG 06-23 15:13:09,368 <====      Total: 1  (BaseJdbcLogger.java:159) DEBUG 06-23 15:13:09,369 <==      Total: 1  (BaseJdbcLogger.java:159) Employee [id=1, lastName=111, email=aa@qq.com, gender=0]Department [id=1, departmentName=ha]
  • 6、在分步查询基础上实现懒加载
    mybatis-config.xml 中配置
<!-- 懒加载;显示的指定每个我们需要更改的配置的值,即使他是默认的。防止版本更新带来的问题  --><setting name="lazyLoadingEnabled" value="true"></setting><setting name="aggressiveLazyLoading" value="false"></setting>

测试类

// 获取接口的实现类对象EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);Employee employee = mapper.getEmpByIdStep(1);System.out.println(employee.getLastName());System.out.println(employee.getDept());

打印出的日志, 即调用getDept()方法才去查询数据库

DEBUG 06-23 15:59:31,908 ==>  Preparing: select * from tbl_employee where id=?   (BaseJdbcLogger.java:159) DEBUG 06-23 15:59:31,947 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) DEBUG 06-23 15:59:32,027 <==      Total: 1  (BaseJdbcLogger.java:159) 111DEBUG 06-23 15:59:32,028 ==>  Preparing: select id,dept_name departmentName from tbl_dept where id=?   (BaseJdbcLogger.java:159) DEBUG 06-23 15:59:32,028 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:159) DEBUG 06-23 15:59:32,030 <==      Total: 1  (BaseJdbcLogger.java:159) Department [id=1, departmentName=ha]

四、一对多查询

场景二:
  查询部门的时候将部门对应的所有员工信息也查询出来:注释在DepartmentMapper.xml中

  • 1、数据库操作,左拼接查询
  • 2、department.java的javabean中添加emps, 并添加get/set方法
private List<Employee> emps;
  • 3、在DepartmentMapper.java 中添加接口方法
// 查询出一个部门中所有员工public Department getDeptByIdPlus(Integer id);
  • 4、DepartmentMapper.xml 中使用collection标签定义关联的集合类型的属性封装规则
    • collection定义关联集合类型的属性的封装规则
    • ofType:指定集合里面元素的类型
<!--嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则  --><resultMap type="com.fc.mybatis.bean.Department" id="MyDept"><id column="did" property="id"/>    <result column="dept_name" property="departmentName"/>    <!--         collection定义关联集合类型的属性的封装规则         ofType:指定集合里面元素的类型    -->    <collection property="emps" ofType="com.fc.mybatis.bean.Employee">        <!-- 定义这个集合中元素的封装规则 -->        <id column="eid" property="id"/>        <result column="last_name" property="lastName"/>        <result column="email" property="email"/>        <result column="gender" property="gender"/>    </collection></resultMap><!-- public Department getDeptByIdPlus(Integer id); --><select id="getDeptByIdPlus" resultMap="MyDept">    SELECT d.id did,d.dept_name dept_name,            e.id eid,e.last_name last_name,e.email email,e.gender gender     FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id=e.d_id WHERE d.id=#{id}</select>
  • 5、一对多下的分步查询和一对一分步查询的异同点
    • 1、将单个关联对象association 换成集合关联对象 collection
    • 2、 同样property="dept" 对应上javabean的名字dept
    • 3、将多列的值封装map传递;比如:column="{deptId=id}"
    • 4、column表示传到下一步操作的列
    • 5、select指向下一步操作的方法
    • 6、fetchType=”lazy”:表示使用延迟加载;
      • lazy:延迟
      • eager:立即

问题

  • 1、Mybatis Generator代码不报错,但是没有生成文件
    解决方案:
    此种情况一般都是设置的路径有误,将从\ 换成/
    比如: ./src/main/java
原创粉丝点击