当前位置: 首页 > news >正文

视频网站自己做服务器征婚网站建设

视频网站自己做服务器,征婚网站建设,做网站 用什么空间,中国工程网查询一、前言 日常工作中#xff0c;我们用到mybatis的时候#xff0c;都是写一个Mapper接口xml文件/注解形式#xff0c;然后就可以在业务层去调用我们在Mapper接口中定义的CRUD方法#xff0c;很方便#xff0c;但一直都没有去研究过执行逻辑#xff0c;下面附一篇我自己研…一、前言 日常工作中我们用到mybatis的时候都是写一个Mapper接口xml文件/注解形式然后就可以在业务层去调用我们在Mapper接口中定义的CRUD方法很方便但一直都没有去研究过执行逻辑下面附一篇我自己研究的过程。 二、注入过程分析 平时我们在使用时都是直接注解标在Mapper接口上从而去注入一个实例但我们是并没有实现过这个Mapper接口的就很容易想到必然是有一个代理类(MapperProxy)来帮我们执行真正的过程而且既然我们定义了接口那大概率就是JDK动态代理了。 注入的过程也比较简单在我们使用时会注明一个mapper扫描的包路径然后在SqlSessionFactory初始化的过程中会去解析每个mapper接口并将其放在Configuration的MapperRegistry中实际存放位置是在MapperRegistry中MapClass?, MapperProxyFactory? knownMappers。 接下来我们在使用mapper接口时会从knownMappers中去获取到对应的MapperProxyFactory从而去实例化真正的代理类代码如下 public T void addMapper(ClassT type) {if (type.isInterface()) {if (hasMapper(type)) {throw new BindingException(Type type is already known to the MapperRegistry.);}boolean loadCompleted false;try {knownMappers.put(type, new MapperProxyFactoryT(type));// Its important that the type is added before the parser is run// otherwise the binding may automatically be attempted by the// mapper parser. If the type is already known, it wont try.MapperAnnotationBuilder parser new MapperAnnotationBuilder(config, type);parser.parse();loadCompleted true;} finally {if (!loadCompleted) {knownMappers.remove(type);}}}} public T T getMapper(ClassT type, SqlSession sqlSession) {final MapperProxyFactoryT mapperProxyFactory (MapperProxyFactoryT) knownMappers.get(type);if (mapperProxyFactory null) {throw new BindingException(Type type is not known to the MapperRegistry.);}try {//关键步骤里面会使用JDK动态代理创建一个MapperProxyreturn mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException(Error getting mapper instance. Cause: e, e);}} public class MapperProxyFactoryT {private final ClassT mapperInterface;private final MapMethod, MapperMethod methodCache new ConcurrentHashMapMethod, MapperMethod();public MapperProxyFactory(ClassT mapperInterface) {this.mapperInterface mapperInterface;}public ClassT getMapperInterface() {return mapperInterface;}public MapMethod, MapperMethod getMethodCache() {return methodCache;}SuppressWarnings(unchecked)protected T newInstance(MapperProxyT mapperProxy) {return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {final MapperProxyT mapperProxy new MapperProxyT(sqlSession, mapperInterface, methodCache);return newInstance(mapperProxy);}} 三、执行过程分析 综上来看其实我们真正的方法是由MapperProxy来实现的接下来看看它的逻辑我们主要分析查询类的执行流程 /*** 执行入口*/Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {if (Object.class.equals(method.getDeclaringClass())) {return method.invoke(this, args);} else if (isDefaultMethod(method)) {return invokeDefaultMethod(proxy, method, args);}} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable(t);}//缓存方法final MapperMethod mapperMethod cachedMapperMethod(method);//真正的执行逻辑return mapperMethod.execute(sqlSession, args);}/** * 根据sql类型执行不同的分支 * convertArgsToSqlCommandParam会转换传入的参数 */ public Object execute(SqlSession sqlSession, Object[] args) {Object result;switch (command.getType()) {case INSERT: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.insert(command.getName(), param));break;}case UPDATE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.update(command.getName(), param));break;}case DELETE: {Object param method.convertArgsToSqlCommandParam(args);result rowCountResult(sqlSession.delete(command.getName(), param));break;}case SELECT://如果是void方法并且自定义了ResultMap等映射则执行此逻辑if (method.returnsVoid() method.hasResultHandler()) {executeWithResultHandler(sqlSession, args);result null;} else if (method.returnsMany()) {//返参为集合类型result executeForMany(sqlSession, args);} else if (method.returnsMap()) {//返参为Mapresult executeForMap(sqlSession, args);} else if (method.returnsCursor()) {//返参为游标result executeForCursor(sqlSession, args);} else {//返参为单对象Object param method.convertArgsToSqlCommandParam(args);result sqlSession.selectOne(command.getName(), param);}break;case FLUSH:result sqlSession.flushStatements();break;default:throw new BindingException(Unknown execution method for: command.getName());}if (result null method.getReturnType().isPrimitive() !method.returnsVoid()) {throw new BindingException(Mapper method command.getName() attempted to return null from a method with a primitive return type ( method.getReturnType() ).);}return result;} 上面的查询方法都会走到下面这两行代码 //获取sql执行的映射过程对象包含了参数、数据源、返参等 MappedStatement ms configuration.getMappedStatement(statement); //执行查询方法 executor.query(ms, wrapCollection(parameter), rowBounds, handler); 接着会走到执行器executor主要有两类实现 org.apache.ibatis.executor.BaseExecutor基本执行器CachingExecutor带缓存的执行器 public E ListE query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {//获取BoundSql对象包含了解析动态SQl生成的sql语句以及参数映射的封装BoundSql boundSql ms.getBoundSql(parameter);//生成缓存keyCacheKey key createCacheKey(ms, parameter, rowBounds, boundSql);//查询return query(ms, parameter, rowBounds, resultHandler, key, boundSql);} public BoundSql getBoundSql(Object parameterObject) {//调用sqlSource获取BoundSqlsqlSource默认为DynamicSqlSource类型动态SQLBoundSql boundSql sqlSource.getBoundSql(parameterObject);ListParameterMapping parameterMappings boundSql.getParameterMappings();//若参数映射为空手动创建boundSqlif (parameterMappings null || parameterMappings.isEmpty()) {boundSql new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);}// check for nested result maps in parameter mappings (issue #30)for (ParameterMapping pm : boundSql.getParameterMappings()) {String rmId pm.getResultMapId();if (rmId ! null) {ResultMap rm configuration.getResultMap(rmId);if (rm ! null) {hasNestedResultMaps | rm.hasNestedResultMaps();}}}return boundSql;} public BoundSql getBoundSql(Object parameterObject) {//获取上下文对象并将传入的入参对象及数据源标识放入bindingsDynamicContext context new DynamicContext(configuration, parameterObject);//基于动态sql解析成的ListSqlNode contents遍历赋值参数rootSqlNode.apply(context);SqlSourceBuilder sqlSourceParser new SqlSourceBuilder(configuration);Class? parameterType parameterObject null ? Object.class : parameterObject.getClass();SqlSource sqlSource sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());BoundSql boundSql sqlSource.getBoundSql(parameterObject);for (Map.EntryString, Object entry : context.getBindings().entrySet()) {boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());}return boundSql;} 准备好BoundSql后就该执行真正的查询了主要链路如下
http://www.yutouwan.com/news/403369/

