三. 深度分析解析SqlSessionFacotryBuild干的核心工作 1. build(InputStream in) 方法做的工作
①借助Dom4j的来解析了xml文件, 将environments解析工作分发给了parseEnvironment(Element environments)
②将mappers的解析工作分发给了parseMapper(Element mapper)
2. parseEnvironment(Element environments)方法做的工作
①主要解析了连接数据库的参数们, 并且创建了数据库连接池
自定义连接池非本章节的重点,所以这里内部本质采用的Druid连接池来做了简化
package com.itheima.ibatis.configuration; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.util.Properties; public class DefaultDataSource { public DataSource getDataSource(Properties properties) { try { return DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } return null; } }
②将解析好的连接池放入configuration对象中,mappers成员变量先别纠结下一章节会讲解
package com.itheima.ibatis.configuration; import lombok.Data; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Data public class Configuration { private Map mappers = new HashMap<>(); private DataSource dataSource; }
详细图解如下图
文章插图
3.parseMapper(Element mapper) 方法做的工作
①解析出用户配置的package找到sql语句所在接口的文件夹, 交给initMapper来处理
文章插图
②递归找到这个包下所有的.class文件,并且获取到接口的全类名, 然后交给initMapper来处理
文章插图
③initMapper通过反射获取类中的每一个方法,将方法交给一个专门解析方法上的注解的工具类ParseMapper的parse方法处理,处理完后将其放到configuration中的mappers的集合中
文章插图
④ParseMapper的parse方法做的工作, 这是解析配置的核心地方
package com.itheima.ibatis.configuration; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ParseMapper { public static Mapper parse(Method method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Annotation[] annotations = method.getAnnotations(); Object value = https://www.isolves.com/it/cxkf/kj/2022-11-14/annotations[0].getClass().getMethod("value").invoke(annotations[0]); Mapper mapper = new Mapper(); Class resultType = method.getReturnType(); String val = (String) value; Pattern pattern = Pattern.compile("/#/{/s*/w+/s*/}"); Matcher matcher = pattern.matcher(val); List paramNames = new ArrayList<>(); while (matcher.find()) { String group = matcher.group(); String fieldName = group.substring(2, group.length() - 1).trim(); paramNames.add(fieldName); } String sql = val.replaceAll("/#/{/s*/w+/s*/}", "?"); mapper.setSql(sql); mapper.setParameterNames(paramNames); mapper.setSql(sql); if (resultType == List.class) { mapper.setSelectList(true); Type genericReturnType = method.getGenericReturnType(); ParameterizedType parameterizedType = (ParameterizedType) genericReturnType; Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0]; mapper.setResultType(actualTypeArgument.getTypeName()); mapper.setType("SELECT"); } else if (resultType == Integer.class || resultType == int.class) { mapper.setType("UPDATE"); } else { mapper.setType("SELECT"); mapper.setResultType(resultType.getName()); } return mapper; } }
首先拿到方法上的注解,得到用户填入的sql语句
文章插图
然后处理sql语句#{参数}的这些数据, 然后将参数的顺序保存起来, 用来后期设置参数的数据做准备, 一个
推荐阅读
- 中国卖家如何在亚马逊全球开店 中国卖家如何在亚马逊开店铺
- 徐克|在《大宅门》中,白萌堂白老爷生有三个儿子,如何评价白老爷的三个儿子?
- 火车卧铺如何睡得舒服
- 如何度过大学三年生活
- 老年人夏季如何养生?
- 在北京如何乘坐地铁
- 如何认定小微企业
- 如何在Word中新建样式:快速新建样式
- 如何清洗掉身上的纹身? 怎样清洗纹身
- 怎样挑选吉他,买哪种吉他好用 想买吉他如何选择