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

零基础学网站建设互联网营销师是干什么的

零基础学网站建设,互联网营销师是干什么的,哪些网站可以做设计赚钱,建设银行信用卡申请网站🎮 作者主页:点击 🎁 完整专栏和代码:点击 🏡 博客主页:点击 文章目录 MapperRegistry 的作用核心字段解析整体工作流程addMapper方法MapperAnnotationBuilder#parse流程详解MapperAnnotationBuilder#parse…

🎮 作者主页:点击
🎁 完整专栏和代码:点击
🏡 博客主页:点击

文章目录

  • MapperRegistry 的作用
  • 核心字段解析
  • 整体工作流程
  • addMapper方法
  • MapperAnnotationBuilder#parse流程详解
  • MapperAnnotationBuilder#parseStatement
      • 处理主键生成策略(KeyGenerator)
      • 处理缓存、超时、ResultMap 等配置
      • 处理 ResultMap
      • 注册 MappedStatement

MapperRegistry 的作用

MapperRegistry 是 MyBatis 核心组件之一,主要负责管理 Mapper 接口的注册和获取。当通过 sqlSession.getMapper(XXXMapper.class) 获取 Mapper 实例时,会通过 MapperRegistry 返回相应的 Mapper 代理对象。

核心字段解析

private final Configuration config;
private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

• Configuration:MyBatis 的全局配置对象,管理 MyBatis 的各种配置信息。
• knownMappers:用于存储已经注册的 Mapper 接口及其对应的 MapperProxyFactory。

整体工作流程

  1. Mapper 注册:
    ◦ 通过 addMapper 方法注册 Mapper 接口,将其与 MapperProxyFactory 绑定,并解析注解或 XML 配置文件。
  2. Mapper 获取:
    ◦ 通过 getMapper 方法获取 Mapper 实例,实际返回的是一个动态代理对象 (MapperProxy)。
  3. 动态代理执行:
    ◦ 当调用 Mapper 方法时,代理对象 (MapperProxy) 会拦截方法调用,并根据方法上的注解或 XML 配置执行对应的 SQL 语句。

addMapper方法

MapperRegistry#addMapper 是 MyBatis 框架中的一个核心方法,用于将 Mapper 接口注册到 MyBatis 环境中。这一过程确保 MyBatis 能够正确识别和管理 Mapper 接口,以便在实际使用时生成相应的代理对象。

