MyBatis之resultMap的作用和xml配置折騰

原文博客:http://blog.csdn.net/iaiti/article/details/53227880
簡單的搭建。

MyBatis實戰——前身iBatis、基礎環境搭建和如何”釣魚” 這篇寫了基礎的環境搭建和代碼操作。

我這裏是使用了xml加interface結合的方法進行操作。現有Employee類。如果是簡單的select,可以看看下面簡單的例子。

Employee.Java

public class Employee {//省略get set 方法  
    private int id;  
    private String first_name;  
    private String last_name;  
    private int salary;  
}  

EmployeeMapper.java

package com.mybatis3.mappers;  

import model.Employee;  

public interface EmployeeMapper  
{  
    Employee findEmployeeById(Integer a);  
}  

EmployeeMapper.xml(和EmployeeMapper.java位於同個package中

<?xml version="1.0" encoding="UTF-8" ?>    
<!DOCTYPE mapper    
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">    
<mapper namespace="com.mybatis3.mappers.EmployeeMapper">    
  <select id="findEmployeeById" resultType="model.Employee">    
    select * from Employee where id = #{abc} <!-- 後面發現這個參數名這裏填什麼都無所謂,能映射到 -->  
  </select>    
</mapper>    

mybatis-config.xml的mappers映射改成:

<mapper class="com.mybatis3.mappers.EmployeeMapper" />  

進行查詢操作。

public class Factory {    
    public static void main(String[] args) {    
        String configxml = "mybatis-config.xml";    
        InputStream is = null;    
        try {    
            is = Resources.getResourceAsStream(configxml);    
        } catch (IOException e) {    
            e.printStackTrace();    
        }    
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);    
        SqlSession s = sf.openSession();    
        EmployeeMapper employeeMapper =  s.getMapper(EmployeeMapper.class);  
        Employee e =  employeeMapper.findEmployeeById(47);  
        System.out.println(e.getFirst_name());    
        System.out.println(e.getLast_name());    
        System.out.println(e.getSalary());   
        s.close();    
    }    
}    

這是單表查詢的時候,那麼問題就來了。如果是多表複雜的查詢。現在有了一張新表Employer,假如你是框架的設計者,會讓Employee的字段全部丟到Employer中嗎,顯然不合適。

這是MyBatis提供了resultmap的方法。先看看單獨一個類也可以使用resultmap進行映射。

Employer類

public class Employer {  
    private int id;//省略set get 方法  
    private int employee_id;  
    private String name;  
    private Employee em;  
}  

EmployerMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>    
<!DOCTYPE mapper    
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

<mapper namespace="com.mybatis3.mappers.EmployerMapper">  
    <resultMap id="Employer" type="model.Employer">  
        <id property="id" column="id" />  <!-- id相當於resultmap的引用的唯一標識-->  
        <result property="name" column="name" />  <!-- property對應javabean的屬性名,column對應數據庫字段名 -->  
        <result property="employee_id" column="employee_id" />  
    </resultMap>  

    <select id="findEmployeeById" resultMap="Employer">  
        select * from Employer where id = #{abc}  
    </select>  
</mapper>  

測試:

public class Factory {    
    public static void main(String[] args) {    
        String configxml = "mybatis-config.xml";    
        InputStream is = null;    
        try {    
            is = Resources.getResourceAsStream(configxml);    
        } catch (IOException e) {    
            e.printStackTrace();    
        }    
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);    
        SqlSession s = sf.openSession();    
        EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);  
        Employer e2 =  employerMapper.findEmployeeById(1);  
        System.out.println(e2.getEmployee_id());  
        System.out.println(e2.getName());  
        s.close();    
    }    
}    

折騰resultMap的id,result屬性:

接下來開始折騰了。將EmployerMapper.xml裏面改成只剩:

<resultMap id="Employer" type="model.Employer">  
</resultMap>  

<select id="findEmployeeById" resultMap="Employer">  
    select * from Employer where id = #{abc}  
</select>  

發現還是能正常映射。但是如果改javabean的一個屬性:

