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

高端企业网站价位网站建立具体步骤是

高端企业网站价位,网站建立具体步骤是,html5网站建设企业论文,网站建设宣传册🎮 作者主页:点击 🎁 完整专栏和代码:点击 🏡 博客主页:点击 文章目录 exceptions包分包设计ExceptionFactory类介绍为什么使用工厂不是直接new呢?【统一的异常处理机制】【异常的封装与转化】【…

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

文章目录

  • exceptions包
  • 分包设计
  • ExceptionFactory类
    • 介绍
    • 为什么使用工厂不是直接new呢?
      • 【统一的异常处理机制】
      • 【异常的封装与转化】
      • 【异常上下文(ErrorContext)】
      • 【扩展性】
  • ErrorContext 的作用
    • 概述
      • 代码
    • store()和recall()方法设计分析
    • 为什么需要 store 和 recall?

exceptions包

exceptions包为 MyBatis定义了绝大多数异常类的父类,同时也提供了异常类的生产工厂
在这里插入图片描述
在这里插入图片描述
MyBatis中异常类类图

分包设计

通过 MyBatis异常类的类图还可以看出,众多的异常类并没有放在 exceptions包中,而是散落在其他各个包中。这涉及项目规划时的分包问题。通常,在规划一个项目的包结构时,可以按照以下两种方式进行包的划分。
按照类型方式划分,例如将所有的接口类放入一个包,将所有的 Controller类放入一个包。这种分类方式从类型上看更为清晰,但是会将完成同一功能的多个类分散在不同的包中,不便于模块化开发。
按照功能方式划分,例如将所有与加/解密有关的类放入一个包,将所有与 HTTP请求有关的类放入一个包。这种分类方式下,同一功能的类内聚性高,便于模块化开发,但会导致同一包内类的类型混乱

通常,在进行一个项目的包结构设计时会同时采用以上两种划分方式。exceptions包就是按照类型划分出来的,但也有许多异常类按照功能划分到了其他包中。MyBatis 中的包也是按照上述两种方式划分的,一类是按照类型划分出来的包,如exceptions包、annotations包;一类是按照功能划分出来的包,如 logging包、plugin包。

在项目设计和开发中,我们推荐优先将功能耦合度高的类放入按照功能划分的包中,而将功能耦合度低或供多个功能使用的类放入按照类型划分的包中。这种划分思想不仅可以用在包的划分上,类、方法、代码片段的组合与拆分等都可以参照这种思想。

ExceptionFactory类

介绍

该类是负责生产 Exception的工厂。ExceptionFactory类只有两个方法。构造方法由 private修饰,确保该方法无法在类的外部被调用,也就永远无法生成该类的实例。通常,会对一些工具类、工厂类等仅提供静态方法的类进行这样的设置,因为这些类不需要实例化就可以使用。wrapException方法就是 ExceptionFactory类提供的静态方法,它用来生成并返回一个RuntimeException对象。

  @Overridepublic void rollback(boolean force) {try {executor.rollback(isCommitOrRollbackRequired(force));dirty = false;} catch (Exception e) {throw ExceptionFactory.wrapException("Error rolling back transaction.  Cause: " + e, e);} finally {ErrorContext.instance().reset();}}

