mybatis学习--自定义映射resultMap

1.1、resultMap处理字段和属性的映射关系

如果字段名和实体类中的属性名不一致的情况下,可以通过resultMap设置自定义映射。

常规写法

/**
 *根据id查询员工信息
 * @param empId
 * @return
 */
Emp getEmpByEmpId(@Param("empId") Integer empId);

    <select id="getEmpByEmpId" resultType="emp">
        select * from emp where emp_id = #{empId}
    </select>
    
@Test
public void testGetEmpByEmpId(){
   Emp emp = empMapper.getEmpByEmpId(2);
    System.out.println(emp);
}

结果:查出的id和name为空值

解决:

⑴可以通过为字段起别名的方式,别名起成和属性名一致。保证字段名和实体类中的属性名一致

<select id="getEmpByEmpId" resultType="emp">
    select emp_id empId,emp_name empName,age,sex from emp where emp_id = #{empId}
</select>

⑵如果字段名和实体类中的属性名不一致的情况下,但是字段名符合数据库的规则(使用_),实体类中使用的属性名符合java的规则(使用驼峰命名),可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中的数据时,自动将带下划线“_”的字段名转为驼峰命名

 user_name:userName

 emp_id:empId

mybatis-config.xml文件中

<settings> 
        <!--将数据库字段名的下划线映射为驼峰-->   
        <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);--> 
<select id="getEmpByEmpId" resultType="emp">
    select * from emp where emp_id = #{empId}  
</select>

⑶使用resutlMap自定义映射处理

<select id="getEmpByEmpId" resultMap="empResultMap">
    select * from emp where emp_id = #{empId}
</select>

<resultMap id="empResultMap" type="emp">
    <id property="empId" column="emp_id"></id>
    <result property="empName" column="emp_name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>
</resultMap>

1.2一对一映射处理

1、级联方式处理
/** 
* 根据id查询人员信息 
* @param id 
* @return
 */ 
 Person findPersonById(@Param("id") Integer id);

<!-- Person findPersonById(Integer id);--> 
 <select id="findPersonById" resultMap="IdCardWithPersonResult">
    SELECT person.*,idcard.code
    FROM person,idcard
    WHERE person.card_id=idcard.id AND person.id=#{id} 
 </select>

  <resultMap id="IdCardWithPersonResult" type="person">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result> 
   <result property="card.id" column="id"></result>
    <result property="card.code" column="code"></result>
</resultMap>

@Test
public void testFindPersonById(){
    Person person = personMapper.findPersonById(2);
    System.out.println(person);
}
2、Association
<resultMap id="IdCardWithPersonResult2" type="person">

    <id property="id" column="id"></id>

    <result property="name" column="name"></result>

    <result property="age" column="age"></result>

    <result property="sex" column="sex"></result>
    <!--association 一对一,多对一-->
    <association property="card" javaType="IdCard">

        <id property="id" column="id"></id>

        <result property="code" column="code"></result>

    </association>

</resultMap>
3、分步查询
<!--分步查询第一步-->
<!-- Person findPersonById3(@Param("id") Integer id);-->
  <select id="findPersonById3" resultMap="IdCardWithPersonResult3">
    select * from person where id=#{id}  
</select>

  <resultMap id="IdCardWithPersonResult3" type="person">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="age" column="age"></result>
    <result property="sex" column="sex"></result>      
 
 <association property="card" javaType="IdCard" column="card_id"                 select="com.qcby.mybatis.mapper.IdCardMapper.findCodeById"> 
     </association>
</resultMap>
<!--分步查询的第二步-->
<!--IdCard findCodeById(@Param("id") Integer id);-->
  <select id="findCodeById" resultType="idcard"> 
   SELECT * from idcard where id=#{id} 
 </select>

1.3多对一映射处理

场景模拟:

查询员工信息以及员工所对应的部门信息

使用resultMap自定义映射处理处理多对一的映射关系:

1.级联方式处理
/**
 * 获取员工以及所对应的部门信息
 * @param empId
 * @return
 */
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);

<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">
    select emp.*,dept.*
    from emp
    left join dept
    on emp.dept_id=dept.dept_id
    where emp.emp_id=#{empId}
</select>

//此处注意要先写column,在写property
<resultMap id="empAndDeptResultMap" type="emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>
    <result column="dept_id" property="dept.deptId"></result>
    <result column="dept_name" property="dept.deptName"></result>
</resultMap>

@Test
public void testGetEmpAndDeptByEmpId(){
    Emp emp = empMapper.getEmpAndDeptByEmpId(1);
    System.out.println(emp);
}
 2.association
<resultMap id="empAndDeptResultMap" type="emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>
    <association property="dept" javaType="dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
    </association>
</resultMap>
3.分步查询
/**
 * 通过分步查询来查询员工以及所对应的部门信息的第一步
 * @param empId
 * @return
 */
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);

