1. 程式人生 > >Spring+SpringMVC+MyBatis深入學習及搭建(四)——MyBatis輸入對映與輸出對映

Spring+SpringMVC+MyBatis深入學習及搭建(四)——MyBatis輸入對映與輸出對映

1. 輸入對映

通過parameterType指定輸入引數的型別,型別可以是簡單型別、hashmap、pojo的包裝型別。

1.1 #{}與${}

#{}實現的是向prepareStatement中的預處理語句設定引數值,sql語句中#{}表示一個佔位符即?

<select id="findUserById" parameterType="int" resultType="user">
   select * from user where id=#{id}
</select>

使用佔位符#{}可以有效防止sql注入,在使用時不需要關係引數值的型別,mybatis會自動進行java型別和jdbc型別的轉換。#{}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個型別值,#{}括號可以是value或其它名稱。

${}和#{}不同,通過${}可以將parameterType傳入的內容拼接在sql中且不進行jdbc型別轉換,${}可以接收簡單型別值或pojo屬性值,如果parameterType傳輸單個簡單型別值,${}括號中只能是value。使用${}不能防止sql注入,但是有時用${}會非常方便,如下例子:

    <select id="findUserByName" parameterType="java.lang.String" resultType="joanna.yan.mybatis.entity.User">
        select * from user where username LIKE '%${value}%'
    
</select>

如果本例子使用#{}則傳入的字串中必須要有%,而%是人為拼接在引數中,顯然有點麻煩,如果採用${}在sql中拼接為%的方式則在呼叫mapper介面傳遞引數就方便很多。

//如果使用佔位符號則必須人為在傳引數中加%
List<User> list = userMapper.selectUserByName("%管理員%");
//如果使用${}原始符號則不用人為在引數中加%
List<User>list = userMapper.selectUserByName("管理員");

再比如order by排序,如果將列名通過引數傳入sql,根據傳的列名進行排序,應該寫為:ORDER BY ${columnName}

如果使用#{}將無法實現此功能。

1.2 傳遞簡單型別

參考上邊的例子。

1.3 傳遞pojo物件

mybatis使用ognl表示式解析物件欄位的值,如下例子:

     <!--傳遞pojo物件綜合查詢使用者資訊  -->
     <select id="findUserByUser" parameterType="user" resultType="user">
         select * from user where id=#{id} and username like '%${username}%'
     </select>

sql中紅色標註的是user物件中的欄位名稱。

測試:

    @Test
    public void findUserByUserTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setId(10);
        user.setUsername("張三");
        List<User> list=userMapper.findUserByUser(user);
        System.out.println(list);
        sqlSession.close();
    }

1.4 傳遞pojo包裝物件

開發中通過pojo傳遞查詢條件,查詢條件是綜合的查詢條件,不僅包括使用者查詢條件,還包括其它的查詢條件(比如將使用者購買的商品資訊也作為查詢條件),這時可以使用包裝物件傳遞輸入引數。

1.4.1 需求

完成使用者資訊的綜合查詢,需要傳入查詢條件很複雜(可能包括使用者資訊、其它資訊,比如商品、訂單等)

1.4.2 定義包裝型別pojo

針對上邊需求,建議使用自定義的包裝型別的pojo,在包裝型別的pojo中將複雜的查詢條件包裝進去。

/**
 * 包裝型別
 * @author Joanna.Yan
 *
 */
public class UserQueryVo {
    //在這裡包裝所需要的查詢條件
    
    //使用者查詢條件
    private UserCustom userCustom;

    public UserCustom getUserCustom() {
        return userCustom;
    }

    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }
    
    //可以包裝其它的查詢條件,訂單、商品
    //......
}

1.4.3 mapper.xml

 在UserMapper.xml中定義使用者資訊綜合查詢(查詢條件複雜,通過高階查詢進行復雜關聯查詢)

    <!--使用者資訊綜合查詢 
    UserQueryVo中定義了userCustom屬性
    #{userCustom.sex}:取出pojo包裝物件中性別值
    ${userCustom.username}:取出pojo包裝物件中使用者名稱稱
     -->
    <select id="findUserList" parameterType="joanna.yan.mybatis.entity.UserQueryVo" resultType="joanna.yan.mybatis.entity.UserCustom">
        SELECT * FROM USER WHERE user.sex=#{userCustom.sex} AND user.username LIKE '%${userCustom.username}%'
    </select>

