1. 程式人生 > >mybatis免sql外掛之JpaMapper-以Jpa hibernate的風格寫mybatis(生成自定義的MappedStatement)

mybatis免sql外掛之JpaMapper-以Jpa hibernate的風格寫mybatis(生成自定義的MappedStatement)

mybatis免sql外掛之JpaMapper-以Jpa hibernate的風格寫mybatis(生成自定義的MappedStatement)

簡介

JpaMapper以Jpa hibernate的風格寫mybatis的程式碼,可以減少手動寫sql的煩惱。

優勢:

  1. 不替換底層實現,僅生成sql並交給mybatis
  2. 方法基本與Jpa hibernate相似,易於框架替換,當然,沒那麼厲害,不支援聯表哦,專案還在繼續完善中。
  3. 提供簡單分表功能
  4. 邏輯簡單,可以拿去自己定製

gitee地址:https://gitee.com/xiaoyaofeiyang/JpaMapper

github地址:https://github.com/feiyangtianyao/jpa-mapper

上篇作為起始篇,介紹一下如何從spring容器中獲取到mybatis的mapper/bean。
這一篇將介紹生成自定義的MappedStatement的過程。

mybatis的註解解析MapperAnnotationBuilder

mybatis的註解解析方法位於MapperAnnotationBuilder中。

  1. parseStatement負責解析每個方法上的sql語句
  2. buildSqlSourceFromStrings負責生成SqlSource
  3. MapperBuilderAssistant負責將SqlSource存入mybatis的管理器中。
  4. handleSelectKeyAnnotation負責處理SelectKey註解,屬於主鍵id回返的策略

當然,裡面的方法不止這些,我們需要用的大概就這些了,其他的都是小細節了。

定義自己的解析器JpaMapperAnnotationBuilder

這裡就只說主要內容了,其他從簡。

  1. 首先我們需要確定我們的方法型別是屬於增刪改查的哪一種

  2. 根據方法名確定我們生成的sql語句

在這之前,我們還是要先拿到mapper介面定義的泛型,並分析泛型類的欄位,拿到我們想要的資訊,比如欄位對應、id欄位及策略、分表字段等

生成SqlSource

根據我們前面拿到的資訊生成sql,並將sql使用languageDriver.createSqlSource建立mybatis需要的SqlSource。

public static SqlSource createSqlSource(JpaModelEntity jpaModelEntity, Method method, SqlType sqlCommandType,
		Class<?> parameterTypeClass, LanguageDriver languageDriver, Configuration configuration) {
	try {
		String sql = "";
		if(jpaModelEntity.isSharding()){
			sql = createShardingSql(jpaModelEntity, method, sqlCommandType);
		}else{
			sql = createCommonSql(jpaModelEntity, method, sqlCommandType);
		}
		if (StringUtil.isEmpty(sql))
			return null;
		return languageDriver.createSqlSource(configuration, sql, parameterTypeClass);
	} catch (Exception e) {
		throw new BuilderException("Could not find value method on SQL annotation.  Cause: " + e, e);
	}
}

生成Sql

這裡僅以findBy + 欄位做說明

mybatis查詢結果一般作為實體或list返回,所以,findBy操作我們將返回Collection,這個可以不管,寫的時候定義什麼就是什麼。

查詢欄位

查詢欄位使用前面分析好的泛型類的欄位,使用@Column註解獲取資料庫欄位的名稱。因此我們可以生成select的字首:

select 資料庫欄位 as 成員名稱 , (…)

表名

表名我們使用@Table註解指定。所有我們可以寫成:

from 表名

查詢條件

findBy + 欄位 (and)做查詢時,查詢條件要把方法名做解析後獲得。

String[] params = 方法名.split(“And|and|AND”);

根據方法名引數,我們可以找到對應的查詢條件:

where 條件1(param在實體中的資料庫對應名稱) = #{實體中的成員名稱} and (…)

至此,一個簡單的findBy寫好了。其他的方法將不再贅述。

下篇介紹下儲存後如何拿回Id欄位的值。