<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptResultMap2">
    select * from emp where emp_id = #{empId}
</select>
<resultMap id="empAndDeptResultMap2" type="emp">
    <id column="emp_id" property="empId"></id>
    <result column="emp_name" property="empName"></result>
    <result column="age" property="age"></result>
    <result column="sex" property="sex"></result>
    <association property="dept" column="dept_id"
                select="com.qc.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo">
    </association>
</resultMap>
/**
 * 通过分步查询来查询员工以及所对应的部门信息的第二步
 * @param deptId
 * @return
 */
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);

<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTwo" resultType="dept">
    select * from dept where dept_id='${deptId}'
</select>

测试:

@Test
public void testGetEmpAndDeptByStepOne(){
    Emp emp = empMapper.getEmpAndDeptByStepOne(3);
    System.out.println(emp);
}

分步查询的优点:可以实现延迟加载(懒加载),但是必须在核心配置文件中设置全局配置信息:

lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有管理对象都会延迟加载

aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载,此时就可以实现按需加载,获取的数据是什么,就会执行相应的sql语句

此时可以通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”

1.4一对多映射处理 

没有级联方式的查询,只有collection 和分步查询

8.4.1 collection

dept接口

/**
 * 查询部门以及部门中的员工信息
 * @param deptId
 * @return
 */
  Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);

dept映射文件中

<!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);--> 
 <select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
    SELECT *    FROM dept    LEFT JOIN emp    ON dept.dept_id=emp.dept_id    WHERE dept.dept_id=#{deptId} 
 </select>
  <resultMap id="deptAndEmpResultMap" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result> 
   <!--ofType:设置集合类型的属性中存储的数据的类型--> 
   <collection property="emps" ofType="emp">
        <id column="emp_id" property="empId"></id>
        <result column="emp_name" property="empName"></result>
        <result column="age" property="age"></result>
        <result column="sex" property="sex"></result>
    </collection>
</resultMap>

测试方法

@Test  public  void testGetDeptAndEmpByDeptId(){
    Dept dept = deptMapper.getDeptAndEmpByDeptId(1);
    System.out.println(dept);
}
1.4.2分步查询

员工表设计

 部门表设计

⑴查询部门信息

/**
 * 通过分步查询进行查询部门及部门中的员工信息的第一步:查询部门信息
 * @param deptId
 * @return 
*/ 
 Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);

<!-- Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);-->
  <select id="getDeptAndEmpBySetpOne" resultMap="deptAndEmpResultMapByStep">
    select * from dept where dept_id = #{deptId}  </select>
  <resultMap id="deptAndEmpResultMapByStep" type="dept">
    <id column="dept_id" property="deptId"></id>
    <result column="dept_name" property="deptName"></result>
      <collection property="emps" column="dept_id"                select="com.qcby.mybatis.mapper.EmpMapper.getDeptAndEmpBySetpTwo">
</collection>
</resultMap>

⑵查询员工信息

/**
 * 通过分步查询进行查询部门及部门中的员工信息的第二步:查询员工信息
 * @param deptId
 * @return 
*/  
List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);

<!-- List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);-->
  <select id="getDeptAndEmpBySetpTwo" resultType="emp">
    select  * from  emp where dept_id = #{deptId} 
 </select>

⑶测试方法

@Test
  public void testGetDeptAndEmpBySetp(){
    Dept dept = deptMapper.getDeptAndEmpBySetpOne(2);
    System.out.println(dept);
}

1.5多对多映射关系

商品和订单两者之间的关系  一种商品存在多个订单中、一个订单存在多个商品

创建一个中间表来描述两者的关联关系

商品的表结构

订单的表结构

中间表

1.5.3 分步查询

⑴查询订单信息

/**
 * 通过分步查询进行查询订单以及订单中的商品信息的第一步
 * @param id 
* @return
 */  List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);
<!-- List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);-->
  <select id="findOrdersWithProduct2" resultMap="OrdersWithProductResult2">
    select * from  orders where id = #{id} 
 </select>

<resultMap id="OrdersWithProductResult2" type="orders">
    <id column="id" property="id"></id>
    <result column="number" property="number"></result>
      <collection property="productList" column="id" ofType="product"                select="com.qcby.mybatis.mapper.ProductMapper.findProductById"> 
   </collection>
</resultMap>

⑵查询商品信息

/**
 * 通过分步查询进行查询订单以及订单中的商品信息的第二步
 * @param id
 * @return */
  List<Product> findProductById(@Param("id") Integer id);

<!--List<Product> findProductById(@Param("id") Integer id);-->
  <select id="findProductById" resultType="product">
    select * from product where id in(
    select product_id from ordersitem where orders_id = #{id}    )  
</select>

⑶测试

@Test
  public void testFindOrdersWithProduct2(){ 
   List<Orders> orders = ordersMapper.findOrdersWithProduct2(1);    orders.forEach(System.out::println);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值