相关文章:

  • 设计网站的一般过程网站中链接怎么做
  • 如何建设社交网站wordpress安装主题后不够
  • 网站建设调研论文阿里云有了域名 网站建设
  • 商会网站设计网站策划ps
  • 班级网站网页设计做图表好看的网站
  • 怎样在网站上做免费的推广wordpress开发文档下载
  • 坪地网站制作网站手机网站制作
  • 什么网站可以免费做视频it运维培训
  • 国外设计文章的网站网站宣传册怎么做的
  • 辽宁注册公司网站企业网站建设应注意什么
  • 宁波建设协会网站关键词优化是什么意思
  • 公司做网站的费用怎么账务处理智通人才网东莞最新招聘信息官网
  • 安徽静安集团网站建设深圳网站建设公司 概况
  • 宁波网站建设哪家比较好怎么在网上卖东西视频
  • 网站建设十大公司临河网站建设
  • 大连网站制作团队高校网站建设说明书
  • 无锡个人网站建设世界十大著名室内设计师
  • 在线报名网站建设如何建立设计一个公司网站
  • 知名做网站哪家好摄影网站模版
  • 怎样使用仿站小工具做网站ppt模板大全百度云
  • 微信网站是怎么做的高密市住房和城乡建设局网站
  • wordpress评论ajax加载seo公司运营
  • 网站使用网络图片做素材 侵权淄博电商网站建设
  • 做理论的网站做新标准大学英语网站
  • 做英文的小说网站有哪些怎么样网站速度快
  • 网站系统与程序的链接秦皇岛城乡建设局网站
  • thinkphp做的教育网站梅江区住房和城乡建设局官方网站
  • vf建设银行网站好的html5网站模板
  • 德州宁津建设局网站哪个网站可以代做试题
  • 做seo时网站发文目的自建网站赚钱