1. 程式人生 > >修改MyBatis原始碼實現掃描註冊列舉-具體實現

修改MyBatis原始碼實現掃描註冊列舉-具體實現

前言

           在上一篇部落格中,我們已經知道了型別轉換處理器的具體註冊過程,那麼在下面,我們將向大家展示如何改造mybatis的原始碼,實現我們自動掃描列舉,自動向萬能型別轉換處理器中註冊我們想要的列舉。

下載mybatis原始碼

mybatis匯入myeclipse

         下載好的mybatis是不能匯入myeclipse或者eclipse的,需要使用maven編譯,才能匯入到專案中,匯入之後pom檔案好像報了錯,不過我沒有理會它,因為可以正常的修改原始碼,並且還能編譯打包,匯入好之後,如下圖所示:

修改mybatis原始碼

修改MappedTypes註解

/**
 * @author Eduardo Macarron
 * @author Fighter
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MappedTypes {
	public Class<?>[] value() default{};
	
	public String[] basePackage() default {};
}

新增BaseEnum介面類

package org.apache.ibatis.type;

/**
 * @author: Fighter168
 */
public interface BaseEnum<E extends Enum<?>, T> {
	public T getValue();
	public String getDisplayName();
}


修改TypeHandlerRegistry的register方法

  public void register(Class<?> typeHandlerClass) {
    boolean mappedTypeFound = false;
    MappedTypes mappedTypes = typeHandlerClass.getAnnotation(MappedTypes.class);
    if (mappedTypes != null) {
      // first scan the enum under basePackage
      for(String basePackage:mappedTypes.basePackage()){
    	    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<Class<?>>();
    	    resolverUtil.find(new ResolverUtil.IsA(BaseEnum.class), basePackage);
    	    Set<Class<? extends Class<?>>> mTypes = resolverUtil.getClasses();
    	    for (Class<?> javaTypeClass : mTypes) {
    	        register(javaTypeClass, typeHandlerClass);
    	      }
      }
      // then regist the mappedTypes
      for (Class<?> javaTypeClass : mappedTypes.value()) {
          register(javaTypeClass, typeHandlerClass);
          mappedTypeFound = true;
        }
    }
    if (!mappedTypeFound) {
      register(getInstance(null, typeHandlerClass));
    }
  }

打包mybatis原始碼

          我們修改好原始碼後,不能使用eclipse或者myeclipse的直接右鍵到處jar,要使用maven的打包命令,將原始碼package,如果打包的方式不對的話,那麼打包出來的jar是不能正常使用的,會缺少很多包。

測試修改後的原始碼

宣告列舉

  首先我們來建立兩個測試所用的列舉

掃描指定的列舉包,向萬能列舉轉化器註冊轉換


編寫mybatis的配置檔案

      直接掃描net.itaem.handler下的萬能列舉處理器
<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  
    <typeHandlers>
    <!-- 
    	這裡就不需要為再為每一個列舉都註冊一個型別轉換器了
		<typeHandler handler="net.itaem.handler.UniversalEnumHandler" 
		javaType="net.itaem.less.PersonType" jdbcType="CHAR"/>
		<typeHandler handler="net.itaem.handler.UniversalEnumHandler" 
		javaType="net.itaem.less.CarType" jdbcType="CHAR"/>
	-->
		<package name="net.itaem.handler"/>
    </typeHandlers>
    <!-- mapping 檔案路徑配置 -->  
    <mappers>  
        <mapper resource="resource/PersonMapper.xml" />  
        <mapper resource="resource/CarMapper.xml" />  
    </mappers>  
</configuration>



編寫測試用例

/**
 * @author: Fighter168
 */
public class SpringTest {

	public static void main(String[] args) {
		ApplicationContext context=new ClassPathXmlApplicationContext("resource/ApplicationContext.xml");
		PersonDao personDao=(PersonDao) context.getBean("personDao");
		CarDao carDao=(CarDao) context.getBean("carDao");
		List<Person> list=personDao.query();
		for(Person p:list){
			System.out.println(p.toString());
		}
		List<Car> list2=carDao.query();
		for(Car p:list2){
			System.out.println(p.toString());
		}
	}
}

展示結果


小結

            好了,終於實現了這功能了,以後在不不需要那麼麻煩的寫一行行的配置了,直接掃描就可以了。一路過來其實遇到蠻多困難的,不過在自己的堅持下還是解決了,很幸運,也很開心,又進步了一點點。