1.4.4 mapper.java

//使用者資訊綜合查詢
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

1.4.5 測試程式碼

    @Test
    public void findUserListTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //建立包裝物件,設定查詢條件
        UserQueryVo userQueryVo=new UserQueryVo();
        UserCustom userCustom=new UserCustom();
        userCustom.setSex("1");
        userCustom.setUsername("張三丰");
        userQueryVo.setUserCustom(userCustom);
        List<UserCustom> list=userMapper.findUserList(userQueryVo);
        System.out.println(list);
    }

1.5 傳遞hashmap

sql對映檔案定義如下:

    <!--傳遞hashmap綜合查詢使用者資訊  -->
    <select id="findUserByHashmap" parameterType="hashmap" resultType="user">
        select * from user where id=#{id} and username like '%${username}%'
    </select>

sql中紅的標註的是hashmap的key。

mapper.java:

//傳遞hashmap綜合查詢使用者資訊
public List<User> findUserByHashmap(HashMap<String, Object> map) throws Exception;

測試:

    @Test
    public void findUserByHashmapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        //構造查詢條件HashMap物件
        HashMap<String, Object> map=new HashMap<>();
        map.put("id", 10);
        map.put("username", "張三");
        //傳遞HashMap物件查詢使用者列表
        List<User> list=userMapper.findUserByHashmap(map);
        System.out.println(list);
        sqlSession.close();
    }

傳遞的map中的key和sql中解析的key不一致時,不會報錯,只是通過key獲取的值為空。

2. 輸出對映

2.1 輸出簡單型別

看下邊的例子,輸出整型,mapper.xml檔案:

    <!--獲取使用者列表總數  -->
    <select id="findUserCount" parameterType="user" resultType="int">
        select count(*) from user
    </select>

mapper介面:

public interface UserMapper {
    //獲取使用者列表總數
    public int findUserCount(User user) throws Exception;
}

測試:

  @Test
    public void findUserCountTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        //建立UserMapper物件,mybatis自動生成mapper代理物件
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setUsername("yan");
        //呼叫userMapper的方法
        int count=userMapper.findUserCount(user);
        System.out.println(count);
        sqlSession.close();
    }

總結:

查詢出來的結果集只有一行且一列,可以使用簡單型別進行輸出對映。

2.2 輸出pojo物件和pojo列表

不管是輸出的pojo單個物件還是一個列表(list中包括pojo),在mapper.xml中resultType指定的型別是一樣的。

在mapper.java指定的方法返回值型別不一樣:

(1)輸出單個pojo物件,方法返回值是單個物件型別。

(2)輸出pojo物件list,方法返回值是List<POJO>

生成的動態代理物件中是根據mapper方法的返回值型別確定是呼叫session.selectOne(返回單個物件呼叫)還是session.selectList(返回集合物件呼叫)。

2.3 resultType總結

使用resultType進行輸出對映,只有查詢出來的列名和pojo中的屬性名一致,該列才可以對映成功。

如果查詢出來的列名和pojo中的屬性名全部不一致,則不會建立pojo物件。

只要查詢出來的列名和pojo中的屬性有一個一致,就會建立pojo物件。

2.4 輸出hashmap

輸出pojo物件可以改用hashmap輸出型別,將輸出的欄位名稱作為map的key,value為欄位值。

2.5 resultMap

resultType可以指定將查詢結果對映為pojo,但需要pojo的屬性名和sql查詢的列名一致才可對映成功。

如果sql查詢欄位名和pojo的屬性名不一致,可以通過resultMap將欄位名和屬性名作一個對應關係,resultMap實質上還需要將查詢結果對映到pojo物件中。

resultMap可以實現將查詢結果對映為複雜型別的pojo,比如在查詢結果對映物件中包括pojo和list實現實現一對一查詢和一對多查詢。

2.5.1 resultMap使用方法

如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個對映關係。

(1)定義resultMap

(2)使用resultMap作為statement的輸出對映型別。

2.5.2 將下邊的sql使用User完成對映

SELECT id id_,username username_ FROM USER WHERE id=#{value}

改sql對查詢結果的列名進行了重新命名:

User類中屬性名和上邊查詢列名不一致。

