1. 程式人生 > >4.mapper.xml對映檔案詳解

4.mapper.xml對映檔案詳解

1.parameterType(輸入型別)

parameterMap已經被廢棄,這裡不做討論.

先了解:#{}${}的使用
#{}實現的是向prepareStatement中的預處理語句中設定引數值,sql語句中#{}表示一個佔位符即?。
使用佔位符#{}可以有效防止sql注入,在使用時不需要關心引數值的型別,mybatis會自動進行java型別和jdbc型別的轉換。
#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱。
${}#{}不同,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc型別轉換,${}

可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。
使用${}不能防止sql注入,但是有時用${}做模糊查詢會非常方便.
關於{}與${}的心得:
1. #{}向prepareStatement中的預處理語句中設定引數值相當於?.
2. #{}可以防止sql注入,如果parameterType傳輸單個簡單型別值,#{}括號中可以是value或其它名稱.(一般寫value或者用到的屬性名字)
3. 如果parameterType傳輸單個簡單型別值,${}括號中只能是value。

使用#{}時,簡單型別時,可以是任意值,一般為#{value}

,或者為想對應Bean的欄位名,eg: #{id}

    <select id="findUserById" parameterType="int"
    resultType="cn.com.yves.project1.model.UserModel">
    SELECT * FROM `user` WHERE id=#{任意值}
    </select>

使用${}時,簡單型別時,只能是${value}

<select id="selectUserByName" parameterType="string"
    resultType=
" cn.com.yves.project1.model.UserModel "> select * from user where username like '%${value}%' </select>

1.傳遞-簡單型別

    <select id="findUserById" parameterType="int"
    resultType="cn.com.yves.project1.model.UserModel">
    SELECT * FROM `user` WHERE id=#{任意值}
    </select>

2.傳遞-pojo物件

<!—傳遞pojo物件綜合查詢使用者資訊:指定性別,模糊名字 -->
<select id="findUserByUser" parameterType="cn.com.yves.project1.model.UserModel"
    resultType="cn.com.yves.project1.model.UserModel">
    select * from user where sex=#{sex} and username like
    '%${username}%'
</select>

3.傳遞-pojo包裝物件

開發中通過pojo傳遞查詢條件 ,查詢條件是綜合的查詢條件,不僅包括使用者查詢條件還包括其它的查詢條件.

pojo程式碼:

 public class UserModel {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //這裡省略get 和set 方法
}
public class QueryFilterModel {
    private UserModel uModel;

    // 定義UserModel的擴充套件類
    // private UserCustomModel customModel;

    // 一些其他需要定義的欄位或者javaBean
    // 這裡省略相應的get 和set方法
}

mapper.xml對映檔案程式碼:

<!-- 高階查詢部分 -->
<select id="findUserByQueryFilterModel" parameterType="cn.com.yves.project1.model.QueryFilterModel"
        resultType="cn.com.yves.project1.model.UserModel">
        SELECT * FROM `user` WHERE sex=#{uModel.sex} and username LIKE
        '%${uModel.username}%'
</select>

說明:mybatis底層通過ognl從pojo中獲取屬性值:#{uModel.sex},uModel即是傳入的包裝物件QueryFilterModel的屬性。sex又是uModel物件中的屬性.

4.傳遞-hashmap

介面方法:

// 根據多個id來查詢出多個結果
public abstract List<UserModel> findUsersByMap(HashMap<String, Object> map) throws Exception;

對映檔案:

<!-- 傳入引數是hashmap, #{}裡面填寫map裡面的key就可以獲取對應的值 -->
<select id="findUsersByMap" parameterType="hashmap"
    resultType="cn.com.yves.project1.model.UserModel">
    SELECT * FROM `user`
    WHERE sex=#{sex} and username=#{name}
</select>

測試程式碼:

    // 測試傳入引數為hashmap的方法
    @Test
    public void testFindUsersByMap() throws Exception {
        // 產生SqlSession連線
        SqlSession sqlSession = sqlFactory.openSession();

        // 產生mapper代理物件, 相當於介面的實現類
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        HashMap<String, Object> map = new HashMap<>();
        map.put("sex", "男");
        map.put("name", "yves");

        // 呼叫方法
        List<UserModel> list = userMapper.findUsersByMap(map);

        // 關閉sqlSession
        sqlSession.close();
    }

2.resultType(輸出型別)

1.輸出-簡單型別

pojo類:

public class UserModel {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //此處省略get 和set方法...
}
public class QueryFilterModel {
    private UserModel uModel;

    // 定義UserModel的擴充套件類
    private UserCustomModel customModel;

    // 一些其他需要定義的欄位或者javaBean
    //省略get set方法
}

dao層介面:

public int findUsersCount(QueryFilterModel queryFilterModel);

mapper.xml中sql語句:

<select id="findUsersCount" parameterType="cn.com.yves.project1.model.QueryFilterModel"
    resultType="int">
    SELECT COUNT(*) FROM `user` WHERE username
    =#{uModel.username}
</select>

測試程式碼:

