/**
* 【mybatis】
* what?
* ORM框架 (将Java 对象 与 数据库字段 进行映射);
*
* How?
* a, 导入 jdbc 驱动包
* b, 导入 mybatis 包
* c, 开发即可
*
* 【org.apache.ibatis.session.SqlSessionFactory】
* 每个基于 MyBatis应用 都是以一个SqlSessionFactory实例为核心;
* SqlSessionFactory实例 可以通过SqlSessionFactoryBuilder获得;
*
* SqlSessionFactory 有六个方法创建 SqlSession 实例。通常来说,当你选择其中一个方法时,你需要考虑以下几点:
* 1、事务处理:你希望在 session 作用域中使用事务作用域,还是使用自动提交(auto-commit)?(对很多数据库和/或 JDBC 驱动来说,等同于关闭事务支持)
* 2、数据库连接:你希望 MyBatis 帮你从已配置的数据源获取连接,还是使用自己提供的连接?
* 3、语句执行:你希望 MyBatis 复用 PreparedStatement 和/或批量更新语句(包括插入语句和删除语句)吗?
*
* // Creates an {@link SqlSession} out of a connection or a DataSource
* public interface SqlSessionFactory {
*
* SqlSession openSession();
* 1、事务作用域将会开启(也就是不自动提交)。
* 2、将由当前环境配置的 DataSource 实例中获取 Connection 对象。
* 3、事务隔离级别将会使用驱动或数据源的默认设置。
* 4、预处理语句不会被复用,也不会批量处理更新。
*
* SqlSession openSession(boolean autoCommit);
* 向 autoCommit 可选参数传递 true 值即可开启自动提交功能;
*
* SqlSession openSession(Connection connection);
* 若要使用自己的 Connection 实例,传递一个 Connection 实例给 connection 参数即可
* ***
* 没有提供同时设置 Connection 和 autoCommit 的方法,这是因为 MyBatis 会依据传入的 Connection 来决定是否启用 autoCommit;
* (JDBC 通过 Connection 管理事务)
*
* SqlSession openSession(TransactionIsolationLevel level);
* MyBatis 使用了一个枚举TransactionIsolationLevel,事务隔离级别支持 JDBC 的五个隔离级别(NONE、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ 和 SERIALIZABLE);
* org.apache.ibatis.session.TransactionIsolationLevel{
* NONE(Connection.TRANSACTION_NONE), int TRANSACTION_NONE = 0;
* READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED), int TRANSACTION_READ_COMMITTED = 2;
* READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED), int TRANSACTION_READ_UNCOMMITTED = 1;
* REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ), int TRANSACTION_REPEATABLE_READ = 4;
* SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE); int TRANSACTION_SERIALIZABLE = 8;
* }
*
* SqlSession openSession(ExecutorType execType);
* org.apache.ibatis.session.ExecutorType{
* SIMPLE,
* 该类型的执行器没有特别的行为。它为每个语句的执行创建一个新的预处理语句。
* REUSE,
* 该类型的执行器会复用预处理语句。
* BATCH
* 该类型的执行器会批量执行所有更新语句,如果 SELECT 在多个更新中间执行,将在必要时将多条更新语句分隔开来,以方便理解。
* }
*
* SqlSession openSession(ExecutorType execType, boolean autoCommit);
*
* SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
*
* SqlSession openSession(ExecutorType execType, Connection connection);
*
* Configuration getConfiguration();
* }
*
*
* 【org.apache.ibatis.session.SqlSessionFactoryBuilder】
* SqlSessionFactoryBuilder 可以 从XML配置文件 或 一个预先配置的Configuration实例 来构建出 SqlSessionFactory实例;
*
* // Builds {@link SqlSession} instances.
* public class SqlSessionFactoryBuilder {
*
* public SqlSessionFactory build(Configuration config){}
*
* // 从 XML文件中构建 SqlSessionFactory实例非常简单,建议使用类路径下的资源文件进行配置;
* // 也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流;
* public SqlSessionFactory build(InputStream inputStream){}
* }
*
*
* 【org.apache.ibatis.io.Resources】
* A class to simplify access to resources through the classloader.
* Resources 简化 通过classloader 访问resources;
*
*
* ****事务***
*
* 【org.apache.ibatis.transaction.TransactionFactory】
*
* 在 MyBatis 中有两种类型的事务管理器(也就是 type="[JDBC|MANAGED]")
* JDBC – 直接使用了 JDBC的提交和回滚 ,它 依赖从DataSource获得的Connection 来管理事务作用域。
* MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
*
* Creates {@link Transaction} instances.
*
* {
* void setProperties(Properties props);
* Transaction newTransaction(Connection conn);
* Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
* }
*
*
* org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory implements TransactionFactory
* Creates {@link JdbcTransaction} instances.
*
*
* org.apache.ibatis.transaction.managed.ManagedTransactionFactory implements TransactionFactory
* Creates {@link ManagedTransaction} instances.
*
*
* 【org.apache.ibatis.transaction.Transaction】
* Wraps a database connection.
* Handles the connection lifecycle that comprises: its creation, preparation, commit/rollback and close.
* 包装了 一个 数据库 connection;
* 处理 connection 的生命周期;
*
* {
* Connection getConnection() throws SQLException;
* void commit() throws SQLException;
* void rollback() throws SQLException;
* void close() throws SQLException;
* }
*
* org.apache.ibatis.transaction.jdbc.JdbcTransaction implements Transaction
* {@link Transaction} that makes use of the JDBC commit and rollback facilities directly.
* It relies on the connection retrieved from the dataSource to manage the scope of the transaction.
* JdbcTransaction 使用了 JDBC的提交和回滚;
* JdbcTransaction 依赖从DataSource获得的Connection 来管理事务作用域
*
* {
* protected Connection connection;
* protected DataSource dataSource;
* protected TransactionIsolationLevel level;
* protected boolean autoCommit;
*
*
* public void commit() throws SQLException {
* connection.commit();
* }
*
* public void rollback() throws SQLException{
* connection.rollback();
* }
* }
*
* org.apache.ibatis.transaction.managed.ManagedTransaction implements Transaction
*
*
* ***数据源***
* dataSource
* 使用 标准的JDBC数据源接口(javax.sql.DataSource) 来配置 JDBC 连接对象(java.sql.Connection)的资源。
*
* 有三种内建的数据源类型(也就是 type="[UNPOOLED|POOLED|JNDI]"):
* UNPOOLED:
* 每次请求时打开和关闭连接;
* 虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择;
* 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形;
*
* POOLED:
* 利用“池”的概念将 JDBC Connection实例 组织起来,避免了创建新的Connection实例时所必需的初始化和认证时间;
* 这种处理方式很流行,能使并发 Web应用快速响应请求。
*
* JNDI:
* 为了能在如 EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。
*
*
* ***映射器***
* 一些 绑定映射语句的 接口;
* How?(MyBatis 到哪里去找到这些语句)
* 1、使用相对于类路径的资源引用
* <mappers>
* <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
* </mappers>
*
* 2、使用完全限定资源定位符(URL)
* <mappers>
* <mapper url="file:///var/mappers/AuthorMapper.xml"/>
* </mappers>
*
* 3、使用映射器接口实现类的完全限定类名
* <mappers>
* <mapper class="org.mybatis.builder.AuthorMapper"/>
* </mappers>
*
* 4、将包内的映射器接口实现全部注册为映射器
* <mappers>
* <package name="org.mybatis.builder"/>
* </mappers>
*
*
* ***插件***
* MyBatis 允许你在 映射语句执行过程中的某一点 进行拦截调用。
* Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
* ParameterHandler (getParameterObject, setParameters)
* ResultSetHandler (handleResultSets, handleOutputParameters)
* StatementHandler (prepare, parameterize, batch, update, query)
*
*/
/**
* 【mybatis-结果集映射】
* 【org.apache.ibatis.mapping.ResultMap】
* ResultMap 是 MyBatis 中最重要最强大的元素;
* ResultMap 的设计思想是:
* 对简单的语句做到零配置;
* 对于复杂一点的语句,只需要描述语句之间的关系就行了;
*
* org.apache.ibatis.mapping.ResultMap{
* private Configuration configuration;
*
* private String id;
* private Class<?> type;
* private List<ResultMapping> resultMappings;
* private List<ResultMapping> idResultMappings;
* private List<ResultMapping> constructorResultMappings;
* private List<ResultMapping> propertyResultMappings;
* private Set<String> mappedColumns;
* private Set<String> mappedProperties;
* private Discriminator discriminator;
* private boolean hasNestedResultMaps;
* private boolean hasNestedQueries;
* private Boolean autoMapping;
* }
*
* 【org.apache.ibatis.mapping.ResultMapping】
*
* org.apache.ibatis.mapping.ResultMapping{
* private Configuration configuration;
* private String property;
* private String column;
* private Class<?> javaType;
* private JdbcType jdbcType;
* private TypeHandler<?> typeHandler;
* private String nestedResultMapId;
* private String nestedQueryId;
* private Set<String> notNullColumns;
* private String columnPrefix;
* private List<ResultFlag> flags;
* private List<ResultMapping> composites;
* private String resultSet;
* private String foreignColumn;
* private boolean lazy;
* }
*
* 【org.apache.ibatis.executor.resultset.ResultSetHandler】
* org.apache.ibatis.executor.resultset.DefaultResultSetHandler implements ResultSetHandler{
*
* }
*
* 自动映射行为:
* org.apache.ibatis.session.AutoMappingBehavior
* NONE、PARTIAL、FULL
*
* 结果映射方式:
* 1、Map
* 2、自定义类型
* a, 数据库字段 与 JavaBean属性 映射?
* aa, 数据库字段 as 'JavaBean属性名称'
* bb, 使用mybatis <resultMap></resultMap>
* cc, 开启驼峰命名自动映射:设置 org.apache.ibatis.session.Configuration#mapUnderscoreToCamelCase 为true
*
*/
/**
* 【mybatis-参数映射】
* 【org.apache.ibatis.executor.parameter.ParameterHandler】
* org.apache.ibatis.executor.parameter.ParameterHandler{
* Object getParameterObject();
*
* void setParameters(PreparedStatement ps) throws SQLException;
* }
*
* 【org.apache.ibatis.scripting.defaults.DefaultParameterHandler】
* org.apache.ibatis.scripting.defaults.DefaultParameterHandler{
* private final TypeHandlerRegistry typeHandlerRegistry;
*
* private final MappedStatement mappedStatement;
* private final Object parameterObject;
* private final BoundSql boundSql;
* private final Configuration configuration;
* }
*/