/*** @author Clinton Begin*/
public class ExceptionFactory {private ExceptionFactory() {// Prevent Instantiation}public static RuntimeException wrapException(String message, Exception e) {return new PersistenceException(ErrorContext.instance().message(message).cause(e).toString(), e);}}

为什么使用工厂不是直接new呢?

【统一的异常处理机制】

通过 ExceptionFactory.wrapException 来封装异常,MyBatis 可以提供一个统一的异常处理方式。这样做的好处是,在整个系统中无论遇到什么异常,都会通过 wrapException 进行统一包装,并且可以附带有一致的异常信息(比如 ErrorContext 中的消息和堆栈信息)。这种方式增强了异常的一致性,方便了异常的管理和日志记录。

【异常的封装与转化】

直接 new 一个异常是可以的,但 MyBatis 通过 wrapException 将异常转化为 PersistenceException,这种做法有助于将底层异常封装成一个业务层异常(如 PersistenceException),而不是让底层的异常类型暴露给上层调用者。这样上层代码就不需要关心底层的具体实现细节(如 SQLException 或其他数据库相关的异常),只需要处理通用的业务异常(PersistenceException)。这也是常见的“异常转译”或“异常抽象”设计模式。

【异常上下文(ErrorContext)】

ErrorContext.instance().message(message).cause(e).toString() 通过 ErrorContext 来追踪异常的上下文信息,提供更多的诊断信息。这对于调试和日志分析非常有用,可以提供异常发生时的详细背景、错误信息以及导致异常的根本原因。这使得开发者可以更容易地定位问题,提升系统的可维护性。

【扩展性】

使用 ExceptionFactory 封装异常,意味着未来如果需要改变异常的处理方式(例如,加入更多的异常日志、不同的异常类型等),只需要在 wrapException 方法中做修改,而不需要修改系统中每个直接抛出异常的地方。这提高了代码的可维护性和可扩展性。
通过 ExceptionFactory.wrapException 这样的设计,MyBatis 实现了异常的统一封装、转化和上下文管理,增强了系统的可维护性、可调试性和可扩展性。直接 new 一个异常虽然简单,但缺乏统一的异常处理和额外的上下文信息,容易导致异常管理混乱。

ErrorContext 的作用

概述

MyBatis 中的 ErrorContext 设计主要用于捕获和存储在执行 SQL 操作过程中发生的错误的相关上下文信息。它通过提供详细的错误上下文信息来帮助开发人员调试和排查问题,尤其是在与数据库交互时发生异常时。ErrorContext 类主要的作用是封装和管理错误相关的诊断信息,使得错误日志更加易于理解和追踪。

代码

public class ErrorContext {private static final String LINE_SEPARATOR = System.lineSeparator();private static final ThreadLocal<ErrorContext> LOCAL = ThreadLocal.withInitial(ErrorContext::new);private ErrorContext stored;private String resource;private String activity;private String object;private String message;private String sql;private Throwable cause;private ErrorContext() {}public static ErrorContext instance() {return LOCAL.get();}public ErrorContext store() {ErrorContext newContext = new ErrorContext();newContext.stored = this;LOCAL.set(newContext);return LOCAL.get();}public ErrorContext recall() {if (stored != null) {LOCAL.set(stored);stored = null;}return LOCAL.get();}public ErrorContext resource(String resource) {this.resource = resource;return this;}public ErrorContext activity(String activity) {this.activity = activity;return this;}public ErrorContext object(String object) {this.object = object;return this;}public ErrorContext message(String message) {this.message = message;return this;}public ErrorContext sql(String sql) {this.sql = sql;return this;}public ErrorContext cause(Throwable cause) {this.cause = cause;return this;}public ErrorContext reset() {resource = null;activity = null;object = null;message = null;sql = null;cause = null;LOCAL.remove();return this;}@Overridepublic String toString() {StringBuilder description = new StringBuilder();// messageif (this.message != null) {description.append(LINE_SEPARATOR);description.append("### ");description.append(this.message);}// resourceif (resource != null) {description.append(LINE_SEPARATOR);description.append("### The error may exist in ");description.append(resource);}// objectif (object != null) {description.append(LINE_SEPARATOR);description.append("### The error may involve ");description.append(object);}// activityif (activity != null) {description.append(LINE_SEPARATOR);description.append("### The error occurred while ");description.append(activity);}// sqlif (sql != null) {description.append(LINE_SEPARATOR);description.append("### SQL: ");description.append(sql.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ').trim());}// causeif (cause != null) {description.append(LINE_SEPARATOR);description.append("### Cause: ");description.append(cause.toString());}return description.toString();}}

ErrorContext 的设计可以帮助 MyBatis 更好地追踪和记录执行过程中发生的异常和错误信息。它提供了关于 SQL 执行过程中各个步骤的详细信息,例如:当前正在执行的 SQL 语句、相关的映射文件、参数信息等,这些都可以帮助开发人员快速定位问题。

store()和recall()方法设计分析

在 MyBatis 中,private ErrorContext stored; 这行代码通常用于 保存当前线程的错误上下文。具体来说,stored 变量通常是一个 ErrorContext 类型的对象,它的作用是暂时存储和保存错误相关的信息,以便在整个操作过程中能够访问和更新。

 private ErrorContext stored;public ErrorContext store() {ErrorContext newContext = new ErrorContext();newContext.stored = this;LOCAL.set(newContext);return LOCAL.get();}public ErrorContext recall() {if (stored != null) {LOCAL.set(stored);stored = null;}return LOCAL.get();}

store() 方法
• 这个方法的作用是 保存当前的错误上下文 到一个新的 ErrorContext 实例中,并将其设置为当前线程的错误上下文。
• newContext.stored = this:这行代码的意思是,将当前的 ErrorContext(即 this)存储到新创建的 newContext 中,这样可以在之后恢复原来的上下文。
• LOCAL.set(newContext):将新创建的上下文对象设置为当前线程的 ErrorContext。由于使用了 ThreadLocal,每个线程都会有独立的错误上下文。
• return LOCAL.get():返回当前线程的 ErrorContext(即 newContext)。

store() 方法一般在 操作开始时调用,用于 保存当前线程的错误上下文,并为后续的错误信息提供独立的上下文。比如,当处理一个新的数据库操作时,可能需要清空当前的错误上下文并开始一个新的上下文。在执行某个操作时,如果错误发生,则可以在新的上下文中记录错误信息。

recall() 方法通常用于 操作完成后,恢复原来的错误上下文,特别是在跨越多个操作的错误追踪中,恢复原来的上下文信息。比如,在处理完某个操作后,系统可能需要恢复到先前的错误上下文,以便继续处理其他操作或者记录原有的错误信息。

