MapperMethod의 생성부터 실행까지의 과정을 분석했습니다. MapperMethod의 실행에는 sql 실행과 결과 반환이 포함됩니다.
SQL을 실행하고 결과를 반환하는 과정은 TypeHandler를 통해 이루어집니다. TypeHandler 공식 웹사이트 http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers에 비교적 자세한 문서가 있습니다. 이 문서는 주로 TypeHandler 사용 방법을 설명합니다. 다음 분석에서는 TypeHandler와 관련된 소스 코드를 분석합니다.
1. 구성
MyBatis에는 구성을 사용자 정의해야 하는 경우 매우 간단합니다. mybatis-config.xml에 다음 구성을 추가합니다.
<typeHandlers> <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/> </typeHandlers>
읽기 설정 구성 과정을 분석해 보겠습니다. XMLConfigBuilder에서 위 소스 코드에
/** * 读取配置文件组装configuration * @param root 配置文件的configuration节点 */ private void parseConfiguration(XNode root) { try { //issue #117 read properties first propertiesElement(root.evalNode("properties")); Properties settings = settingsAsProperties(root.evalNode("settings")); loadCustomVfs(settings); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); reflectorFactoryElement(root.evalNode("reflectorFactory")); settingsElement(settings); // read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments")); databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } }
에 한 줄이 있습니다.
typeHandlerElement(root.evalNode("typeHandlers"));
typeHandlerElement 메소드를 살펴보겠습니다.
/** * 读取typeHandlers配置并注册 * @param parent 配置文件typeHandlers节点 * @throws Exception */ private void typeHandlerElement(XNode parent) throws Exception { if (parent != null) { for (XNode child : parent.getChildren()) { if ("package".equals(child.getName())) { String typeHandlerPackage = child.getStringAttribute("name"); typeHandlerRegistry.register(typeHandlerPackage); } else { String javaTypeName = child.getStringAttribute("javaType"); String jdbcTypeName = child.getStringAttribute("jdbcType"); String handlerTypeName = child.getStringAttribute("handler"); Class<?> javaTypeClass = resolveClass(javaTypeName); JdbcType jdbcType = resolveJdbcType(jdbcTypeName); Class<?> typeHandlerClass = resolveClass(handlerTypeName); if (javaTypeClass != null) { if (jdbcType == null) { typeHandlerRegistry.register(javaTypeClass, typeHandlerClass); } else { typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass); } } else { typeHandlerRegistry.register(typeHandlerClass); } } } } }
if 및 else의 코드 로직은 결국 typeHandler의 두 가지 구성 메소드에 해당합니다. >
typeHandlerRegistry.register()
은 결국 TypeHandler와 TypeHandlerRegistry, Configuration, BaseTypeHandler의 관계가 호출됩니다.
2. >
매개변수를 설정할 때 먼저 ParameterHandler.setParameters()를 호출한 다음 setParameters()에서 해당 typeHandler를 가져오고 마지막으로 typeHandler.setParameter()를 호출합니다.BaseTypeHandler의 setParameter 메소드를 살펴보세요
매개변수가 null이 아닌 경우 setNonNullParameter가 호출됩니다. 이는 하위 클래스에 setNonNullParameterBigIntegerTypeHandler:이제 TypeHandler의 역할을 대략적으로 분석했습니다.