1. 程式人生 > >java-mybaits-00401-Mapper-輸入輸出

java-mybaits-00401-Mapper-輸入輸出

hone isp 通過 一對一 ext column factory order 屬性。

Mapper.xml映射文件中定義了操作數據庫的sql,每個sql是一個statement,映射文件是mybatis的核心。

1、parameterType(輸入類型)

1.1、#{}與${}

#{}   實現的是向prepareStatement中的預處理語句中設置參數值,sql語句中#{}表示一個占位符即?。   使用占位符#{}可以有效防止sql註入   在使用時不需要關心參數值的類型,mybatis會自動進行java類型和jdbc類型的轉換   可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。
<!--
根據id查詢用戶信息 --> <select id="findUserById" parameterType="int" resultType="user"> select * from user where id = #{id} </select>
${}   和#{}不同,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換   可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,${}括號中只能是value。   使用${}不能防止sql註入,但是有時用${}會非常方便,如下的例子:
<!--
根據名稱模糊查詢用戶信息 --> <select id="selectUserByName" parameterType="string" resultType="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>
上邊紅色標註的是user對象中的字段名稱。 註意參數名稱,如果不一致,會產生異常。

1.4、傳遞pojo包裝對象

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

1.4.1、定義包裝對象

定義包裝對象將查詢條件(pojo)以類組合的方式包裝起來。 Vo:視圖層對象 Po:持久層 Pojo:自定義的綜合體 完成用戶信息的綜合查詢,需要傳入查詢條件很復雜(可能包括用戶信息、其它信息,比如商品、訂單的) 技術分享
package com.lhx.mybatis.po;

public class QueryVo {
    private User user;
    // 自定義用戶擴展類
    private UserCustom userCustom;
    private String ordercode;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public UserCustom getUserCustom() {
        return userCustom;
    }
    public void setUserCustom(UserCustom userCustom) {
        this.userCustom = userCustom;
    }
    public String getOrdercode() {
        return ordercode;
    }
    public void setOrdercode(String ordercode) {
        this.ordercode = ordercode;
    }
    
}
View Code

如果用戶需要擴展

技術分享
package com.lhx.mybatis.po;

public class UserCustom extends User {
    private String phone;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
    
}
View Code

1.4.2 mapper.xml映射文件

技術分享
    <select id="findUserList" parameterType="com.lhx.mybatis.po.QueryVo" 
    resultType="com.lhx.mybatis.po.User">
    select * from user where #{user.username} and sex=#{user.sex} 
    </select>
View Code

select * from user where sex=#{user.sex} and username like ‘%${user.username}%‘

說明:mybatis底層通過ognl從pojo中獲取屬性值:#{user.username},user即是傳入的包裝對象的屬性。queryVo是別名,即上邊定義的包裝對象類型。

1.4.3、編寫Mapper

    public List<User> findUserList(QueryVo queryVo) throws Exception;

1.5、傳遞hashmap

Sql映射文件定義如下:

<!-- 傳遞hashmap綜合查詢用戶信息 -->
<select id="findUserByHashmap" parameterType="hashmap" resultType="com.lhx.mybatis.po.User">
  select * from user where id=#{id} and username like ‘%${username}%‘
</select>

上邊紅色標註的是hashmap的key。 測試: 技術分享
    public void testFindUserByHashmap() throws Exception {
        // 獲取session
        SqlSession session = sqlSessionFactory.openSession();
        // 獲限mapper接口實例
        UserMapper userMapper = session.getMapper(UserMapper.class);
        // 構造查詢條件Hashmap對象
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("id", 1);
        map.put("username", "管理員");

        // 傳遞Hashmap對象查詢用戶列表
        List<User> list = userMapper.findUserByHashmap(map);
        // 關閉session
        session.close();
    }
View Code 異常測試: 傳遞的map中的key和sql中解析的key不一致。 測試結果沒有報錯,只是通過key獲取值為空。

2、resultType(輸出類型)

2.1 輸出簡單類型

參考getnow輸出日期類型,看下邊的例子輸出整型: Mapper.xml文件
<!-- 獲取用戶列表總數 -->
    <select id="findUserCount" parameterType="user" resultType="int">
       select count(1) from user
    </select>
Mapper接口
public int findUserCount(User user) throws Exception;
調用: 技術分享
public void testFindUserCount() throws Exception{
       //獲取session
       SqlSession session = sqlSessionFactory.openSession();
       //獲取mapper接口實例
       UserMapper userMapper = session.getMapper(UserMapper.class);
   
       User user = new User();
       user.setUsername("管理員");
 
       //傳遞Hashmap對象查詢用戶列表
       int count = userMapper.findUserCount(user);
      
       //關閉session
       session.close();
    }
View Code 總結: 輸出簡單類型必須查詢出來的結果集有一條記錄,最終將第一個字段的值轉換為輸出類型。 使用session的selectOne可查詢單條記錄。

