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

北京网站关键字优化高安做网站

北京网站关键字优化,高安做网站,太原网站建设制作公司哪家好,微信手机网站制作这里有两种方式#xff0c;一种为常用的 Spring 依赖注入 Mapper 的方式。另一种为直接使用 SqlSessionTemplate 执行 Sql 的方式。 Spring 依赖注入 Mapper 的方式 Mapper 接口注入 SpringIOC 容器 Spring 容器在扫描 BeanDefinition 阶段会扫描 Mapper 接口类#xff0c…这里有两种方式一种为常用的 Spring 依赖注入 Mapper 的方式。另一种为直接使用 SqlSessionTemplate 执行 Sql 的方式。 Spring 依赖注入 Mapper 的方式 Mapper 接口注入 SpringIOC 容器 Spring 容器在扫描 BeanDefinition 阶段会扫描 Mapper 接口类并生成这些类的 MapperFactoryBean 的工厂 bean 定义。Spring 容器在 createBean 阶段的时候会根据 BeanDefintion 创建 bean。在创建完 factoryBean 的时候会调用 factoryBean 的 getObject()方法从 DefaultSqlSession 的 knownMapper 重获取 Mapper 接口类的 mapperProxy。使用 MapperProxy 创建出代理类。 public T T getMapper(ClassT type, SqlSession sqlSession) {MapperProxyFactoryT mapperProxyFactory (MapperProxyFactory)this.knownMappers.get(type);if (mapperProxyFactory null) {throw new BindingException(Type type is not known to the MapperRegistry.);} else {try {return mapperProxyFactory.newInstance(sqlSession);} catch (Exception var5) {throw new BindingException(Error getting mapper instance. Cause: var5, var5);}} }public T newInstance(SqlSession sqlSession) {MapperProxyT mapperProxy new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);return this.newInstance(mapperProxy); }protected T newInstance(MapperProxyT mapperProxy) {return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy); }Mapper 类调用 在 Service 层或者 Controller 层通过注解引入 Bean这个时候引入的 Mapper 就是上文创建的 MapperProxy。MapperProxy 的增强逻辑首先过滤掉了 Object 类中的 toString()、equal()等方法。 如果调用的是 Object 类中的方法直接放过不代理 对于 Mapper 接口中的方法进行代理。代理前先检查 methodCache 是否缓存了该方法的 invoke 逻辑。 default 方法的逻辑 非 default 方法的逻辑比较重要。 通过 PlainMethodInvoker 这个类代理了其他接口方法代理逻辑在 MapperMethod 中。 MapperMethod 是最为核心的逻辑。MapperMethod 在执行构建方法时就会创建一个 SqlCommand 和一个 MethodSignature 方法签名。 SqlCommand 封装了从 SqlSession 中 Config 配置中获取到的 MappedStatement。 调用 execute 方法。传参为 MappedStatement 的增删改查的类型和参数 根据增删改查的类型选择不同的执行逻辑 增删改的逻辑 解析参数得到 param反射根据 mybatis 中参数注解解析​sqlSession.insert(this.command.getName(), param) ​或者​sqlSession.update(this.command.getName(), param) ​或者​sqlSession.delete(this.command.getName(), param) ​或者处理结果返回值 select 语句根据返回值类型不同调用不同执行逻辑 returnVoid返回值为空且有专门的结果类型处理器returnsMany​this.executeForMany(sqlSession, args);​returnsMap​this.executeForMap(sqlSession, args);​returnsCursor​this.executeForCursor(sqlSession, args);​returnsOne 返回一行sqlSession.selectOne(this.command.getName(), param);​ flush 刷新类型的 SQL​result sqlSession.flushStatements();​ 如果调用的是 Object 类中的方法直接放过布袋里 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {// 对于Object类中的方法放过不增强直接执行即可。return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);} catch (Throwable var5) {throw ExceptionUtil.unwrapThrowable(var5);} }在 MapperProxy 中有一个缓存结构 methodCacheMapMethod, MapperMethodInvoker methodCache​ 增强逻辑中会先判断当前方法是否被缓存在 methodCache 中如果没有则创建一个放到缓存中。 MapUtil.computeIfAbsent(this.methodCache, method, (m)-{/*创建缓存*/});创建逻辑为 MapUtil.computeIfAbsent(this.methodCache, method, (m) - {// default方法的逻辑DefaultMethodInvokerjava8和Java9的不一样。if (m.isDefault()) {return privateLookupInMethod null ? new DefaultMethodInvoker(this.getMethodHandleJava8(method)) :new DefaultMethodInvoker(this.getMethodHandleJava9(method));} else {return new PlainMethodInvoker(new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration()));} }); default 的先不用管 DefaultMethodInvoker直接看 else 中的 PlainMethodInvoker 创建一个 MapperMethod然后 PlainMethodInvoker 在 invoke 方法中调用 MapperMethod 的方法 execute()。 在构造 MapperMethod 方法中创建了一个 SqlCommand 。SqlCommand 封装了从 SqlSession 中 Config 配置中获取到的 MappedStatement。在之后的 execute 方法中执行的就是 SqlCommand 中的 Mapped Statement。 // SqlCommand 封装了从SqlSession中Config配置中获取到的MappedStatement。 public MapperMethod(Class? mapperInterface, Method method, Configuration config) {this.command new SqlCommand(config, mapperInterface, method);this.method new MethodSignature(config, mapperInterface, method); }private static class PlainMethodInvoker implements MapperMethodInvoker {private final MapperMethod mapperMethod;public PlainMethodInvoker(MapperMethod mapperMethod) {this.mapperMethod mapperMethod;}public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {return this.mapperMethod.execute(sqlSession, args);} }接下来就是执行 SqlSession 中的增删改查方法了。可以先看一下 SqlCommand public SqlCommand(Configuration configuration, Class? mapperInterface, Method method) {String methodName method.getName();Class? declaringClass method.getDeclaringClass();MappedStatement ms this.resolveMappedStatement(mapperInterface, methodName, declaringClass, configuration);if (ms span stylefont-weight: bold; classmark null) {if (method.getAnnotation(Flush.class) /span null) {throw new BindingException(Invalid bound statement (not found): mapperInterface.getName() . methodName);}this.name null;this.type SqlCommandType.FLUSH;} else {this.name ms.getId();this.type ms.getSqlCommandType();if (this.type SqlCommandType.UNKNOWN) {throw new BindingException(Unknown execution method for: this.name);}} }参数转化然后 excute Sql封装返回值 public Object execute(SqlSession sqlSession, Object[] args) {Object result;Object param;switch (this.command.getType()) {case INSERT:// 将args参数数组转换成方法中的注解的参数param this.method.convertArgsToSqlCommandParam(args);// 调用DefaultSqlSession的insert方法。// 处理结果返回值result this.rowCountResult(sqlSession.insert(this.command.getName(), param));break;case UPDATE:// 将args参数数组转换成方法中的注解的参数param this.method.convertArgsToSqlCommandParam(args);// 调用DefaultSqlSession的update方法。// 处理结果返回值result this.rowCountResult(sqlSession.update(this.command.getName(), param));break;case DELETE:// 将args参数数组转换成方法中的注解的参数param this.method.convertArgsToSqlCommandParam(args);// 调用DefaultSqlSession的delete方法。// 处理结果返回值result this.rowCountResult(sqlSession.delete(this.command.getName(), param));break;case SELECT:// select 语句情况较多根据返回值类型不同调用不同执行逻辑。// returnVoid返回值为空且有专门的结果类型处理器if (this.method.returnsVoid() this.method.hasResultHandler()) {this.executeWithResultHandler(sqlSession, args);result null;} else if (this.method.returnsMany()) {result this.executeForMany(sqlSession, args);} else if (this.method.returnsMap()) {result this.executeForMap(sqlSession, args);} else if (this.method.returnsCursor()) {result this.executeForCursor(sqlSession, args);} else {param this.method.convertArgsToSqlCommandParam(args);result sqlSession.selectOne(this.command.getName(), param);if (this.method.returnsOptional() (result null || !this.method.getReturnType().equals(result.getClass()))) {result Optional.ofNullable(result);}}break;case FLUSH:result sqlSession.flushStatements();break;default:throw new BindingException(Unknown execution method for: this.command.getName());}if (result null this.method.getReturnType().isPrimitive() !this.method.returnsVoid()) {throw new BindingException(Mapper method this.command.getName() attempted to return null from a method with a primitive return type ( this.method.getReturnType() ).);} else {return result;}}SqlSessionTemplate 执行 Sql 在创建 SqlSession 的时候已经创建了 Executor。默认为 Simple public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {Assert.notNull(sqlSessionFactory, Property sqlSessionFactory is required);Assert.notNull(executorType, Property executorType is required);this.sqlSessionFactory sqlSessionFactory;this.executorType executorType;this.exceptionTranslator exceptionTranslator;this.sqlSessionProxy (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionInterceptor());}在 Spring Boot 自动配置这篇文章中已经讲过 Configuration 类中有一个属性 mappedStatements​。这是一个 HashMap解析过后的 MappedStatement ​被添加到了 map 中 当我们的 SqlSession 在执行 sql 语句时会先从 configuration 中拿到 sql。然后执行。 private E ListE selectList(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {List var6;try {MappedStatement ms this.configuration.getMappedStatement(statement);var6 this.executor.query(ms, this.wrapCollection(parameter), rowBounds, handler);} catch (Exception var10) {throw ExceptionFactory.wrapException(Error querying database. Cause: var10, var10);} finally {ErrorContext.instance().reset();}return var6;}然后看一下 public E ListE query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {BoundSql boundSql ms.getBoundSql(parameter);CacheKey key this.createCacheKey(ms, parameter, rowBounds, boundSql);return this.query(ms, parameter, rowBounds, resultHandler, key, boundSql);}‍ 再往下一层就是执行 JDBC 那一套了获取链接执行得到 ResultSet解析 ResultSet 映射成 JavaBean。
http://www.w-s-a.com/news/545140/