2.5.2.1 定義resultMap

    <!--定義resultMap
        將SELECT id id_,username username_ FROM USER和User類中的屬性作一個對映關係。
          type:resultMap最終對映的java物件型別,可以使用別名
          id:對resultMap的唯一標識
      -->
    <resultMap type="user" id="userResultMap">
        <!--id表示查詢結果集中唯一標識
            column:查詢出來的列名
            property:type指定的pojo型別中的屬性名
                    最終resultMap對column和property作一個對映關係(對應關係)
          -->
        <id column="id_" property="id"/>
        <!--result:對普通名對映定義
            column:查詢出來的列名
            property:type指定的pojo型別中的屬性名
                    最終resultMap對column和property作一個對映關係(對應關係)
          -->
        <result column="username_" property="username"/>
    </resultMap>

2.5.2.2 使用resultMap作為statement的輸出對映型別

    <!--使用resultMap進行輸出對映
        resultMap:指定定義的resultMap的id,如果這個resultMap在其它的mapper檔案,前邊需要加namespace
      -->
    <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
        SELECT id id_,username username_ FROM USER WHERE id=#{value}
    </select>

2.5.2.3 mapper.java

    //根據id查詢使用者資訊,使用resultMap輸出
    public User findUserByIdResultMap(int id) throws Exception;

2.5.2.4 測試

    @Test
    public void findUserByIdResultMapTest() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        User user=userMapper.findUserByIdResultMap(1);
        System.out.println(user);
        sqlSession.close();
    }

2.6 小結

使用resultType進行輸出對映,只有查詢出來的列名和pojo中的屬性名一致,該列才可以對映成功。

如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個對映關係。

如果此文對您有幫助,微信打賞我一下吧~ 

相關推薦

Spring+SpringMVC+MyBatis深入學習搭建()——MyBatis輸入映射輸出映射

指定 2.6 face 生成 shm hashmap ace and 包裝 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6878529.html 前面有講到Spring+SpringMVC+MyBatis深入學習及搭建(三)&

Spring+SpringMVC+MyBatis深入學習搭建()——MyBatis輸入映射輸出映射(轉發同上)

resultmap 根據 except 就會 ash 用戶名 mvc html like 原地址:http://www.cnblogs.com/shanheyongmu/p/7121556.html 1. 輸入映射 通過parameterType指定輸入參數的類型,類型可

Spring+SpringMVC+MyBatis深入學習搭建()——MyBatis輸入對映輸出對映

1. 輸入對映 通過parameterType指定輸入引數的型別,型別可以是簡單型別、hashmap、pojo的包裝型別。 1.1 #{}與${} #{}實現的是向prepareStatement中的預處理語句設定引數值,sql語句中#{}表示一個佔位符即? <select id="findUse

Spring+SpringMVC+MyBatis深入學習搭建(三)——MyBatis全局配置文件解析

保持 nbsp 延遲加載 行為 span 方便 doc ima actor 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6874672.html 前面有寫到Spring+SpringMVC+MyBatis深入學習及搭建(二)&

Spring+SpringMVC+MyBatis深入學習搭建(八)——MyBatis查詢緩存

