手敲MyBatis(十一章)-支持注解配置执行SQL

1.前言

这一章节从题目中也看出来我们要支持注解版的增删改查,可以在Mapper层的接口类的方法上写Sql语句,如:Insert,Update,Delete,Select的这几个基础Sql,如下图,这样就不用在Xml里去写Sql了,但是这就引申出一个问题,我们怎么解析注解的Sql语句,将方法上的SQL内容取出来并按之前的既定流程去处理执行Sql呢?

 我们现在要处理以下几步才能达到目的

1.配置文件中去配置注解类,加上此在解析的时候才能知道什么情况下用XML方式,在什么情况下用注解方式

2.在配置解析时如果是注解类,直接将class值为namespce进行代理注册 

3.开始解析注解,找到Mapper类里所有的方法,每一个方法都判断下是不是加了这4种注解

   3.1.获取Sql内容,传输到以前就有的流程里得到处理过后的Sql语句,SqlSource

   3.2.通过反射获取方法的参数、返回值、参数类型、返回值类型、并将获取到的数据映射到MappedStatement以及ResultMap

4.之后的流程不变

2.Uml类图

看到类图我们知道,这一章节其实也是很简单的,涉及添加的类只有几个,涉及的修改也不多

添加了4个注解类,1个解析注解类MappernnotationBuilder

XmlConfiguration这里修改判断下如果是注解方式直接调用MapperRegistry的addMapper方法将当前的class进行代理注册,

MapperRegistry类的addMapper方法里添加调用MappernnotationBuilder解析注解数据。

MappernnotationBuilder拿到Sql原内容后调用XmlLanguageDriver进行Sql源处理,继续解析参数、返回值、调用MapperBuilderAsisstant的addMappedStatement和addResultMaps方法将所得的数据映射到MappedStatement和ResultMap类中,供后续使用,之后的就还是和之前的流程一样。

 3.代码实现

XMLConfigBuilder类:此类解析Mapper时添加从xml中获取Class,如果这个Class不为空,证明是要解析注解类,通过反射将String的class类转换为类对象,并通过configuration添加到mapper映射里。

// 处理mapper的方法,mapper里有多个sql语句,所以需要List
    private void mapperElement(Element mappers) throws Exception {
        // 得到mybatis-config-datasource.xml的mappers标签里的mapper
        List<Element> mapperList = mappers.elements("mapper");
        for (Element e : mapperList) {
            String resource = e.attributeValue("resource");
            String mapperClass = e.attributeValue("class");
            // xml解析方式
            if (resource != null && mapperClass == null) {
                InputStream inputStream = Resources.getResourceAsStream(resource);
                // 在for循环里每个mapper都重新new一个XMLMapperBuilder,来解析
                XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource);
                mapperParser.parse();
            } else if (resource == null && mapperClass != null) {
                // 注解方式
                Class<?> mapperInterface = Resources.classForName(mapperClass);
                configuration.addMapper(mapperInterface);
            }
        }
    }

 MapperRegistry类:此类里就添加了解析注解类的处理调用。

public <T> void addMapper(Class<T> type) {
        // 是接口
        if (type.isInterface()) {
            if (hasMapper(type)) {
                // 如果重复添加了报错
                throw new RuntimeException("Type " + type + " is already known to the MapperRegistry.");
            }
            // 注册映射器代理工厂
            knownMappers.put(type, new MapperProxyFactory<>(type));


            // 解析注解类语句配置
            MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
            parser.parse();
        }
    }

MapperAnnotationBuilder类:此类本节新添加的类,专门处理注解的解析,如sql,参数,返回值等操作,

1.parse方法,拿到class的所有方法,如IuserDao定义的所有方法。

2.循环遍历每一个方法并调用parseStatement(method)方法,

    2.1 获取参数类型,调用getParameterType(method);
    2.2 获取语言驱动器,目的是为了创造Sql源,调用getLanguageDriver(method)                              2.3 获取数据源,通过调用getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver)方法。

          2.3.1 通过调用getSqlAnnotationType(method)方法,获取注解类型                                                  2.3.2 根据得到的注解类型获取当前方法上的注解信息,并得到方法上的注解值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值