이전 글 "Mybatis 시리즈 심층 소개(5)---TypeHandler(mybatis 소스 코드) 소개 및 구성"에서는 TypeHandler에 대해 간략하게 살펴보았습니다. 이번에는 mybatis의 구성 파일에 대한 연구를 마치겠습니다. 이번에는 언급되지 않은 나머지 노드(objectFactory, DatabaseIdProvider, 플러그인 및 매퍼)의 구성이 포함됩니다.
그럼 다음으로 이러한 구성의 기능을 간략하게 소개하겠습니다.
1. objectFactory는 무엇을 하나요? 구성해야 합니까?
MyBatis가 결과 개체의 새 인스턴스를 생성할 때마다 이를 수행하기 위해 ObjectFactory 인스턴스를 사용합니다. 기본 개체 팩토리에서 수행해야 하는 모든 작업은 기본 생성자를 통해 또는 매개 변수 맵이 있는 경우 매개 변수 생성자를 통해 대상 클래스를 인스턴스화하는 것입니다. 기본적으로 구성할 필요가 없으며 mybatis는 기본으로 구현된 objectFactory를 호출합니다. ObjectFactory 구현을 사용자 정의하려는 경우가 아니면 수동으로 구성해야 합니다.
그렇다면 ObjectFactory 구현을 어떻게 사용자 정의할 수 있을까요? 어떻게 구성하나요?
ObjectFactory를 사용자 정의하려면 DefaultObjectFactory(ObjectFactory 인터페이스의 구현 클래스)를 상속하고 해당 메서드를 다시 작성하기만 하면 됩니다. 여기서는 자세히 다루지 않고 나중에 자세히 설명하겠습니다.
ObjectFactory를 작성한 후 다음과 같이 구성하기만 하면 됩니다.
<configuration> ...... <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory> ...... </configuration
2. 플러그인의 역할? 구성해야 합니까?
플러그인은 선택적인 구성입니다. mybatis의 플러그인은 실제로 인터셉터입니다. 이는 Executor, ParameterHandler, ResultSetHandler 및 StateHandler의 일부 메소드를 가로채어 자체 로직을 처리할 수 있습니다. Executor는 실제로 SQL 문을 실행하는 것이고, ParameterHandler는 우리가 전달하는 매개변수를 처리하는 것입니다. 앞서 TypeHandler에 관해 이야기할 때 언급한 내용이 아직도 기억납니다. Mybatis는 기본적으로 typeHandler를 명시적으로 구성하지 않을 때 많은 typeHandler를 구현하는 데 도움을 줍니다. mybatis 실제로는 ParameterHandler인 매개변수 유형을 기반으로 실행을 위해 적절한 typeHandler가 자동으로 선택됩니다. 선택에. ResultSetHandler는 반환된 결과를 처리합니다.
플러그인을 사용자 정의하는 방법은 무엇입니까?
플러그인을 커스터마이징하려면 Interceptor 인터페이스를 구현해야 합니다. 여기서는 자세히 다루지 않고 나중에 실제적인 부분에서 자세히 설명하겠습니다. 정의한 후 구성은 다음과 같습니다.
<configuration> ...... <plugins> <plugin interceptor="org.mybatis.example.ExamplePlugin"> <property name="someProperty" value="100"/> </plugin> </plugins> ...... </configuration>
3. 매퍼, 이는 mybatis의 핵심 중 하나를 구성해야 합니까?
매퍼 노드 아래에서 매퍼 매핑 파일을 구성합니다. 소위 매퍼 매핑 파일은 mybatis가 데이터 테이블과 javabeans 간의 매핑을 설정하는 데 사용하는 브리지입니다. 실제 개발에서는 일반적으로 매퍼 파일이 dao 인터페이스에 해당하며 이 매퍼는 dao의 구현으로 간주될 수 있습니다. 따라서 매퍼를 구성해야 합니다.
그럼 어떻게 구성하나요?
<configuration> ...... <mappers> <!-- 第一种方式:通过resource指定 --> <mapper resource="com/dy/dao/userDao.xml"/> <!-- 第二种方式, 通过class指定接口,进而将接口与对应的xml文件形成映射关系 不过,使用这种方式必须保证 接口与mapper文件同名(不区分大小写), 我这儿接口是UserDao,那么意味着mapper文件为UserDao.xml <mapper class="com.dy.dao.UserDao"/> --> <!-- 第三种方式,直接指定包,自动扫描,与方法二同理 <package name="com.dy.dao"/> --> <!-- 第四种方式:通过url指定mapper文件位置 <mapper url="file://........"/> --> </mappers> ...... </configuration>
이 글은 간략한 소개일 뿐입니다. 좀 더 고급 사용법과 구현 원리는 나중에 실제적인 부분에서 자세히 설명하겠습니다.
이러한 노드의 파싱 소스 코드는 앞서 언급한 노드의 파싱과 유사하므로 여기서는 다루지 않습니다. 소스코드를 접었으니 필요하시면 열어보셔도 됩니다.
/** * objectFactory 节点解析 */private void objectFactoryElement(XNode context) throws Exception { if (context != null) { //读取type属性的值, 接下来进行实例化ObjectFactory, 并set进 configuration //到此,简单讲一下configuration这个对象,其实它里面主要保存的都是mybatis的配置 String type = context.getStringAttribute("type"); //读取propertie的值, 根据需要可以配置, mybatis默认实现的objectFactory没有使用properties Properties properties = context.getChildrenAsProperties(); ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance(); factory.setProperties(properties); configuration.setObjectFactory(factory); } } /** * plugins 节点解析 */ private void pluginElement(XNode parent) throws Exception { if (parent != null) { for (XNode child : parent.getChildren()) { String interceptor = child.getStringAttribute("interceptor"); Properties properties = child.getChildrenAsProperties(); //由此可见,我们在定义一个interceptor的时候,需要去实现Interceptor, 这儿先不具体讲,以后会详细讲解 Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance(); interceptorInstance.setProperties(properties); configuration.addInterceptor(interceptorInstance); } } } /** * mappers 节点解析 * 这是mybatis的核心之一,这儿先简单介绍,在接下来的文章会对它进行分析 */ private void mapperElement(XNode parent) throws Exception { if (parent != null) { for (XNode child : parent.getChildren()) { if ("package".equals(child.getName())) { //如果mappers节点的子节点是package, 那么就扫描package下的文件, 注入进configuration String mapperPackage = child.getStringAttribute("name"); configuration.addMappers(mapperPackage); } else { String resource = child.getStringAttribute("resource"); String url = child.getStringAttribute("url"); String mapperClass = child.getStringAttribute("class"); //resource, url, class 三选一 if (resource != null && url == null && mapperClass == null) { ErrorContext.instance().resource(resource); InputStream inputStream = Resources.getResourceAsStream(resource); //mapper映射文件都是通过XMLMapperBuilder解析 XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); mapperParser.parse(); } else if (resource == null && url != null && mapperClass == null) { ErrorContext.instance().resource(url); InputStream inputStream = Resources.getUrlAsStream(url); XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments()); mapperParser.parse(); } else if (resource == null && url == null && mapperClass != null) { Class<?> mapperInterface = Resources.classForName(mapperClass); configuration.addMapper(mapperInterface); } else { throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one."); } } } } }
以上就是深入浅出Mybatis系列(六)---objectFactory、plugins、mappers简介与配置的内容,更多相关内容请关注PHP中文网(www.php.cn)!