@Test
    public void findUsersCount() {

        // 產生SqlSession連線
        SqlSession sqlSession = sqlFactory.openSession();

        // 產生mapper代理物件, 相當於介面的實現類
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        QueryFilterModel queryFilterModel = new QueryFilterModel();
        UserModel userModel = new UserModel();
        userModel.setUsername("Yves");
        queryFilterModel.setuModel(userModel);

        // 呼叫方法
        int count = userMapper.findUsersCount(queryFilterModel);

        // 關閉sqlSession
        sqlSession.close();
    }

2.輸出-pojo物件

pojo類:

public class UserModel {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //此處省略get 和set方法...
}

dao層方法:

    public abstract UserModel findUserById(int id) throws Exception;

mapper.xml中sql語句:

    <select id="findUserById" parameterType="int"
        resultType="cn.com.yves.project1.model.UserModel">
        SELECT * FROM `user` WHERE id=#{任意值}
    </select>

測試程式碼:

    @Test
    public void testFindUserById() throws Exception {

        // 產生SqlSession連線
        SqlSession sqlSession = sqlFactory.openSession();

        // 產生mapper代理物件, 相當於介面的實現類
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 呼叫方法
        UserModel userModel = userMapper.findUserById(10);

        // 關閉sqlSession
        sqlSession.close();
    }

3.輸出-pojo列表

pojo類:

public class UserModel {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //此處省略get 和set方法...
}
public class QueryFilterModel {
    private UserModel uModel;

    // 定義UserModel的擴充套件類
    private UserCustomModel customModel;

    // 一些其他需要定義的欄位或者javaBean
    //省略get set方法
}

dao層介面:

    // 根據模糊名字來查詢:輸出型別為list 或者陣列時候
    // public UserModel[] findUsersByFuzzyName(UserModel userModel);
    public List<UserModel> findUsersByFuzzyName(UserModel userModel);

mapper.xml中sql語句:

    <select id="findUsersByFuzzyName" parameterType="cn.com.yves.project1.model.UserModel"
        resultType="cn.com.yves.project1.model.UserModel">
        SELECT * FROM `user` WHERE username LIKE
        "%${username}%"
    </select>

測試程式碼:

    // 根據模糊名字來查詢
    @Test
    public void testFindUsersByFuzzyName() {

        // 產生SqlSession連線
        SqlSession sqlSession = sqlFactory.openSession();

        // 產生mapper代理物件, 相當於介面的實現類
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        UserModel userModel = new UserModel();
        userModel.setUsername("Yves");

        // 呼叫方法
        List<UserModel> list = userMapper.findUsersByFuzzyName(userModel);

        // 關閉sqlSession
        sqlSession.close();
    }

4.輸出-hashmap

實用效能不如定義resultMap後引用resultMap.

3.resultMap輸出型別

  • resultType可以指定pojo將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致方可對映成功。
  • 如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係,resultMap實質上還需要將查詢結果對映到pojo物件中。
  • resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現一對一查詢和一對多查詢。
  • 用到的pojo
public class UserModel {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //此處省略get set方法
}
public class ViewVo {
    private String aaa;
    private String bbb;

    // ... 還可以定義成一些要顯示的欄位
    //  這裡篇幅有限,省略了get和set方法
}
  • 1.dao層介面
// 根據UserModel的id屬性來查找出資料庫裡面的列,然後通過resultMap來對映到顯示層的ViewVo中
// (通常用作高階查詢中的關聯查詢,然後將對應的列對映到ViewVo中)
public ViewVo findUserByIdViewVoResultMap(UserModel userModel);
// 如果返回結果是陣列或者list其他不變只改變介面的返回值為陣列或list
// public List<ViewVo> findUserByIdViewVoResultMap(UserModel userModel);
  • 2.定義resultMap
<!--  定義resultMap 將SELECT id id_,username username_ FROM USER 和User類中的屬性作一個對映關係 
    type:resultMap最終對映的java物件型別,可以使用別名 
    id:對resultMap的唯一標識 
-->
<resultMap type="cn.com.yves.project1.model.ViewVo" id="viewVoResultMap">

    <!-- id標籤表示查詢結果集中唯一標識,資料庫中的key欄位
       column:查詢出來的列名
       property:type指定的pojo型別中的屬性名 最終resultMap對column和property作一個對映關係 (對應關係)
    -->
    <id column="id_" property="aaa" />

    <!-- result:對普通名對映定義
       column:查詢出來的列名
       property:type指定的pojo型別中的屬性名 最終resultMap對column和property作一個對映關係(對應關係)
    -->
    <result column="username_" property="bbb" />

</resultMap>
  • 3.使用resultMap
<!-- resultMap:指定定義的resultMap的id,如果這個resultMap在其它的mapper檔案,前邊需要加namespace -->
<select id="findUserByIdViewVoResultMap" parameterType="cn.com.yves.project1.model.UserModel"
    resultMap="viewVoResultMap">
    SELECT id id_,username username_ FROM USER WHERE id=#{id}
</select>