public <T> void addMapper(Class<T> type) {// 判断是否是接口,如果不是接口,直接返回if (type.isInterface()) {if (hasMapper(type)) {// 防止重复注册,如果已经注册过,则抛出异常throw new BindingException("Type " + type + " is already known to the MapperRegistry.");}boolean loadCompleted = false;try {// 添加到 knownMappers(一个 Map<Class<?>, MapperProxyFactory<?>>)中knownMappers.put(type, new MapperProxyFactory<>(type));// It's 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 won't try.// 检查该接口是否有与之关联的 XML 映射文件MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);parser.parse();loadCompleted = true;} finally {if (!loadCompleted) {knownMappers.remove(type);}}}}

MapperAnnotationBuilder#parse流程详解

MapperRegistry#addMapper方法流程最后是将解析流程交给了MapperAnnotationBuilder#parse,下面针对这个方法进行详细分析。
org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#parse 是 MyBatis 中用来解析 @Mapper 接口中注解的方法,它的作用是扫描并处理 @Select, @Insert, @Update, @Delete 等 SQL 操作注解,生成对应的 MappedStatement 并将其注册到 Configuration 中。

  public void parse() {String resource = type.toString();// 检查资源是否已加载if (!configuration.isResourceLoaded(resource)) {// 解析加载mapper关联的XML文件信息,如果是注解形式则为空loadXmlResource();configuration.addLoadedResource(resource);assistant.setCurrentNamespace(type.getName());// 解析缓存和缓存引用parseCache();parseCacheRef();// 获取当前 Mapper 接口中的所有方法for (Method method : type.getMethods()) {// 调用 canHaveStatement(method) 方法检查该方法是否适合生成 MappedStatementif (!canHaveStatement(method)) {continue;}// 处理Select和SelectProvider注解方法if (getAnnotationWrapper(method, false, Select.class, SelectProvider.class).isPresent()&& method.getAnnotation(ResultMap.class) == null) {parseResultMap(method);}try {// 解析 Mapper 方法上的注解并生成 MappedStatementparseStatement(method);} catch (IncompleteElementException e) {configuration.addIncompleteMethod(new MethodResolver(this, method));}}}parsePendingMethods();}

• 通过 configuration.isResourceLoaded(resource) 检查当前 Mapper 是否已经被加载过,如果加载过则直接返回,避免重复加载。如果没有加载过,则将其标记为已加载。
• loadXmlResource用于加载 XML 资源(即 Mapper.xml 文件),并确保其与 @Mapper 注解的接口绑定在一起。如果 Mapper.xml 存在,则将其加载到 Configuration 中,并将其中的 select, insert, update, delete 等语句转换为 MappedStatement。
• assistant.setCurrentNamespace(type.getName()) 的作用是将当前 Mapper 接口的全限定类名(如 com.example.mapper.UserMapper)设置为命名空间。MyBatis 中的命名空间是用于隔离不同 Mapper 的关键机制,确保每个 MappedStatement 的 id 是唯一的,避免冲突。
• canHaveStatement(Method method) 方法用于判断当前 Mapper 接口中的某个方法是否可以解析为 MyBatis 的 MappedStatement。这意味着只有符合条件的方法,MyBatis 才会尝试为其生成对应的 SQL 映射语句(MappedStatement)。method.isBridge()排除桥接方法。method.isDefault() 用于检查该方法是否为 Java 8 引入的接口默认方法。

MapperAnnotationBuilder#parseStatement

这段代码是 org.apache.ibatis.builder.annotation.MapperAnnotationBuilder 类的一部分,其作用是从 Mapper接口的方法(通常标注有 @Select、@Insert、@Update 或 @Delete 注解的方法)中提取信息,并构建出 MappedStatement 对象,用于 SQL 的执行。
以下是方法的总体思路:

  1. 解析方法参数类型。
  2. 获取方法所使用的语言驱动(LanguageDriver)。
  3. 从注解中构建 SqlSource 和 SqlCommandType。
  4. 解析主键生成策略。
  5. 解析缓存、超时、结果集等配置。
  6. 生成并注册 MappedStatement。
final Class<?> parameterTypeClass = getParameterType(method);
final LanguageDriver languageDriver = getLanguageDriver(method);

• getParameterType(method):获取方法的参数类型。如果方法有多个参数,则 MyBatis 会将其封装为 Map 类型。
• getLanguageDriver(method):确定使用哪种语言驱动,默认是 XMLLanguageDriver。语言驱动用于解析 SQL 语句,可以是注解中的 SQL,也可以是 XML 配置中的 SQL。

getAnnotationWrapper(method, true, statementAnnotationTypes).ifPresent(statementAnnotation -> {final SqlSource sqlSource = buildSqlSource(statementAnnotation.getAnnotation(), parameterTypeClass, languageDriver, method);final SqlCommandType sqlCommandType = statementAnnotation.getSqlCommandType();
  private SqlSource buildSqlSource(Annotation annotation, Class<?> parameterType, LanguageDriver languageDriver,Method method) {if (annotation instanceof Select) {return buildSqlSourceFromStrings(((Select) annotation).value(), parameterType, languageDriver);} else if (annotation instanceof Update) {return buildSqlSourceFromStrings(((Update) annotation).value(), parameterType, languageDriver);} else if (annotation instanceof Insert) {return buildSqlSourceFromStrings(((Insert) annotation).value(), parameterType, languageDriver);} else if (annotation instanceof Delete) {return buildSqlSourceFromStrings(((Delete) annotation).value(), parameterType, languageDriver);} else if (annotation instanceof SelectKey) {return buildSqlSourceFromStrings(((SelectKey) annotation).statement(), parameterType, languageDriver);}return new ProviderSqlSource(assistant.getConfiguration(), annotation, type, method);}

• getAnnotationWrapper():获取方法上的 SQL 注解(如 @Select、@Insert 等)。
• buildSqlSource():根据注解内容生成 SqlSource 对象,SqlSource 用于封装 SQL 语句,并处理占位符参数(如 #{})。
• getSqlCommandType():确定 SQL 命令类型,如 SELECT、INSERT、UPDATE、DELETE。

      final Options options = getAnnotationWrapper(method, false, Options.class).map(x -> (Options)x.getAnnotation()).orElse(null);

它的作用是从 Mapper 方法中获取 @Options 注解,并将其解析为 Options 对象,以便在后续配置 MappedStatement时使用。MyBatis 提供了 @Options 注解,用于配置 Mapper 方法的一些额外选项。常见的配置选项包括:useCache:是否启用二级缓存。timeout:SQL 执行超时时间。

处理主键生成策略(KeyGenerator)

// 处理主键生成策略(KeyGenerator)final KeyGenerator keyGenerator;String keyProperty = null;String keyColumn = null;if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {// 如果方法上有 @SelectKey 注解,使用其生成主键SelectKey selectKey = getAnnotationWrapper(method, false, SelectKey.class).map(x -> (SelectKey)x.getAnnotation()).orElse(null);if (selectKey != null) {keyGenerator = handleSelectKeyAnnotation(selectKey, mappedStatementId, getParameterType(method), languageDriver);keyProperty = selectKey.keyProperty();} else if (options == null) {// 默认使用 JDBC3 的主键生成方式keyGenerator = configuration.isUseGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;} else {keyGenerator = options.useGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;keyProperty = options.keyProperty();keyColumn = options.keyColumn();}} else {keyGenerator = NoKeyGenerator.INSTANCE;}

• 如果 SqlCommandType 是 INSERT 或 UPDATE,则可能需要生成主键。
• 优先使用 @SelectKey 注解来生成主键;如果没有,则根据配置选择是否自动生成主键。
• keyProperty 和 keyColumn 用于指定主键映射。

处理缓存、超时、ResultMap 等配置

  // 处理缓存、超时、ResultMap 等配置Integer fetchSize = null;Integer timeout = null;// statementType:语句类型,默认为 PREPARED,还可以是 STATEMENT 或 CALLABLE。StatementType statementType = StatementType.PREPARED;ResultSetType resultSetType = configuration.getDefaultResultSetType();boolean isSelect = sqlCommandType == SqlCommandType.SELECT;boolean flushCache = !isSelect;boolean useCache = isSelect;if (options != null) {// 从方法上的 @Options 注解中提取配置,如 flushCache、useCache、fetchSize 和 timeout。if (FlushCachePolicy.TRUE.equals(options.flushCache())) {flushCache = true;} else if (FlushCachePolicy.FALSE.equals(options.flushCache())) {flushCache = false;}useCache = options.useCache();fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348timeout = options.timeout() > -1 ? options.timeout() : null;statementType = options.statementType();if (options.resultSetType() != ResultSetType.DEFAULT) {resultSetType = options.resultSetType();}}

处理 ResultMap

 // 处理 ResultMapString resultMapId = null;if (isSelect) {// 如果方法是 SELECT 查询,则可能需要 ResultMap 来映射结果集到 Java 对象。ResultMap resultMapAnnotation = method.getAnnotation(ResultMap.class);if (resultMapAnnotation != null) {// 优先使用 @ResultMap 注解;如果没有,则自动生成 ResultMap。resultMapId = String.join(",", resultMapAnnotation.value());} else {resultMapId = generateResultMapName(method);}}

注册 MappedStatement

 // 注册 MappedStatementassistant.addMappedStatement(mappedStatementId,sqlSource,statementType,sqlCommandType,fetchSize,timeout,// ParameterMapIDnull,parameterTypeClass,resultMapId,getReturnType(method),resultSetType,flushCache,useCache,// TODO gcode issue #577false,keyGenerator,keyProperty,keyColumn,statementAnnotation.getDatabaseId(),languageDriver,// ResultSetsoptions != null ? nullOrEmpty(options.resultSets()) : null);

• 调用 assistant.addMappedStatement() 将解析好的信息封装成 MappedStatement 并注册到 MyBatis 的 Configuration 中。
• MappedStatement 包含了执行 SQL 所需的所有信息,包括 SQL 语句、参数类型、结果集映射、缓存策略等。


文章转载自:
http://dinncocounterfoil.bkqw.cn
http://dinncovascular.bkqw.cn
http://dinnconapless.bkqw.cn
http://dinncoyugawaralite.bkqw.cn
http://dinncosympathin.bkqw.cn
http://dinncomicrosequencer.bkqw.cn
http://dinncophotometric.bkqw.cn
http://dinncolingual.bkqw.cn
http://dinncosomatopsychic.bkqw.cn
http://dinncobraunschweig.bkqw.cn
http://dinncoexpressionism.bkqw.cn
http://dinncoleachability.bkqw.cn
http://dinncozilch.bkqw.cn
http://dinncopettily.bkqw.cn
http://dinncobywork.bkqw.cn
http://dinncounknowable.bkqw.cn
http://dinncohylomorphism.bkqw.cn
http://dinncokinase.bkqw.cn
http://dinncotricoline.bkqw.cn
http://dinncoimminence.bkqw.cn
http://dinncohypericum.bkqw.cn
http://dinncolandocracy.bkqw.cn
http://dinncofractionlet.bkqw.cn
http://dinncomiler.bkqw.cn
http://dinncoproteinic.bkqw.cn
http://dinncoputrefy.bkqw.cn
http://dinncotriticale.bkqw.cn
http://dinncodiageotropic.bkqw.cn
http://dinncotdy.bkqw.cn
http://dinncounspeak.bkqw.cn
http://dinncoaccrual.bkqw.cn
http://dinncobill.bkqw.cn
http://dinncopyometra.bkqw.cn
http://dinncoschizogenous.bkqw.cn
http://dinncorosolite.bkqw.cn
http://dinncotransphosphorylation.bkqw.cn
http://dinncopetrograph.bkqw.cn
http://dinncoumber.bkqw.cn
http://dinncomage.bkqw.cn
http://dinncoqiana.bkqw.cn
http://dinncoparamount.bkqw.cn
http://dinncoawe.bkqw.cn
http://dinncoroar.bkqw.cn
http://dinncoarcuate.bkqw.cn
http://dinncocurtle.bkqw.cn
http://dinncodevonshire.bkqw.cn
http://dinncoauthorware.bkqw.cn
http://dinncoroxburgh.bkqw.cn
http://dinnconumb.bkqw.cn
http://dinncoimpendent.bkqw.cn
http://dinncodilutive.bkqw.cn
http://dinncogrey.bkqw.cn
http://dinncorestrictionism.bkqw.cn
http://dinncomusa.bkqw.cn
http://dinncoendostea.bkqw.cn
http://dinncoparaformaldehyde.bkqw.cn
http://dinncoconcupiscence.bkqw.cn
http://dinncoreschedule.bkqw.cn
http://dinncocheeselike.bkqw.cn
http://dinncopantile.bkqw.cn
http://dinncomarc.bkqw.cn
http://dinncoaberglaube.bkqw.cn
http://dinncocinematheque.bkqw.cn
http://dinncoreset.bkqw.cn
http://dinncomulki.bkqw.cn
http://dinncoabdominous.bkqw.cn
http://dinncotugboatman.bkqw.cn
http://dinncordac.bkqw.cn
http://dinncocatachrestial.bkqw.cn
http://dinncora.bkqw.cn
http://dinncobussbar.bkqw.cn
http://dinncoumbellifer.bkqw.cn
http://dinncoplebeianize.bkqw.cn
http://dinncospicula.bkqw.cn
http://dinncoeutectic.bkqw.cn
http://dinncoarjuna.bkqw.cn
http://dinncointrusion.bkqw.cn
http://dinncodamnum.bkqw.cn
http://dinncofoxbase.bkqw.cn
http://dinncocern.bkqw.cn
http://dinncochiv.bkqw.cn
http://dinncozacharias.bkqw.cn
http://dinncooverinspirational.bkqw.cn
http://dinnconotarikon.bkqw.cn
http://dinncodinoflagellate.bkqw.cn
http://dinncofumigate.bkqw.cn
http://dinncotransmontane.bkqw.cn
http://dinncothoughtway.bkqw.cn
http://dinncoparrotfish.bkqw.cn
http://dinncosakya.bkqw.cn
http://dinncoassertative.bkqw.cn
http://dinncoexcremental.bkqw.cn
http://dinncophytosociology.bkqw.cn
http://dinncovolumenometer.bkqw.cn
http://dinncorepaper.bkqw.cn
http://dinncousurpative.bkqw.cn
http://dinncooracular.bkqw.cn
http://dinncoprotestant.bkqw.cn
http://dinncokiangsu.bkqw.cn
http://dinncourotropine.bkqw.cn
http://www.dinnco.com/news/141022.html

相关文章:

  • 网站怎么做流量互换网络营销推广难做吗
  • 地方门户类网站产品推广营销型网站一般有哪些内容
  • 企业彩铃制作网站本周的新闻大事10条
  • 自己做电商网站.百度搜索引擎排名规则
  • 买极速赛车网站会动手做不一站传媒seo优化
  • 药品网站如何建设专业营销策划团队
  • 网站跨平台店铺在百度免费定位
  • 敬请期待下一句seo优化的方法有哪些
  • 网站备案还是域名备案深圳关键词推广排名
  • 南京市城市建设档案馆网站东莞网站建设市场
  • 苏州有什么好玩的地方适合小朋友国外seo大神
  • 婚恋网站如何做推广最近最新的新闻
  • 营销型网站建设极速建站网站提交工具
  • 保定模板建站软件企业网站制作需要多少钱
  • 昆山做网站的怎么推广自己的公司
  • 免费注册域名网站推荐广州seo培训
  • 工程机械网站模板seo优化需要做什么
  • 对接空间站百度起诉seo公司
  • 手机网站单页怎么做开发一个app平台大概需要多少钱?
  • 罗湖附近公司做网站建设哪家服务周到西安网站关键词推广
  • 自媒体营销方式有哪些seo网站编辑优化招聘
  • 福建省城乡建设官方网站网站开发费用
  • dw制作简单网站模板企业网站有哪些类型
  • 湛江做网站的有哪些短视频推广引流方案
  • 90平方装修全包价格优化seo是什么
  • 做婚恋网站的费用多少首页排名seo
  • 不是万维网的网站怎么做外链
  • 虚拟主机网站建设过程免费观看b站的广告网站平台
  • 清河网站建设google关键词工具
  • 企业网站托管方案网站优化基本技巧