2.2 輸出pojo對象

參考findUserById的定義: Mapper.xml
   <!-- 根據id查詢用戶信息 -->
    <select id="findUserById" parameterType="int" resultType="user">
       select * from user where id = #{id}
    </select>
Mapper接口:
public User findUserById(int id) throws Exception;
測試: 技術分享
public void testFindUserById() throws Exception {
       //獲取session
       SqlSession session = sqlSessionFactory.openSession();
       //獲限mapper接口實例
       UserMapper userMapper = session.getMapper(UserMapper.class);
       //通過mapper接口調用statement
       User user = userMapper.findUserById(1);
       System.out.println(user);
       //關閉session
       session.close();
    }
View Code 使用session調用selectOne查詢單條記錄。

2.3 輸出pojo列表

參考selectUserByName的定義: Mapper.xml
<!-- 根據名稱模糊查詢用戶信息 -->
    <select id="findUserByUsername" parameterType="string" resultType="user">
       select * from user where username like ‘%${value}%‘
    </select>
Mapper接口:
public List<User> findUserByUsername(String username) throws Exception;

測試:

public void testFindUserByUsername()throws Exception{
       //獲取session
       SqlSession session = sqlSessionFactory.openSession();
       //獲限mapper接口實例
       UserMapper userMapper = session.getMapper(UserMapper.class);
       //如果使用占位符號則必須人為在傳參數中加%
       //List<User> list = userMapper.selectUserByName("%管理員%");
       //如果使用${}原始符號則不用人為在參數中加%
       List<User> list = userMapper.findUserByUsername("管理員");
       //關閉session
       session.close();
    }
使用session的selectList方法獲取pojo列表。

2.4 resultType總結:

使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。 如果查詢出來的列名和pojo中的屬性名全部不一致,沒有創建pojo對象。 只要查詢出來的列名和pojo中的屬性有一個一致,就會創建pojo對象。 輸出pojo對象和輸出pojo列表在sql中定義的resultType是一樣的。 返回單個pojo對象要保證sql查詢出來的結果集為單條,內部使用session.selectOne方法調用,mapper接口使用pojo對象作為方法返回值。 返回pojo列表表示查詢出來的結果集可能為多條,內部使用session.selectList方法,mapper接口使用List<pojo>對象作為方法返回值。

2.5 輸出hashmap

輸出pojo對象可以改用hashmap輸出類型,將輸出的字段名稱作為map的key,value為字段值。

3、resultMap

resultType可以指定pojo將查詢結果映射為pojo,但需要pojo的屬性名和sql查詢的列名一致方可映射成功。 如果sql查詢字段名和pojo的屬性名不一致,可以通過resultMap將字段名和屬性名作一個對應關系 ,resultMap實質上還需要將查詢結果映射到pojo對象中。 resultMap可以實現將查詢結果映射為復雜類型的pojo,比如在查詢結果映射對象中包括pojo和list實現一對一查詢和一對多查詢。

3.1 Mapper.xml定義

    <select id="findUserListResultMap" parameterType="com.lhx.mybatis.po.QueryVo"
        resultMap="userListMap">
        select id id_,username username_ from user where
        #{user.username} and
        sex=#{user.sex}
    </select>

使用resultMap指定上邊定義的personmap。

3.2 定義resultMap

由於上邊的mapper.xml中sql查詢列和Users.java類屬性不一致,需要定義resultMap:userListResultMap將sql查詢列和Users.java類屬性對應起來
    <resultMap type="com.lhx.mybatis.po.User" id="userListMap">
        <id column="id_" property="id"></id>
        <result column="username_" property="username"></result>
    </resultMap>

<id />:此屬性表示查詢結果集的唯一標識,非常重要。如果是多個字段為復合唯一約束則定義多個<id />。
Property:表示類的屬性。
Column:表示sql查詢出來的字段名。
Column和property放在一塊兒表示將sql查詢出來的字段映射到指定的pojo類屬性上。
<result />:普通結果,即pojo的屬性。

3.3 Mapper接口定義

public List<User> findUserListResultMap(QueryVo queryVo) throws Exception;

3.4 測試

技術分享
public void testFindUserListResultMap() throws Exception {
        // 獲取session
        SqlSession session = sqlSessionFactory.openSession();
        // 獲限mapper接口實例
        UserMapper userMapper = session.getMapper(UserMapper.class);
        QueryVo queryVo = new QueryVo();
        User user = new User();
        user.setUsername("張");
        user.setSex("女");
        queryVo.setUser(user);
        // 傳遞Hashmap對象查詢用戶列表
        List<User> list = userMapper.findUserListResultMap(queryVo);
        // 關閉session
        session.close();
    }
View Code

小結

使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。 如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap對列名和pojo屬性名之間作一個映射關系。

java-mybaits-00401-Mapper-輸入輸出