  protected void generateKeys(Object parameter) {KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();ErrorContext.instance().store();keyGenerator.processBefore(executor, mappedStatement, null, parameter);ErrorContext.instance().recall();}

上面这段代码就是实际mybatis使用store和recall地方。
这段代码出现在 MyBatis 中,通常是在执行某些数据库操作时生成主键的过程,尤其是在插入操作中,涉及到主键生成的逻辑。generateKeys() 方法负责生成数据库操作后的主键,并确保在生成主键的过程中能够正确管理和追踪错误上下文。让我们逐行分析这段代码,理解其具体含义和作用:

protected void generateKeys(Object parameter) {// 获取与当前映射语句相关的 KeyGeneratorKeyGenerator keyGenerator = mappedStatement.getKeyGenerator();// 存储当前线程的错误上下文,防止在主键生成过程中出现错误时丢失上下文ErrorContext.instance().store();// 在执行主键生成前,调用 KeyGenerator 的处理方法keyGenerator.processBefore(executor, mappedStatement, null, parameter);// 恢复之前存储的错误上下文,确保其他操作的错误上下文不受影响ErrorContext.instance().recall();
}

为什么需要 store 和 recall?

在 MyBatis 中,ErrorContext 负责捕获和存储当前错误的上下文信息。在多步骤的操作中(如插入操作生成主键时),有时会因为主键生成的策略(如自增长主键)涉及到复杂的数据库操作,因此需要确保在生成主键之前,当前的错误上下文能够被保存,避免在主键生成时如果发生错误丢失上下文信息。
通过调用 store() 方法,保存当前错误上下文,并在执行主键生成逻辑后通过 recall() 恢复之前的上下文,能够确保错误信息在不同的操作之间得到正确的隔离和处理。这种方式使得 MyBatis 可以精确地记录并跟踪错误,尤其是在复杂的多步骤操作中,避免错误上下文的混乱。

上面方法的最外层是DefaultSqlSession#update(java.lang.String, java.lang.Object)