idt rtu void spring 寫到 查詢緩存 修改 針對 target 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(

Spring+SpringMVC+MyBatis深入學習搭建(十)——MyBatis逆向工程

cat springmvc blank 不為 tex llc root from ssi 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6973266.html 前面講到:Spring+SpringMVC+MyBatis深入學習及

Spring+SpringMVC+MyBatis深入學習搭建(二)——MyBatis原始Dao開發和mapper代理開發

oid 方法註入 內部 需要 com 配置文件信息 lec lang auth 前面有寫到Spring+SpringMVC+MyBatis深入學習及搭建(一)——MyBatis的基礎知識。MybatisFirst中存在大量重復的代碼。這次簡化下代碼: 使用MyBatis開發

Spring+SpringMVC+MyBatis深入學習搭建(九)——MyBatisSpring整合

1.整合思路需要Spring通過單例方式管理SqlSessionFactory。Spring和MyBatis整合生成代理物件,使用SqlSessionFactory建立SqlSession。(Spring和MyBatis整合自動完成)持久層的mapper都需要由Spring進

Spring+SpringMVC+MyBatis深入學習搭建(八)——MyBatis查詢快取

1.什麼是查詢快取 mybatis提供查詢快取,用於減輕資料庫壓力,提高資料庫效能。 mybatis提供一級快取和二級快取。 一級快取是SqlSession級別的快取。在操作資料庫時需要構造sqlSession物件,在物件中有一個數據結構(HashMap)用於儲存快取資料。不同的sqlSession之間

Spring+SpringMVC+MyBatis深入學習搭建(七)——MyBatis延遲載入

1.什麼是延遲載入 resultMap可以實現高階對映(使用association、collection實現一對一及一對多對映),association、collection具備延遲載入功能。 需求: 如果查詢訂單並且關聯查詢使用者資訊。如果先查詢訂單資訊即可滿足要求,當我們需要查詢使用者資訊時再查下使用

Spring+SpringMVC+MyBatis深入學習搭建(六)——MyBatis關聯查詢

1.商品訂單資料模型 1.1資料模型分析思路 (1)每張表記錄的資料內容   分模組對每張表記錄的內容進行熟悉,相當於你學習系統需求(功能)的過程。 (2)每張表重要的欄位設定   非空欄位、外來鍵欄位 (3)資料庫級別表與表之間的關係   外來鍵關係 (4)表與表之間的業務關係   在分析表與表之間的

Spring+SpringMVC+MyBatis深入學習搭建(三)——MyBatis全域性配置檔案解析

MyBatis的全域性配置檔案SqlMapConfig.xml,配置內容和順序如下: properties(屬性) setting(全域性配置引數) typeAliases(類名別名) typeHandlers(類名處理器) objectFactory(物件工廠) plugins(外掛) environm

Spring+SpringMVC+MyBatis深入學習搭建(十)——SpringMVCMyBatis整合

文件拷貝 conf lips glib ide doc from ive body 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/7010363.html 前面講到:Spring+SpringMVC+MyBatis深入學習及搭建(

Spring+SpringMVC+MyBatis深入學習搭建(十一)——SpringMVC架構

框架 ppi spring框架 edit 不同的 com get request html 轉載請註明出處:http://www.cnblogs.com/Joanna-Yan/p/6985816.html 前面講到:Spring+SpringMVC+MyBatis深入學習

Spring+SpringMVC+MyBatis深入學習搭建(五)——動態sql

mybatis核心:對sql語句進行靈活操作,通過表示式進行判斷,對sql進行靈活拼接、組裝。 mybatis提供各種標籤方法實現動態拼接sql。 1. if&where 1.2 需求 使用者資訊綜合查詢列表和使用者資訊查詢列表總數這兩個statement的定義使用動態sql。 對查詢條件進行判斷

Spring+SpringMVC+MyBatis深入學習搭建】17.SpringMVC攔截器

1.攔截器定義 Spring Web MVC的處理器攔截器類似於Servlet開發中的過濾器Filter,用於對處理器進行預處理和後處理。 定義攔截器,實現HandlerInterceptor介面。介面中提供三個方法。 package joanna.yan.ssm.interceptor; imp

MyBatis學習筆記(三)——輸入(parameterType)輸出(resultType、resultMap)對映

一、輸入對映 parameterType 在MyBatis中,我們通過parameterType屬性完成輸入型別對映。這個屬性可接收普通型別也可以接收一個pojo物件。那麼如果我們想要通過這個屬性對映兩個或多個pojo物件時應該怎麼做呢? 這個時候我們就可以運用包裝類來解決

Mybatis輸入對映輸出對映

輸入型別(parameterType) 傳遞簡單型別(參考Mybatis入門程式) 傳遞POJO物件(Mybatis使用Ognl表示式解析物件欄位的值,#{}佔位符與拼接符 ${}括號內的值為POJO屬性名稱) 傳遞POJO包裝物件 開發中通過

spring深入學習(十) IOC 之開啟 bean 的載入

(此圖來自《Spring 揭祕》) Spring IOC 容器所起的作用如上圖所示,它會以某種方式載入 Configuration Metadata,將其解析註冊到容器內部,然後回根據這些資訊繫結整個系統的物件,最終組裝成一個可用的基於輕量級容器的應用系統。 Spring 在實現上述功

多執行緒深入學習面試解決思路

課程目標 執行緒與程序區別 為什麼要使用多執行緒? 多執行緒應用場景? 多執行緒建立方式 獲取執行緒物件以及名稱 守護執行緒 多執行緒執行狀態 join()方法作用 多執行緒分批處理資料 作業題 面試題 備註單詞 執行緒與程序區別