private int employeeid;  
public int getEmployeeid() {  
    return employeeid;  
}  
public void setEmployeeid(int employee_id) {  
    this.employeeid = employee_id;  
}  

這樣最後取值是取不到的,因爲映射不到。那究竟是屬性名還是通過getset方法的名字映射呢。再折騰:

private int employeeid;  
public int getEmployee_id() {  
    return employeeid;  
}  
public void setEmployee_id(int employee_id) {  
    this.employeeid = employee_id;  
}  

employeeid屬性名與數據庫字段名不對應,但是get,set的方法名是和數據庫字段名對應的。運行正常。

如果不想在配置這裏瞎折騰,JavaBean字段名保持和數據庫字段名是最好的選擇。

折騰resultMap extends屬性,表關聯查詢。

Employer.xml

<?xml version="1.0" encoding="UTF-8" ?>    
<!DOCTYPE mapper    
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"    
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  

<mapper namespace="com.mybatis3.mappers.EmployerMapper">  
    <resultMap id="Employer" type="model.Employer">  
    </resultMap>  
    <resultMap type="model.Employer" id="EmployerWithEmployee"  
        extends="Employer">  
        <result property="em.id" column="id" />  
        <result property="em.first_name" column="first_name" />  
        <result property="em.last_name" column="last_name" />  
        <result property="em.salary" column="salary" />  
    </resultMap>  
    <select id="findEmployeeById2" resultMap="EmployerWithEmployee">  
        select employee_id,name,b.first_name,b.salary,b.last_name from Employer a  
        left join Employee b on a.employee_id=b.id where a.id = #{abc}  
    </select>  
</mapper>  

測試:

SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);    
SqlSession s = sf.openSession();    
EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);  
Employer e2 =  employerMapper.findEmployeeById2(1);  
System.out.println(e2.getEmployee_id());  
System.out.println(e2.getName());  
System.out.println(e2.getEm().getFirst_name());  
System.out.println(e2.getEm().getLast_name());  

注意這次的em不再是和上面第一個折騰的一樣,是和方法名一致的。這次是和屬性名一致。不然會報錯。

而且MyBatis的關聯查詢就這麼簡單,還是一樣的關聯語句,只不過加了一些映射配置。

折騰association

extends拓展看起來挺好,但是講到解耦的話,你extends出來是個不倫不類的東西。本身我就有Employee的存在。

所以,這時association出現了。

<mapper namespace="com.mybatis3.mappers.EmployerMapper">  
    <resultMap id="Employee" type="model.Employee">  
        <id property="id" column="id" />  
        <result property="first_name" column="first_name" />  
        <result property="last_name" column="last_name" />  
        <result property="salary" column="salary" />  
    </resultMap>  

    <resultMap id="Employer" type="model.Employer">  
        <id property="id" column="id" />  <!-- id相當於resultmap的引用的唯一標識-->  
        <result property="name" column="name" />  <!-- property對應javabean的屬性名,column對應數據庫字段名 -->  
        <result property="employee_id" column="employee_id" />  
        <association property="em" resultMap="Employee" />  
    </resultMap>  
    <select id="findEmployeeById2" resultMap="Employer">  
        select employee_id,name,b.first_name,b.salary,b.last_name from Employer a  
        left join Employee b on a.employee_id=b.id where a.id = #{abc}  
    </select>  
</mapper>  

測試代碼不變:

SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(is);    
SqlSession s = sf.openSession();    
EmployerMapper employerMapper =  s.getMapper(EmployerMapper.class);  
Employer e2 =  employerMapper.findEmployeeById2(1);  
System.out.println(e2.getEmployee_id());  
System.out.println(e2.getName());  
System.out.println(e2.getEme().getFirst_name());  
System.out.println(e2.getEme().getLast_name());  
s.close();    

但是不同於resultmap使用extends,result標籤是不可少的,一旦少了,將獲取不到其屬性值。

經過上面種種折騰之後終於知道作者講的作用是什麼:最後就明白了書上所講的ResultMap的作用,映射SQL選擇聲明的結果到JavaBean屬性中。通過一對一和一對多associations可以將簡單選擇聲明映射覆雜的聲明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章