• mybatis源码学习(一)


    1、 mybatis:java持久层框架,通过XML配置的方式消除了绝大部分JDBC重复代码以及参数的设置,结果集的映射。

      学习框架不仅要细致完整的熟悉框架提供的每个特性,还要理解框架的初始化过程,不能泛泛的快速浏览那个功能是通过哪个类或接口实现和封装的,对于核心特性和初始化过程的实现,我们要做到:

        对于核心特性和内部功能,具体如何实现,采用的数据结构,是否合理,在上下文发挥的作用,采用了哪些设计模式,设计模式是否合理,哪部分可以扩展,如果按照要求进行扩展以满足自己的需求。

    2、#{}中可以放什么内容?

      1)参数对象的属性

      2)随意内容,此时的#{}是个占位符

      3)参数为map时的key

      4)参数为map时,若key所对应的value为对象,则可将该对象的属性放入

      5)参数的索引号

    3、作用域和生命周期

      SqlSessionFactoryBuilder一旦创建了SqlSessionFactory对象,就不再需要了,因此,SqlSessionFactoryBuilder最佳作用域是方法作用域,不要让其一直存在,以保证xml解析资源可以被释放给更重要的事情。

      SqlSessionFactory最佳作用域是应用作用域,使用单例模式或静态单例模式。

      SqlSession,每个线程都应该有它自己的SqlSession实例,SqlSession对象不是线程安全的,因此不能被共享,所以它的最佳的作用域是请求或方法作用域。绝对不能将SqlSession的实例放在一个类的静态域,甚至一个类的实例变量也不行,也绝对不能将SqlSession实例的引用放在任何类型的托管域中,比如servlet框架的HttpSession。在web框架中,要考虑sqlSession放在一个和http请求对象相似的作用域中,换句话说,每次收到的http请求,就可以打开一个sqlSession,返回一个响应就关闭它

    try (SqlSession session = sqlSessionFactory.openSession()) {
      // 你的应用逻辑代码
    }

       映射器是一些由你创建的、绑定你映射的语句的接口。映射器接口的实例是从 SqlSession 中获得的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。

     4、摘录configuration部分代码

    public class Configuration {
    
      protected Environment environment;
      // 允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false。默认为false
      protected boolean safeRowBoundsEnabled;
      // 允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为false。
      protected boolean safeResultHandlerEnabled = true;
      // 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。默认false
      protected boolean mapUnderscoreToCamelCase;
      // 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。默认值false (true in ≤3.4.1)
      protected boolean aggressiveLazyLoading;
      // 是否允许单一语句返回多结果集(需要兼容驱动)。
      protected boolean multipleResultSetsEnabled = true;
    
      // 允许 JDBC 支持自动生成主键,需要驱动兼容。这就是insert时获取mysql自增主键/oracle sequence的开关。注:一般来说,这是希望的结果,应该默认值为true比较合适。
      protected boolean useGeneratedKeys;
    
      // 使用列标签代替列名,一般来说,这是希望的结果
      protected boolean useColumnLabel = true;
    
      // 是否启用缓存
      protected boolean cacheEnabled = true;
    
      // 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。
      protected boolean callSettersOnNulls;
    
      // 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始)
      protected boolean useActualParamName = true;
    
      //当返回行的所有列都是空时,MyBatis默认返回null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (i.e. collectioin and association)。(从3.4.2开始) 注:这里应该拆分为两个参数比较合适, 一个用于结果集,一个用于单记录。通常来说,我们会希望结果集不是null,单记录仍然是null
      protected boolean returnInstanceForEmptyRow;
    
      // 指定 MyBatis 增加到日志名称的前缀。
      protected String logPrefix;
    
      // 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。一般建议指定为slf4j或log4j
      protected Class <? extends Log> logImpl;
    
      // 指定VFS的实现, VFS是mybatis提供的用于访问AS内资源的一个简便接口
      protected Class <? extends VFS> vfsImpl;
    
      // MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。
      protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
    
      // 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。
      protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
    
      // 指定对象的哪个方法触发一次延迟加载。
      protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));
    
      // 设置超时时间,它决定驱动等待数据库响应的秒数。默认不超时
      protected Integer defaultStatementTimeout;
    
      // 为驱动的结果集设置默认获取数量。
      protected Integer defaultFetchSize;
    
      // SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。
      protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
    
      // 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。
      protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
    
      // 指定发现自动映射目标未知列(或者未知属性类型)的行为。这个值应该设置为WARNING比较合适
      protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
    
      // settings下的properties属性
      protected Properties variables = new Properties();
    
      // 默认的反射器工厂,用于操作属性、构造器方便
      protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
    
      // 对象工厂, 所有的类resultMap类都需要依赖于对象工厂来实例化
      protected ObjectFactory objectFactory = new DefaultObjectFactory();
    
      // 对象包装器工厂,主要用来在创建非原生对象,比如增加了某些监控或者特殊属性的代理类
      protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
    
      // 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。
      protected boolean lazyLoadingEnabled = false;
    
      // 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。MyBatis 3.3+使用JAVASSIST
      protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL
    
      // MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。
      protected String databaseId;
    
      /**
       * Configuration factory class.
       * Used to create Configuration for loading deserialized unread properties.
       * 指定一个提供Configuration实例的类. 这个被返回的Configuration实例是用来加载被反序列化对象的懒加载属性值. 这个类必须包含一个签名方法static Configuration getConfiguration(). (从 3.2.3 版本开始)
       */
      protected Class<?> configurationFactory;
    
      protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
    
      // mybatis插件列表
      protected final InterceptorChain interceptorChain = new InterceptorChain();
      protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
    
      // 类型注册器, 用于在执行sql语句的出入参映射以及mybatis-config文件里的各种配置比如<transactionManager type="JDBC"/><dataSource type="POOLED">时使用简写, 后面会详细解释
      protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
      protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
    
      protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
      protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
      protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
      protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>("Parameter Maps collection");
      protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<KeyGenerator>("Key Generators collection");
    
      protected final Set<String> loadedResources = new HashSet<String>();
      protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>("XML fragments parsed from previous mappers");
    
      protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
      protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
      protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
      protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();
    
      /*
       * A map holds cache-ref relationship. The key is the namespace that
       * references a cache bound to another namespace and the value is the
       * namespace which the actual cache is bound to.
       */
      protected final Map<String, String> cacheRefMap = new HashMap<String, String>();
    
      public Configuration(Environment environment) {
        this();
        this.environment = environment;
      }
    
      public Configuration() {
        // 内置别名注册
        typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
        typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
    
        typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
        typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
        typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
    
        typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
        typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
        typeAliasRegistry.registerAlias("LRU", LruCache.class);
        typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
        typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
    
        typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
    
        typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
        typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
    
        typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
        typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
        typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
        typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
        typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
        typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
        typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
    
        typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
        typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
    
        languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
        languageRegistry.register(RawLanguageDriver.class);
      }
    //......
    }
    configuration
  • 相关阅读:
    python2.7下同步华为云照片的爬虫程序实现
    python 下字符串格式时间比较
    C# Socket通信 小案例
    win 10 安装 mysql解压版 步骤
    Android 连接 SQL Server (jtds方式)——下
    Android 连接 SQL Server (jtds方式)——上
    Android 项目建立步骤
    ubuntu 配置android开发环境
    ubuntu 安装eclipse
    ubuntu 配置Java jdk
  • 原文地址:https://www.cnblogs.com/yaohuiqin/p/11864816.html
Copyright © 2020-2023  润新知