• 关于 外部作用域如何看配置 的搜索结果

问题

【精品问答】Java技术1000问(1)

问问小秘 2019-12-01 21:57:43 34170 浏览量 回答数 10

回答

初识 MyBatis MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到数据库字段和记录。 MyBatis 的特点 那么 MyBatis 具有什么特点呢?或许我们可以从如下几个方面来描述 MyBatis 中的 SQL 语句和主要业务代码分离,我们一般会把 MyBatis 中的 SQL 语句统一放在 XML 配置文件中,便于统一维护。 解除 SQL 与程序代码的耦合,通过提供 DAO 层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。SQL 和代码的分离,提高了可维护性。 MyBatis 比较简单和轻量 本身就很小且简单。没有任何第三方依赖,只要通过配置 jar 包,或者如果你使用 Maven 项目的话只需要配置 Maven 以来就可以。易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。 屏蔽样板代码 MyBatis 回屏蔽原始的 JDBC 样板代码,让你把更多的精力专注于 SQL 的书写和属性-字段映射上。 编写原生 SQL,支持多表关联 MyBatis 最主要的特点就是你可以手动编写 SQL 语句,能够支持多表关联查询。 提供映射标签,支持对象与数据库的 ORM 字段关系映射 ORM 是什么?对象关系映射(Object Relational Mapping,简称ORM) ,是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 提供 XML 标签,支持编写动态 SQL。 你可以使用 MyBatis XML 标签,起到 SQL 模版的效果,减少繁杂的 SQL 语句,便于维护。 MyBatis 整体架构 MyBatis 最上面是接口层,接口层就是开发人员在 Mapper 或者是 Dao 接口中的接口定义,是查询、新增、更新还是删除操作;中间层是数据处理层,主要是配置 Mapper -> XML 层级之间的参数映射,SQL 解析,SQL 执行,结果映射的过程。上述两种流程都由基础支持层来提供功能支撑,基础支持层包括连接管理,事务管理,配置加载,缓存处理等。 接口层 在不与Spring 集成的情况下,使用 MyBatis 执行数据库的操作主要如下: InputStream is = Resources.getResourceAsStream("myBatis-config.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); sqlSession = factory.openSession(); 其中的SqlSessionFactory,SqlSession是 MyBatis 接口的核心类,尤其是 SqlSession,这个接口是MyBatis 中最重要的接口,这个接口能够让你执行命令,获取映射,管理事务。 数据处理层 配置解析 在 Mybatis 初始化过程中,会加载 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configration 对象中。之后,根据该对象创建SqlSessionFactory 对象。待 Mybatis 初始化完成后,可以通过 SqlSessionFactory 创建 SqlSession 对象并开始数据库操作。 SQL 解析与 scripting 模块 Mybatis 实现的动态 SQL 语句,几乎可以编写出所有满足需要的 SQL。 Mybatis 中 scripting 模块会根据用户传入的参数,解析映射文件中定义的动态 SQL 节点,形成数据库能执行的SQL 语句。 SQL 执行 SQL 语句的执行涉及多个组件,包括 MyBatis 的四大核心,它们是: Executor、StatementHandler、ParameterHandler、ResultSetHandler。SQL 的执行过程可以用下面这幅图来表示 MyBatis 层级结构各个组件的介绍(这里只是简单介绍,具体介绍在后面): SqlSession: ,它是 MyBatis 核心 API,主要用来执行命令,获取映射,管理事务。接收开发人员提供 Statement Id 和参数。并返回操作结果。Executor :执行器,是 MyBatis 调度的核心,负责 SQL 语句的生成以及查询缓存的维护。StatementHandler : 封装了JDBC Statement 操作,负责对 JDBC Statement 的操作,如设置参数、将Statement 结果集转换成 List 集合。ParameterHandler : 负责对用户传递的参数转换成 JDBC Statement 所需要的参数。ResultSetHandler : 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合。TypeHandler : 用于 Java 类型和 JDBC 类型之间的转换。MappedStatement : 动态 SQL 的封装SqlSource : 表示从 XML 文件或注释读取的映射语句的内容,它创建将从用户接收的输入参数传递给数据库的 SQL。Configuration: MyBatis 所有的配置信息都维持在 Configuration 对象之中。 基础支持层 反射模块 Mybatis 中的反射模块,对 Java 反射进行了很好的封装,提供了简易的 API,方便上层调用,并且对反射操作进行了一系列的优化,比如,缓存了类的 元数据(MetaClass)和对象的元数据(MetaObject),提高了反射操作的性能。 类型转换模块 Mybatis 的别名机制,能够简化配置文件,该机制是类型转换模块的主要功能之一。类型转换模块的另一个功能是实现 JDBC 类型与 Java 类型的转换。在 SQL 语句绑定参数时,会将数据由 Java 类型转换成 JDBC 类型;在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型。 日志模块 在 Java 中,有很多优秀的日志框架,如 Log4j、Log4j2、slf4j 等。Mybatis 除了提供了详细的日志输出信息,还能够集成多种日志框架,其日志模块的主要功能就是集成第三方日志框架。 资源加载模块 该模块主要封装了类加载器,确定了类加载器的使用顺序,并提供了加载类文件和其它资源文件的功能。 解析器模块 该模块有两个主要功能:一个是封装了 XPath,为 Mybatis 初始化时解析 mybatis-config.xml配置文件以及映射配置文件提供支持;另一个为处理动态 SQL 语句中的占位符提供支持。 数据源模块 Mybatis 自身提供了相应的数据源实现,也提供了与第三方数据源集成的接口。数据源是开发中的常用组件之一,很多开源的数据源都提供了丰富的功能,如连接池、检测连接状态等,选择性能优秀的数据源组件,对于提供ORM 框架以及整个应用的性能都是非常重要的。 事务管理模块 一般地,Mybatis 与 Spring 框架集成,由 Spring 框架管理事务。但 Mybatis 自身对数据库事务进行了抽象,提供了相应的事务接口和简单实现。 缓存模块 Mybatis 中有一级缓存和二级缓存,这两级缓存都依赖于缓存模块中的实现。但是需要注意,这两级缓存与Mybatis 以及整个应用是运行在同一个 JVM 中的,共享同一块内存,如果这两级缓存中的数据量较大,则可能影响系统中其它功能,所以需要缓存大量数据时,优先考虑使用 Redis、Memcache 等缓存产品。 Binding 模块 在调用 SqlSession 相应方法执行数据库操作时,需要制定映射文件中定义的 SQL 节点,如果 SQL 中出现了拼写错误,那就只能在运行时才能发现。为了能尽早发现这种错误,Mybatis 通过 Binding 模块将用户自定义的Mapper 接口与映射文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作,从而避免上述问题。注意,在开发中,我们只是创建了 Mapper 接口,而并没有编写实现类,这是因为 Mybatis 自动为 Mapper 接口创建了动态代理对象。 MyBatis 核心组件 在认识了 MyBatis 并了解其基础架构之后,下面我们来看一下 MyBatis 的核心组件,就是这些组件实现了从 SQL 语句到映射到 JDBC 再到数据库字段之间的转换,执行 SQL 语句并输出结果集。首先来认识 MyBatis 的第一个核心组件 SqlSessionFactory 对于任何框架而言,在使用该框架之前都要经历过一系列的初始化流程,MyBatis 也不例外。MyBatis 的初始化流程如下 String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); sqlSessionFactory.openSession(); 上述流程中比较重要的一个对象就是SqlSessionFactory,SqlSessionFactory 是 MyBatis 框架中的一个接口,它主要负责的是 MyBatis 框架初始化操作 为开发人员提供SqlSession 对象 SqlSessionFactory 有两个实现类,一个是 SqlSessionManager 类,一个是 DefaultSqlSessionFactory 类 DefaultSqlSessionFactory : SqlSessionFactory 的默认实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。 SqlSessionManager : 已被废弃,原因大概是: SqlSessionManager 中需要维护一个自己的线程池,而使用MyBatis 更多的是要与 Spring 进行集成,并不会单独使用,所以维护自己的 ThreadLocal 并没有什么意义,所以 SqlSessionManager 已经不再使用。 ####SqlSessionFactory 的执行流程 下面来对 SqlSessionFactory 的执行流程来做一个分析 首先第一步是 SqlSessionFactory 的创建 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 1 从这行代码入手,首先创建了一个 SqlSessionFactoryBuilder 工厂,这是一个建造者模式的设计思想,由 builder 建造者来创建 SqlSessionFactory 工厂 然后调用 SqlSessionFactoryBuilder 中的 build 方法传递一个InputStream 输入流,Inputstream 输入流中就是你传过来的配置文件 mybatis-config.xml,SqlSessionFactoryBuilder 根据传入的 InputStream 输入流和environment、properties属性创建一个XMLConfigBuilder对象。SqlSessionFactoryBuilder 对象调用XMLConfigBuilder 的parse()方法,流程如下。 XMLConfigBuilder 会解析/configuration标签,configuration 是 MyBatis 中最重要的一个标签,下面流程会介绍 Configuration 标签。 MyBatis 默认使用 XPath 来解析标签,关于 XPath 的使用,参见 https://www.w3school.com.cn/xpath/index.asp 在 parseConfiguration 方法中,会对各个在 /configuration 中的标签进行解析 重要配置 说一下这些标签都是什么意思吧 properties,外部属性,这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。 <properties> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="root" /> </properties> 一般用来给 environment 标签中的 dataSource 赋值 <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </dataSource> </environment> 还可以通过外部属性进行配置,但是我们这篇文章以原理为主,不会介绍太多应用层面的操作。 settings ,MyBatis 中极其重要的配置,它们会改变 MyBatis 的运行时行为。 settings 中配置有很多,具体可以参考 https://mybatis.org/mybatis-3/zh/configuration.html#settings 详细了解。这里介绍几个平常使用过程中比较重要的配置 一般使用如下配置 <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> </settings> typeAliases,类型别名,类型别名是为 Java 类型设置的一个名字。 它只和 XML 配置有关。 <typeAliases> <typeAlias alias="Blog" type="domain.blog.Blog"/> </typeAliases> 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。 typeHandlers,类型处理器,无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。 在 org.apache.ibatis.type 包下有很多已经实现好的 TypeHandler,可以参考如下 你可以重写类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很方便的类 org.apache.ibatis.type.BaseTypeHandler, 然后可以选择性地将它映射到一个 JDBC 类型。 objectFactory,对象工厂,MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。 public class ExampleObjectFactory extends DefaultObjectFactory { public Object create(Class type) { return super.create(type); } public Object create(Class type, List constructorArgTypes, List constructorArgs) { return super.create(type, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { super.setProperties(properties); } public boolean isCollection(Class type) { return Collection.class.isAssignableFrom(type); } } 然后需要在 XML 中配置此对象工厂 <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory> plugins,插件开发,插件开发是 MyBatis 设计人员给开发人员留给自行开发的接口,MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。MyBatis 允许使用插件来拦截的方法调用包括:Executor、ParameterHandler、ResultSetHandler、StatementHandler 接口,这几个接口也是 MyBatis 中非常重要的接口,我们下面会详细介绍这几个接口。 environments,MyBatis 环境配置,MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。 这里注意一点,虽然 environments 可以指定多个环境,但是 SqlSessionFactory 只能有一个,为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties); databaseIdProvider ,数据库厂商标示,MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> </databaseIdProvider> mappers,映射器,这是告诉 MyBatis 去哪里找到这些 SQL 语句,mappers 映射配置有四种方式 上面的一个个属性都对应着一个解析方法,都是使用 XPath 把标签进行解析,解析完成后返回一个 DefaultSqlSessionFactory 对象,它是 SqlSessionFactory 的默认实现类。这就是 SqlSessionFactoryBuilder 的初始化流程,通过流程我们可以看到,初始化流程就是对一个个 /configuration 标签下子标签的解析过程。 SqlSession 在 MyBatis 初始化流程结束,也就是 SqlSessionFactoryBuilder -> SqlSessionFactory 的获取流程后,我们就可以通过 SqlSessionFactory 对象得到 SqlSession 然后执行 SQL 语句了。具体来看一下这个过程‘ 在 SqlSessionFactory.openSession 过程中我们可以看到,会调用到 DefaultSqlSessionFactory 中的 openSessionFromDataSource 方法,这个方法主要创建了两个与我们分析执行流程重要的对象,一个是 Executor 执行器对象,一个是 SqlSession 对象。执行器我们下面会说,现在来说一下 SqlSession 对象 SqlSession 对象是 MyBatis 中最重要的一个对象,这个接口能够让你执行命令,获取映射,管理事务。SqlSession 中定义了一系列模版方法,让你能够执行简单的 CRUD 操作,也可以通过 getMapper 获取 Mapper 层,执行自定义 SQL 语句,因为 SqlSession 在执行 SQL 语句之前是需要先开启一个会话,涉及到事务操作,所以还会有 commit、 rollback、close 等方法。这也是模版设计模式的一种应用。 MapperProxy MapperProxy 是 Mapper 映射 SQL 语句的关键对象,我们写的 Dao 层或者 Mapper 层都是通过 MapperProxy 来和对应的 SQL 语句进行绑定的。下面我们就来解释一下绑定过程 这就是 MyBatis 的核心绑定流程,我们可以看到 SqlSession 首先调用 getMapper 方法,我们刚才说到 SqlSession 是大哥级别的人物,只定义标准(有一句话是怎么说的来着,一流的企业做标准,二流的企业做品牌,三流的企业做产品)。 SqlSession 不愿意做的事情交给 Configuration 这个手下去做,但是 Configuration 也是有小弟的,它不愿意做的事情直接甩给小弟去做,这个小弟是谁呢?它就是 MapperRegistry,马上就到核心部分了。MapperRegistry 相当于项目经理,项目经理只从大面上把握项目进度,不需要知道手下的小弟是如何工作的,把任务完成了就好。最终真正干活的还是 MapperProxyFactory。看到这段代码 Proxy.newProxyInstance ,你是不是有一种恍然大悟的感觉,如果你没有的话,建议查阅一下动态代理的文章,这里推荐一篇 (https://www.jianshu.com/p/95970b089360) 也就是说,MyBatis 中 Mapper 和 SQL 语句的绑定正是通过动态代理来完成的。 通过动态代理,我们就可以方便的在 Dao 层或者 Mapper 层定义接口,实现自定义的增删改查操作了。那么具体的执行过程是怎么样呢?上面只是绑定过程,别着急,下面就来探讨一下 SQL 语句的执行过程。 MapperProxyFactory 会生成代理对象,这个对象就是 MapperProxy,最终会调用到 mapperMethod.execute 方法,execute 方法比较长,其实逻辑比较简单,就是判断是 插入、更新、删除 还是 查询 语句,其中如果是查询的话,还会判断返回值的类型,我们可以点进去看一下都是怎么设计的。 很多代码其实可以忽略,只看我标出来的重点就好了,我们可以看到,不管你前面经过多少道关卡处理,最终都逃不过 SqlSession 这个老大制定的标准。 我们以 selectList 为例,来看一下下面的执行过程。 这是 DefaultSqlSession 中 selectList 的代码,我们可以看到出现了 executor,这是什么呢?我们下面来解释。 Executor 还记得我们之前的流程中提到了 Executor(执行器) 这个概念吗?我们来回顾一下它第一次出现的位置。 由 Configuration 对象创建了一个 Executor 对象,这个 Executor 是干嘛的呢?下面我们就来认识一下 Executor 的继承结构 每一个 SqlSession 都会拥有一个 Executor 对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为 JDBC 中 Statement 的封装版。 也可以理解为 SQL 的执行引擎,要干活总得有一个发起人吧,可以把 Executor 理解为发起人的角色。 首先先从 Executor 的继承体系来认识一下 如上图所示,位于继承体系最顶层的是 Executor 执行器,它有两个实现类,分别是BaseExecutor和 CachingExecutor。 BaseExecutor 是一个抽象类,这种通过抽象的实现接口的方式是适配器设计模式之接口适配 的体现,是Executor 的默认实现,实现了大部分 Executor 接口定义的功能,降低了接口实现的难度。BaseExecutor 的子类有三个,分别是 SimpleExecutor、ReuseExecutor 和 BatchExecutor。 SimpleExecutor : 简单执行器,是 MyBatis 中默认使用的执行器,每执行一次 update 或 select,就开启一个Statement 对象,用完就直接关闭 Statement 对象(可以是 Statement 或者是 PreparedStatment 对象) ReuseExecutor : 可重用执行器,这里的重用指的是重复使用 Statement,它会在内部使用一个 Map 把创建的Statement 都缓存起来,每次执行 SQL 命令的时候,都会去判断是否存在基于该 SQL 的 Statement 对象,如果存在 Statement 对象并且对应的 connection 还没有关闭的情况下就继续使用之前的 Statement 对象,并将其缓存起来。因为每一个 SqlSession 都有一个新的 Executor 对象,所以我们缓存在 ReuseExecutor 上的 Statement作用域是同一个 SqlSession。 BatchExecutor : 批处理执行器,用于将多个 SQL 一次性输出到数据库 CachingExecutor: 缓存执行器,先从缓存中查询结果,如果存在就返回之前的结果;如果不存在,再委托给Executor delegate 去数据库中取,delegate 可以是上面任何一个执行器。 Executor 的创建和选择 我们上面提到 Executor 是由 Configuration 创建的,Configuration 会根据执行器的类型创建,如下 这一步就是执行器的创建过程,根据传入的 ExecutorType 类型来判断是哪种执行器,如果不指定 ExecutorType ,默认创建的是简单执行器。它的赋值可以通过两个地方进行赋值: 可以通过 标签来设置当前工程中所有的 SqlSession 对象使用默认的 Executor <settings> <!--取值范围 SIMPLE, REUSE, BATCH --> <setting name="defaultExecutorType" value="SIMPLE"/> </settings> 另外一种直接通过Java对方法赋值的方式 session = factory.openSession(ExecutorType.BATCH); Executor 的具体执行过程 Executor 中的大部分方法的调用链其实是差不多的,下面是深入源码分析执行过程,如果你没有时间或者暂时不想深入研究的话,给你下面的执行流程图作为参考。 我们紧跟着上面的 selectList 继续分析,它会调用到 executor.query 方法。 当有一个查询请求访问的时候,首先会经过 Executor 的实现类 CachingExecutor ,先从缓存中查询 SQL 是否是第一次执行,如果是第一次执行的话,那么就直接执行 SQL 语句,并创建缓存,如果第二次访问相同的 SQL 语句的话,那么就会直接从缓存中提取。 上面这段代码是从 selectList -> 从缓存中 query 的具体过程。可能你看到这里有些觉得类都是什么东西,我想鼓励你一下,把握重点,不用每段代码都看,从找到 SQL 的调用链路,其他代码想看的时候在看,看源码就是很容易发蒙,容易烦躁,但是切记一点,把握重点。 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler 上面代码会判断缓存中是否有这条 SQL 语句的执行结果,如果没有的话,就再重新创建 Executor 执行器执行 SQL 语句,注意, list = doQuery 是真正执行 SQL 语句的过程,这个过程中会创建我们上面提到的三种执行器,这里我们使用的是简单执行器。 到这里,执行器所做的工作就完事了,Executor 会把后续的工作交给 StatementHandler 继续执行。下面我们来认识一下 StatementHandler StatementHandler 的继承结构 有没有感觉和 Executor 的继承体系很相似呢?最顶级接口是四大组件对象,分别有两个实现类 BaseStatementHandler 和 RoutingStatementHandler,BaseStatementHandler 有三个实现类, 他们分别是 SimpleStatementHandler、PreparedStatementHandler 和 CallableStatementHandler。 RoutingStatementHandler : RoutingStatementHandler 并没有对 Statement 对象进行使用,只是根据StatementType 来创建一个代理,代理的就是对应Handler的三种实现类。在MyBatis工作时,使用的StatementHandler 接口对象实际上就是 RoutingStatementHandler 对象。 BaseStatementHandler : 是 StatementHandler 接口的另一个实现类,它本身是一个抽象类,用于简化StatementHandler 接口实现的难度,属于适配器设计模式体现,它主要有三个实现类 SimpleStatementHandler: 管理 Statement 对象并向数据库中推送不需要预编译的SQL语句。PreparedStatementHandler: 管理 Statement 对象并向数据中推送需要预编译的SQL语句。CallableStatementHandler:管理 Statement 对象并调用数据库中的存储过程。 StatementHandler 的创建和源码分析 我们继续来分析上面 query 的调用链路,StatementHandler 的创建过程如下 MyBatis 会根据 SQL 语句的类型进行对应 StatementHandler 的创建。我们以预处理 StatementHandler 为例来讲解一下 执行器不仅掌管着 StatementHandler 的创建,还掌管着创建 Statement 对象,设置参数等,在创建完 PreparedStatement 之后,我们需要对参数进行处理了。 如 如果用一副图来表示一下这个执行流程的话我想是这样 这里我们先暂停一下,来认识一下第三个核心组件 ParameterHandler ParameterHandler - ParameterHandler 介绍 ParameterHandler 相比于其他的组件就简单很多了,ParameterHandler 译为参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法 ParameterHandler 只有一个实现类 DefaultParameterHandler , 它实现了这两个方法。 getParameterObject: 用于读取参数setParameters: 用于对 PreparedStatement 的参数赋值ParameterHandler 的解析过程 上面我们讨论过了 ParameterHandler 的创建过程,下面我们继续上面 parameterSize 流程 这就是具体参数的解析过程了,下面我们来描述一下 下面用一个流程图表示一下 ParameterHandler 的解析过程,以简单执行器为例 我们在完成 ParameterHandler 对 SQL 参数的预处理后,回到 SimpleExecutor 中的 doQuery 方法 上面又引出来了一个重要的组件那就是 ResultSetHandler,下面我们来认识一下这个组件 ResultSetHandler - ResultSetHandler 简介 ResultSetHandler 也是一个非常简单的接口 ResultSetHandler 是一个接口,它只有一个默认的实现类,像是 ParameterHandler 一样,它的默认实现类是DefaultResultSetHandler ResultSetHandler 解析过程 MyBatis 只有一个默认的实现类就是 DefaultResultSetHandler,DefaultResultSetHandler 主要负责处理两件事 处理 Statement 执行后产生的结果集,生成结果列表 处理存储过程执行后的输出参数 按照 Mapper 文件中配置的 ResultType 或 ResultMap 来封装成对应的对象,最后将封装的对象返回即可。 其中涉及的主要对象有: ResultSetWrapper : 结果集的包装器,主要针对结果集进行的一层包装,它的主要属性有 ResultSet : Java JDBC ResultSet 接口表示数据库查询的结果。 有关查询的文本显示了如何将查询结果作为java.sql.ResultSet 返回。 然后迭代此ResultSet以检查结果。 TypeHandlerRegistry: 类型注册器,TypeHandlerRegistry 在初始化的时候会把所有的 Java类型和类型转换器进行注册。 ColumnNames: 字段的名称,也就是查询操作需要返回的字段名称 ClassNames: 字段的类型名称,也就是 ColumnNames 每个字段名称的类型 JdbcTypes: JDBC 的类型,也就是 java.sql.Types 类型 ResultMap: 负责处理更复杂的映射关系 在 DefaultResultSetHandler 中处理完结果映射,并把上述结构返回给调用的客户端,从而执行完成一条完整的SQL语句。 内容转载自:CSDN博主:cxuann 原文链接:https://blog.csdn.net/qq_36894974/article/details/104132876?depth_1-utm_source=distribute.pc_feed.none-task&request_id=&utm_source=distribute.pc_feed.none-task

问问小秘 2020-03-05 15:44:27 0 浏览量 回答数 0

回答

iperf,具体要纤细直接去看文档, 简单给你列条测试:(TCP和UDP知只是两种传输数据的协议) 1)TCP测试    服务器执行:./iperf -s -i 1 -w 1M '这裏是指定windows如果是 iperf -s则windwos默认大小为8kbyte/s    客户端执行:./iperf -c host -i 1 -w 1M   其中-w表示TCP window size,host需替换成服务器地址。    2)UDP测试    服务器执行:./iperf -u -s    客户端执行:./iperf -u -c 10.255.255.251 -b 900M -i 1 -w 1M -t 60   其中-b表示使用多少带宽,1G的线路你可以使用900M进行测试。 不给分不给力 连接速度是个很怪的概念。我们通常用连接带宽和网络延迟来表达网络连接的状态。 带宽可以用一端建立FTP服务器,另一端下载来测试。网络延时可以用PING命令来测试。 希望能帮到你。 行的。 家庭或小型办公室,如果有两台或更多的计算机,很自然地希望将他们组成一个网络。为方便叙述,以下约定将其称为局域网。在家庭环境下,可用这个网络来共享资源、玩那些需要多人参与的游戏、共用一个调制解调器享用Internet连接等等。办公室中,利用这样的网络,主要解决共享外设如打印机等,此外,办公室局域网也是多人协作工作的基础设施。 别看这样小的网络工程,在过去也是需要专业人员来进行组网配置的。那时,大部分操作的都是手工的,一般的用户都不具备相应的知识和经验。正好属于"高不成低不就"的情况,自然限制了它的发展。Windows XP的出现,打破了这种局面,这依赖它内建有强大的网络支持功能和方便的向导。用户完成物理连接后,运行连接向导,可以自己探测出网络硬件、安装相应的驱动程序或协议,并指导用户,完成所有的配置步骤。 本文介绍两种在Windows XP操作系统下的组网方案,并介绍Windows XP用于局域网中的各种很有特色的功能。 一. 目标: 组成家庭局域网:对外,可以连接Internet,允许局域网内的各个计算机共享连接。对内,可以共享网络资源和设备。 二. 采用什么网络形式? 家庭网中的计算机可能有桌面机或便携机,例如掌上电脑或笔记本机等,也可能出现各种传输介质的接口,所以网络形式上,不宜都采用有线网络,无线接口是必须考虑的。但如果可以明确定位在纯粹的有线网上,也可不设无线接口。所以,这里提供两种方案: 1. 有线与无线混合。 2. 有线。 三. 网络硬件选择 网络适配器(网卡)可采用PCI、PC或PCMCIA接口的卡(后两者多用在便携式机或笔记本机上),Windows XP也支持用USB接口的网络适配器。究竟采用那种适配器,取决于接入网络中的计算机。无论那种适配器,都需要注意与现有计算机的接口以及HUB的协调一致,USB接口的适配器可能适应性更强一些,但对于较旧的计算机,又需要注意它是否支持USB接口。 网络连接线,常用的有同轴电缆和双绞线,这都是大家熟悉的东西,不多解释。究竟采用哪一种,就看你怎么想了。 四. 可采用的网络结构和介质 以太结构:这种结构在办公室或商业用户中最为流行,熟悉的人也很多,技术资料和维护人员也容易找到,所以不多赘述。 电话线连接:这种形式主要的特色是成本很低,物理连接也很简单,适用于大部分的家庭用户。 无线电波:利用电磁波信号来传输信号,可以不用任何连线来进行通讯,并可以在移动中使用。但需要在每台计算机上加装无线适配器,成本高是肯定了。在我国,无线形式用在计算机网络通讯的还较少。在美国,用于无线网络的是一个称为IEEE 802.11b的标准协议,用于计算机近距离网络通讯。在该协议支持下,可达到的网速是11 Mbps。 五. 方案之一 这是一个有线、无线混合方案,具体结构可以参看图1。这个例子中,用4台计算机组成了一个混合网络,PC1是主机,它与外部连接有3个通路: 1. 与Internet接连的调制解调器:用于整个网络的各个计算机共享上网之用。 2. 无线适配器:用于和本网络内的无线设备之间的通讯。 3. HUB:用于"带动"本网络内的下游计算机。 该方案中的PC1、PC2机,必须用Windows XP操作系统,有线部分采用的是以太网结构连接。图中的HPNA是home phoneline network adaptor的缩写,表示家庭电话线网络适配器。图中的PC3和移动计算机,并不要求非使用Windows XP操作系统不可,别的windows版本也行。移动计算机和主机之间的网络连接利用的是无线形式。 如果希望建立混合网络,这种方案已经具备典型的功能,并且不需要花费很大就可以扩充网络规模。 关于连通操作: 图1显示的结构只能表示物理连接关系,物理连接完成后,还需要进行连通操作,网络才可真正投入使用。连通操作包括局域网内部各个计算机之间的连通,和局域网与Internet之间的连通。前者连通建立的步骤如下: 1. 鼠标点击 开始,进入控制面板,点击"Network and Internet Connections网络和Internet连接",选择网络连接( Network Connections),进行下一步。 2. 选择进行"两个或多个LAN的连接" 3. 右键点击一个连接. 4. 确定完成连接任务. 局域网之内的连通操作就完成了。 再说局域网与Internet之间的连通,这种情况主要考虑速度与成本两方面的兼顾。多机上网,最省事的办法是每个机器占据一条独立的电话线,但这不是一般用户能承受起的,资源的浪费也太大。另一个办法,可以使用住宅网关,但这样成本需要增加,不是最佳途径。比较好的方法是使用一个计算机作为主机服务器。这不仅技术上可行,还有很多别的优点,如: ①:由于Windows XP有内建的防火墙,主机介于Internet和终端机之间,可以利用主机的防火墙保护局域网中的分机免受来自Internet的攻击。 ②:主机是"隐匿在" Internet和局域网之间的,充当了网关的脚色,在分机上,用户感觉好像自己是直接连在Interne上一样,察觉不到中间还有主机存在。特别是可以使局域网中的每台计算机同时上网。大大减少了设备投资。 ③:除主机必须使用Windows XP操作系统之外,局域网内的计算机可使用早期的windows版本。 ④:如果局域网中需要使用不同的媒体(例如有线和无线混合),可以利用Windows XP作为过渡的网桥。 ⑤:虽然有网络资源和设备的共享功能,但也可以限制别人对私有文件和数据的访问,特别是将文件存放在主机上的时候,更具有这种优势可用。 ⑥:利用"万能即插即用"功能,可以随时扩充局域网的规模。 六. 方案之二 下面是这种方案的结构示意图。该方案适用于小型办公室。与上一个方案比较,主要是去掉了无线部分,主机与分机之间不采用电话线连接,而是采用了电缆或双绞线连接。所有分机都通过一个HUB与主机连接到Internet上,并可以支持打印机共享。这其实就是最常见的那种局域网的结构。 该方案完成物理连接之后,还需要进行下列操作: 1. 打开网络连接文件夹或找到网络连接的图标. 2. 右键点击"connection to the Internet you want to share(共享Internet连接)"然后再右键点击"Properties(属性)" 3. 选择"Advanced(高级)"任务条。 4. 选择"Allow other networkusers to connect through this computer′s Internet connection(允许另外用户通过这个计算机连接到Internet)"检查框,并选定。 5. 点击 OK.结束操作。 启用Windows XP的防火墙,必须进行设置,不设置是不起作用的。设置过程: 1.打开网络连接文件夹或找到网络连接的图标. 2.右键点击"connection to the Internet you want to share(共享Internet连接)"然后再右键点击"Properties(属性)" 3.选择"Advanced(高级)"任务条。 4. 选择"Protect my computer and network by limitingor preventing access to this computer from the Internet(利用这个计算机限制从Internet进入的访问并保护我的计算机和网络" ,在其下面有一个Internet连接防火墙的检查框,鼠标点击选定。 5. 点击 OK.结束操作。 七. 几点说明 A.主机必须采用Windows XP操作系统,局域网内的计算机可以使用早一些的windows版本,如:windows98、windows ME、windows2000等等。 B.这里提供的是典型的情况,想扩充网络规模基本上可以照此叠加。 C.本文是依据英文测试版本进行的试验,不能保证将来的正式版本。特别是中文正式版本的性能与此完全一致。 参考资料: 创建局域网及配置管理 一.概念: (一).局域网的概念: 局域网做为网络的组成部分,发挥了不可忽视的作用。我们可以用Windows 9X把众多的计算机联系在一起,组成一个局域网,在这个局域网中,我们可以在它们之间共享程序、文档等各种资源,而不必再来回传递软盘;还可以通过网络使多台计算机共享同一硬件,如打印机、调制解调器等;同时我们也可以通过网络使用计算机发送和接收传真,方便快捷而且经济。 局域网是一个范围可大可小、简单的只有2台运行着Windows95的计算机连网(以工作组方式工作),也可以是幅员辽阔的高速ATM网和以太网混合使用、运行多种平台的大型企业。 (二).网络的类型: 1、按网络的地理位置分类 a.局域网(LAN):一般限定在较小的区域内,小于10km的范围,通常采用有线的方式连接起来 b.城域网(MAN):规模局限在一座城市的范围内,10~100km的区域。 c.广域网(WAN):网络跨越国界、洲界,甚至全球范围。 目前局域网和广域网是网络的热点。局域网是组成其他两种类型网络的基础,城域网一般都加入了广域网。广域网的典型代表是Internet网。 (二).硬件指南:网络硬件设备 组成小型局域网的主要硬件设备有网卡、集线器等网络传输介质和中继器、网桥、路由器、网关等网络互连设备。以下主要介绍网卡、集线器等网络传输介质和中继器、网桥、路由器、网关等局域网互连设备。 1.网卡 网卡(Network Interface Card,NIC)也叫网络适配器,是连接计算机与网络的硬件设备。网卡插在计算机或服务器扩展槽中,通过网络线(如双绞线、同轴电缆或光纤)与网络交换数据、共享资源。 Realtek 10/100M,这是我们实例中所使用的网卡 二.组网: 返回顶部 (一).硬件配置:服务器:普通PC机,主板:intel 815,硬盘:迈拓40G,CPU:PIII933,内存:512M ,显示器:ACER。 其他:双绞线一箱(300m),16口HUB一个,RJ45头32个,网卡:Realtek 10/100M 16块。。 由于服务器需要安装两块网卡来用SyGate维护管理,两个网卡的设置请参阅如下的动画。 三.网络维护: 返回顶部 SyGate 4.0是一种支持多用户访问因特网的软件,并且是只通过一台计算机,共享因特网帐号,达到上网的目的。使用SyGate 4.0,若干个用户能同时通过一个小型网络(包括您的笔记本电脑),迅速、快捷、经济地访问因特网。SyGate 4.0能在目前诸多流行的操作系统上运行,譬如:Windows95、Windows98、Windows NT, Windows2000等操作系统;同时,SyGate 4.0还支持多数的因特网连接方式,这包括:调制解调器(模拟线路)拨入、ISDN(综合业务数字网)、线缆调制解调器(Cable Modem)、ADSL以及DirectPC等方式。 SyGate 4.0具有以下优势: 易于安装 SyGate在数分钟之内便可以安装完成,并且通常不需要其他外加的设置。和其他代理服务器软件(proxy server)不同的是,SyGate仅安装Server便可以了。 易于使用 SyGate拥有直观的图形化界面,懂得操作Windows的人员均会操作。SyGate启动后便在后台运行,不需要人工的干预。当SyGate检测到局域网内有上网 要求时,它能自动地连接到因特网上,免去了每次需要手工拨号的烦恼。用户可以不间断地、透明地浏览因特网、收发电子邮件、聊天、使用FTP以及操作其他的小程序等等。局域网内非Windows用户,如Macintosh、Solaris和Linux,均能通过TCP/IP协议上网。 四.Windows 对等网创建与维护 返回顶部 (一).建网软件要求 在一个局域网中,Windows 95、98、NT和2000等操作系统可以并存。当然,即使你的电脑是在DOS下面跑的,也可以实现联网。由于Windows操作系统才是广泛应用的系统,本文不准备讨论DOS联网。 建网硬件要求 要组建电脑网络,无疑需要能将电脑连在一起的硬件设备。最简单的办法是,使用特制的电缆,将两台电脑的并口或者串口联接起来,通过Windows的“直接电缆连接”实现联网。这种联接电缆可以自制,也可以到电脑城购买。其缺点是,只能联接两台电脑,联网距离较短、方式古板,实际应用很不方便,通常要求将一台电脑用作服务器,另外一台用作客户端来实现联网。 但更为普遍采用的是网卡加网线的联网方式。从插槽上分,网卡有ISA和PCI两种;从速度上分,网卡又有10MB和100MB甚至传输速度更高的网卡。要求不高的话,一块PCI 10MB网卡就够用了。 五.疑难解答 返回顶部 (一).网卡安装故障检查方法 如果无法安装网卡驱动程序或安装网卡后无法登录网络,请按下述步骤检查处理: 1.选择“控制面板”/“系统”图标,打开“系统属性”窗口; 2.在“系统属性”窗口的“设备管理”标签的“按类型查看设备列表”中,双击“网络适配器”条目前的“ ”号将其展开,其下应当列出当前网卡; 3.如果“设备管理”标签中没有“网络适配器”条目或当前网卡前有一“X”号,说明系统没能识别网卡,可能产生的原因有网卡驱动程序安装不当、网卡硬件安装不当、网卡硬件故障等等; 参考 LAN(局域网)一词指位于同一区域甚至同一建筑物内的中小型计算机网络,字典上的解释是:将计算机和字处理机等电子办公设备连接在一起构成的办公室或建筑物内的网络系统。相信大多数人都在学校里、当地图书馆或朋友家里。接触过局域网。 随着宽带互联网日益流行,许多人家里都有几台计算机,家庭局域网正在形成规范。通过局域网共享宽带互联网访问可降低成本,不需要每台计算机都连接调制解调器和单独的IP地址。但如何构建一个家庭局域网共享宽带互联网访问呢? 网络带宽表示 网络带宽以兆位秒Mbps测量,通常不用兆字节秒MBps表示。一个字节有八个二进制位组成,多数人都熟悉MBps。当前局域网多为10base-T(10Mbps或1.25MBps)和100base-TX(100Mbps或12.5MBps)的以太网,使用类似标准电话线的RJ-45接口,通过网络电缆把集线器(或路由器、交换器)和计算机连接起来就构成了以太网。 网络布线 开始组建家庭局域网之前,应多少了解一些可用网络电缆的区别。这取决你家中PC机需要安排的位置,因为可能需要在墙上打眼,以穿过五类网络电缆。对家里地方不宽敞的人,这可能是令人畏缩的任务,甚至不太可能。如果你想避免穿墙打眼的麻烦,无线局域网也很方便,但应注意,无线局域网通常速度不够快,花费也高的多。另一种选择可考虑10Mbps电话线套件,利用你现成的电话线在计算机之间传送数据,可购买D-Link,Linksys,3Com和Netgear等公司的产品。不想采用无线局域网的人,可选择五类双绞线网络电缆。如果对电缆不熟悉,下面列出了电子工业协会EIA关于电缆分类的解释。根据电缆的速度和质量,可将电缆分为六类: 一、二类电缆:数据传输速度低于10Mbps(普通电话线) 三类电缆:数据传输速度达16 Mbps 四类电缆:数据传输速度达20 Mbps 五类电缆:数据传输速度达100 Mbps 五类电缆增强:数据传输速度达200 Mbps 六类电缆:数据传输速度达600 Mbps 五类电缆十分普通,连接以太网费用也较低。如果你计划穿墙打眼或使用超过50英尺五类电缆,应购买细电缆,自己动手将RJ-45插头接在电缆两端。注意,别忘了电缆穿过墙之后再接RI-45插头。 连接RJ-45插头 五类电缆连接RJ-45插头并不困难,但需要专用连接工具,可从当地五金商店买一把或从朋友处借用。操作时小心剪掉约1/4英寸电缆外塑料皮,露出电缆里面8根彩色线,注意放入RJ-45连接器里面电缆线的次序: 1、白绿 2、绿 3、白橙 4、兰 5、白兰 6、橙 7、白橙 8、棕 应仔细展开8条彩色编码线,放入RJ-45插孔中,用专用工具压紧。有条件时可用RJ-45测试器验证一下是否连接可靠,以免将来麻烦。 需要的硬件 首先确保每台计算机里都安装了网卡,100base-TX或10base-T网卡,型号、尺寸任意。注意,一般选PCI网卡,各网卡速率应一致。100base-TX网卡数据传输率较高,适合于大量数据传输,如数字电影或其它大的多媒体文件。 组建局域网需要使用集线器,交换器或内置集线器的路由器,集线器只不过用于将你所有的计算机连到局域网上。如果你只有2台计算机并且不打算增加数量,可以用一段电缆直接将2台计算机连起来,缺点是你试图共享宽带互联网访问仍然有麻烦。如果你想多台计算机访问宽带互联网,使用路由器是个好主意,可以选购Netgaer,D-Link和Linksys等著名网络公司的产品。 典型的以太网使用集线器或交换器,两种设备都有单独的连接器,用于将每台计算机连接到局域网上。集线器与交换器的主要差别在于吞吐量,集线器在所有在用的端口间分配吞吐量,因此4端口100base-TX集线器每个在用的端口只有25Mbps吞吐量。交换器更贵些,但允许每个端口全速运行。 假如你准备设置一个只有单个宽带互联网连接的局域网,应确保你的DSL或有线电缆供应商给你提供的是外置调制解调器。多数外置调制解调器通过网卡连接到你的计算机,你可把具有调制解调器的那台计算机设置为路由器,虽然这并不推荐。作为一个例子,你将电话插头接入宽带调制解调器,然后经RJ-45(双绞线)电缆连至集线器/交换器/路由器,从此,你的任一台计算机都可连接到互联网上。 设置Windows网络 确保你准备在局域网上使用的每台计算机,都有足够的五类电缆已连到了集线器或路由器。现在你可能已安装了适当的网卡以及相应的驱动程序,右击“网络邻居”,选择“属性”,可以看到当前已经安装的协议和网卡。要设置网络,应确保所用的网卡已安装了TCP/IP协议。如果你使用的微软操作系统是Windows98或更高版本,网络设置相当简单,Windows网络作为操作系统的基本选项之一应该已经安装了。如果你至少在一台计算机上使用的是Windows Me,你可运行家庭网络向导,将一步步引导你完成设置。记住,你需要使用相同的组名设置你网络中的每台计算机。在Windows95/98中,需要进入网络属性,并确保所有设置为缺省。你的互联网服务供应商ISP可能已经告诉你,如何设置TCP/IP,怎样连接到互联网。你可能是静态IP地址,或是动态IP地址,取决于你的ISP。静态IP地址设置需要的时间稍长一点,如果你想给互联网用户提供服务,如FTP,Web服务器或任何其它服务,静态IP地址是不错的。如果你分配的是IP地址,你的TCP/IP协议属性获得的应是自动选择的IP地址。要检查你的计算机是否已被集线器/路由器分配了一个IP地址,可使用Windows TP配置(进入开始 传输大点的东西,用iostat 1 查看io 来源于网络,供您参考

保持可爱mmm 2019-12-02 02:20:25 0 浏览量 回答数 0

中小企业与商标那些事

企业品牌保护从商标开始,如何挑选一家靠谱的渠道注册商标,解读品牌权益维护的重要节点。
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 SQL审核 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 人工智能 阿里云云栖号 云栖号案例 云栖号直播