1. 程式人生 > >mybatis中parameterType 物件傳值欄位匹配問題

mybatis中parameterType 物件傳值欄位匹配問題

眾所周知,parametertype傳入引數分為以下兩種:

(1)java基本資料型別

(2)複雜資料型別(java實體類和Map,List) 

本文的重點討論的分頁查詢中是java實體類的欄位匹配問題

分頁的通用實體類如下:

public abstract class BaseQuery {
    private Integer page=1;         // 當前頁
    private Integer rows=10;        // 每頁顯示條數
    
    private Date startDate;         // 開始日期
    private Date endDate;           // 結束日期
    
    /**
     * limit開始數
     * @return
     */
    public Integer getStartSize() {
        return (page - 1) * rows;
    }
    
    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getRows() {
        return rows;
    }

    public void setRows(Integer rows) {
        this.rows = rows;
    }

    
    public Date getStartDate() {
        return startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setStartDateStr(String startDateStr) {
        if (StringUtils.isNotBlank(startDateStr)) {
            this.startDate = DateUtils.INSTANCE.getDate(startDateStr, DateUtils.DATE_FROMAT);
        } else {
            this.startDate = null;
        }
    }

    @SuppressWarnings("all")
    public void setEndDateStr(String endDateStr) {
        if (StringUtils.isNotBlank(endDateStr)) {
            Date date = DateUtils.INSTANCE.getDate(endDateStr, DateUtils.DATE_FROMAT);
            if (date != null) {
                date.setDate(date.getDate() + 1);
            }
            this.endDate = date;
        } else {
            this.endDate = null;
        }
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

Mapper.xml中的分頁sql如下:

<select id="querySubList" parameterType="UserQuery" resultMap="resultDMap">
		SELECT id,phone,status,email,address,distributor_name,distributor_code,create_time,modify_time
			FROM 
				ts_user
			<include refid="queryConditionSql"/>
			and shop_id is not null
			ORDER BY 
				create_time 
			LIMIT 
				#{startSize},#{rows}
			
</select>

其中,需要傳入的分頁引數是 startSize 和  rows

但是在實體類中,沒有startSize這個屬性欄位,只有getStartSize()這個get方法,為什麼能取到值去匹配呢?

先猜測,是不是拿的get方法取值的呢?當然後續要去驗證

Mybatis的Mapper.java檔案沒有對應的實現類,具體是有Mybatis自己根據Mapper.xml和Mapper.java的對應關係做的代理是實現的,於是跟蹤程式碼如下:

MapperProxy  帶有後綴Proxy的我就不說了,都知道是代理類了,用反射去呼叫代理類中的invoke方法

MapperMethod   進去具體的Mapper中的method方法區組裝stmt 和 sql

具體組裝sql,生成 stmt的我就不貼圖了啊,檢視stmt中的內容如下:

[email protected] wrapping com.mysql.cj.jdbc.ClientPreparedStatement: 
select id,msg_from,msg_to,type,msg_info,msg_content,create_time
	     from ts_push
	     where msg_to=** NOT SPECIFIED **
	      
	     order by create_time desc
	     limit ** NOT SPECIFIED **,** NOT SPECIFIED **
		 

下面就該欄位匹配去填充stmt中的欄位了,繼續跟蹤如下:

果然是 根據欄位 去找 getMethods中找,getMethods是個HashMap,存放的是獲取的實體類的反射物件的所有的get方法

因此又去檢視getMethods初始化的程式碼,如下所示:

可以看出,在用反射獲取分頁實體類的時候,是拿了全部的內容,如上圖所示。

至此為止,mybatis中parameterType 物件傳值欄位匹配問題終於有了清晰地認識和了理解

總結:剛開始,自己不明白,準備直接開口請教別人呢,但是做一個程式猿,還是要沉下心來自己鑽研 一下原始碼,這樣才能理解的更深刻。當然,實在不行,再請教大神。