  @Overridepublic int update(String statement, Object parameter) {try {dirty = true;MappedStatement ms = configuration.getMappedStatement(statement);return executor.update(ms, wrapCollection(parameter));} catch (Exception e) {throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);} finally {ErrorContext.instance().reset();}}

上面会捕获所有的异常并使用ExceptionFactory,而里面输出的信息就是ErrorContext存储的。
假设执行keyGenerator.processBefore(executor, mappedStatement, null, parameter);出现数据库异常了,那么此时可能抛出SQLException异常,而且在processBefore中会执行很多的自定义的操作,这些可能导致ErrorContext中存储的信息被修改了,那么之前在processBefore前保存的上下文信息就丢失了,这就会导致最终异常信息输出的时候只有processBefore的信息了,而丢失了原来的上下文信息,在使用了store方法后,先将这个前面的上下文信息保存,这样的话,假设在processBefore中ErrorContext信息被修改了,在最后的异常信息输出的时候,也可以通过store字段获取到。store() 和 recall() 确保了每个操作的错误上下文是独立的。在 generateKeys() 执行前,保存当前的错误上下文,在生成主键后恢复原有的上下文。这样,即使在执行过程中某个操作失败,错误信息也能清楚地区分开来,避免了上下文混乱。如果 generateKeys() 阶段失败,错误信息会指明是主键生成阶段的问题,而不是后续的更新操作。这样能够更容易地诊断和解决问题。会清楚知道错误发生在更新操作而不是主键生成阶段,从而能够更快定位问题。

通过使用 ErrorContext 进行错误上下文的存储和恢复,可以确保每个操作的错误信息都能得到独立处理,便于调试和问题的准确定位。


文章转载自:
http://protozoal.rywn.cn
http://orache.rywn.cn
http://fretful.rywn.cn
http://smirnoff.rywn.cn
http://trebuchet.rywn.cn
http://intracardiac.rywn.cn
http://lyssic.rywn.cn
http://intubate.rywn.cn
http://enterolith.rywn.cn
http://borated.rywn.cn
http://serriform.rywn.cn
http://soppy.rywn.cn
http://editorship.rywn.cn
http://fleam.rywn.cn
http://butterfingers.rywn.cn
http://bale.rywn.cn
http://dsc.rywn.cn
http://phenobarbital.rywn.cn
http://canalisation.rywn.cn
http://former.rywn.cn
http://communicable.rywn.cn
http://siddhi.rywn.cn
http://pastorale.rywn.cn
http://cpcu.rywn.cn
http://studded.rywn.cn
http://contravention.rywn.cn
http://ophthalmitis.rywn.cn
http://lollapalooza.rywn.cn
http://sab.rywn.cn
http://halogenation.rywn.cn
http://flutey.rywn.cn
http://bivouacking.rywn.cn
http://corruptible.rywn.cn
http://timorous.rywn.cn
http://rowdedow.rywn.cn
http://mayo.rywn.cn
http://sirian.rywn.cn
http://ruthenia.rywn.cn
http://archness.rywn.cn
http://breen.rywn.cn
http://inconclusively.rywn.cn
http://thermosiphon.rywn.cn
http://pussytoes.rywn.cn
http://remedy.rywn.cn
http://pasquil.rywn.cn
http://pneumatograph.rywn.cn
http://crackle.rywn.cn
http://aeroballistics.rywn.cn
http://northeastward.rywn.cn
http://acicular.rywn.cn
http://eent.rywn.cn
http://bearbaiter.rywn.cn
http://aft.rywn.cn
http://already.rywn.cn
http://covariation.rywn.cn
http://senectitude.rywn.cn
http://rexine.rywn.cn
http://downward.rywn.cn
http://convector.rywn.cn
http://equipotential.rywn.cn
http://gazer.rywn.cn
http://quetta.rywn.cn
http://foamflower.rywn.cn
http://lantana.rywn.cn
http://reliably.rywn.cn
http://knotty.rywn.cn
http://omnisexual.rywn.cn
http://sowcar.rywn.cn
http://hepster.rywn.cn
http://mausoleum.rywn.cn
http://crystalloid.rywn.cn
http://bleachery.rywn.cn
http://aimlessly.rywn.cn
http://limner.rywn.cn
http://gradualness.rywn.cn
http://tref.rywn.cn
http://leach.rywn.cn
http://connote.rywn.cn
http://bushfighter.rywn.cn
http://lamaze.rywn.cn
http://xxxi.rywn.cn
http://calciphobous.rywn.cn
http://unhuman.rywn.cn
http://luxembourg.rywn.cn
http://interlanguage.rywn.cn
http://information.rywn.cn
http://zarape.rywn.cn
http://revamp.rywn.cn
http://lamia.rywn.cn
http://unburden.rywn.cn
http://rubout.rywn.cn
http://sevenfold.rywn.cn
http://rooinek.rywn.cn
http://reune.rywn.cn
http://guadalcanal.rywn.cn
http://ketolysis.rywn.cn
http://miniminded.rywn.cn
http://deoxygenization.rywn.cn
http://revolvable.rywn.cn
http://elyseeology.rywn.cn
http://www.15wanjia.com/news/92583.html

相关文章:

  • 养殖公司网站市场调查报告模板及范文
  • 陕西省建设执业资格注册中心网站网站收录查询站长工具
  • 做计算机项目的网站百度seo泛解析代发排名
  • 济南网站制作工作室搜索引擎营销的实现方法
  • 网站自适应手机转码网站关键词推广工具
  • 大连网站建设多少钱附近的电脑培训班在哪里
  • 在线设计软件网站信息流广告优秀案例
  • 查一下红之易道学做的什么网站南宁seo计费管理
  • 网站建设网站网站建设网站大数据智能营销
  • 如何自己做资源类网站品牌营销策划是干嘛的
  • 合肥市建设通网站做销售记住这十句口诀
  • ps网站怎么做滑动背景提高网站搜索排名
  • 免费程序网站百度收录官网
  • jsp和.net做网站的区别必应搜索引擎网站
  • synology建设网站市场营销推广方案怎么做
  • 宁波网站建设方案咨询宁波网站推广制作
  • 做素材网站存储问题东台网络推广
  • 中企动力优秀网站百度爱采购关键词优化
  • 南充住房和城乡建设厅网站站长工具的使用seo综合查询运营
  • 简述企业网站的建设过程武汉网络推广自然排名
  • 网站程上传站长工具使用
  • ui生成器网站做一个微信小程序需要多少钱
  • 建设网站目的百度大搜数据多少钱一条
  • 网站子站怎么做、友情链接是啥意思
  • 网页制作网站建设公司it人必看的网站
  • 网站建设选超速云建站宁波seo快速优化公司
  • 流量网站怎么盈利腾讯朋友圈广告投放价格
  • 受欢迎的免费建站乐天seo视频教程
  • 网站备案时间也太慢了app平台搭建需要多少钱
  • 做网站需要买域名牛奶推广软文文章