相关文章:

  • 网站使用说明书网站建设公司的介绍
  • 推广型网站免费建设网站防盗链设置
  • 建设银行网站查开户行网站反链暴增怎么回事
  • centos7做网站软件实施工程师工资一般多少
  • 专业房产网站建设深圳建设交易集团
  • 政务网站建设标准项目经理接到网站开发怎么开展
  • 网站框架设计好后怎么做网站广告销售怎们做
  • asp技校网站保定八大平台公司
  • wordpress网站前端优化网站备案批量查询
  • 北京企业做网站杭州seo中心
  • 护肤品网站建设前的行业分析wordpress电子书模板
  • 做网站怎么销售.net开发网站怎么样
  • 蚌埠网站优化网站换空间wordpress
  • 微网站开发框架公司企业logo
  • 大淘客官网做的网站打不开网站建设完成
  • 婚纱摄影网站模板让别人做网站怎样才安全
  • 技术支持 骏域网站建设专家佛山网站运营管理教材
  • 个体营业执照可以做网站服务吗电商运营学校培训
  • 企业网站免费推广的方法.wordpress 爱情模板下载地址
  • 轻淘客 轻网站怎么做手机开发人员选项怎么打开
  • 天津做网站制作公司html网站 下载
  • 哪个网站的课件做的好crm客户管理系统全称
  • 网站建设工作室创业计划书seo是什么职位的简称
  • o2o平台网站开发什么是白帽seo
  • 免费建个人手机网站WordPress 简历库
  • 建网站 是否 数据库阳瘘的最佳治疗方法是什么
  • 知晓程序网站怎么做网站基础维护
  • 兼职做网站赚钱吗图片设计制作哪个软件好手机
  • 做手机旅游网站智慧校园登录入口
  • 莆田网站建设维护国外极简网站