当前位置:   article > 正文

Mybatis的工作流程、SqlSession的创建_mybatis的sqlsession什么时候创建

mybatis的sqlsession什么时候创建

目录

JDBC(Java Data Base Connectivity)​

JDK动态代理

Mybatis 的基本流程:

SqlSessionFactoryBuilder(工厂构造器,生命周期只存于方法内部):

SqlSessionFactory(工厂接口):

SqlSession(会话):

​​SqlSession四大对象

SqlSession接口源码:


JDBC(Java Data Base Connectivity)

1.Driver接口(类管理数据库驱动程序的列表)
  Driver接口由数据库厂家提供,编程中要连接数据库,须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。
  装载 MySql 驱动: Class.forName("com.mysql.jdbc.Driver");
  装载 Oracle 驱动: Class.forName("oracle.jdbc.driver.OracleDriver");

2.Connection接口( 与数据库中的所有的通信是通过唯一的连接对象)
  Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。
   DriverManager.getConnection(url,user,password)方法建立在JDBC URL中定义的数据库Connection连接上。
  连 MySql: Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");
  连 Oracle: Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");
  连 SqlServer: Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");
   常用方法:
      createStatement(): 创建向数据库发送 sql 的 statement 对象
      prepareStatement(sql): 创建向数据库发送预编译 sql 的 PrepareSatement 对象
      prepareCall(sql): 创建执行存储过程的 callableStatement 对象
      setAutoCommit(boolean autoCommit): 设置事务是否自动提交
      commit(): 在链接上提交事务
      rollback(): 在此链接上回滚事务

3.Statement接口(把创建的SQL对象,转而存储到数据库当中)
  用于执行静态SQL语句并返回它所生成结果的对象
  三种Statement类:
   Statement: 由createStatement创建,用于发送简单的SQL语句(不带参数)。
   PreparedStatement: 继承自Statement接口,由preparedStatement创建,用于发送含有一个或多个参数的SQL语句。PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入,所以我们一般都使用PreparedStatement。
   CallableStatement: 继承自PreparedStatement接口,由方法prepareCall创建,用于调用存储过程。
   常用Statement方法:
       execute(String sql): 运行语句,返回是否有结果集
       executeQuery(String sql): 运行select语句,返回ResultSet结果集
       executeUpdate(String sql): 运行insert/update/delete操作,返回更新的行数
       addBatch(String sql): 把多条sql语句放到一个批处理中
       executeBatch(): 向数据库发送一批sql语句执行

4.ResultSet接口(它是一个迭代器,用于检索查询数据)
    ResultSet提供检索不同类型字段的方法,常用的有:
    getString(int index)、getString(String columnName): 获得在数据库里是varchar、char等类型的数据对象
    getFloat(int index)、getFloat(String columnName): 获得在数据库里是Float类型的数据对象
    getDate(int index)、getDate(String columnName): 获得在数据库里是Date类型的数据
    getBoolean(int index)、getBoolean(String columnName): 获得在数据库里是Boolean类型的数据
    getObject(int index)、getObject(String columnName): 获取在数据库里任意类型的数据
    ResultSet还提供了对结果集进行滚动的方法:
        next(): 移动到下一行
        Previous(): 移动到前一行
        absolute(int row): 移动到指定行
        beforeFirst(): 移动resultSet的最前面
        afterLast(): 移动到resultSet的最后面
        使用后依次关闭对象及连接: ResultSet → Statement → Connection

JDK动态代理

  1. public interface JDKAgent {
  2. public void sayHello(String messgae);
  3. }
  4. public class JDKAgentImpl implements JDKAgent{
  5. @Override
  6. public void sayHello(String messgae){
  7. System.out.println("---JDKAgentImpl--Hello: "+messgae);
  8. }
  9. }
  10. public class JDKAgentProxy implements InvocationHandler {
  11. // 目标对像
  12. private Object target;
  13. public Object bind(Object target){
  14. this.target = target;
  15. return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
  16. }
  17. @Override
  18. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  19. System.out.println("******************** JDK动态代理开始 ********************");
  20. Object result = null;
  21. result = method.invoke(target,args);
  22. System.out.println("********* JDK动态代理结束 ********* ");
  23. return result;
  24. }
  25. // 测试方法
  26. public static void main(String []args){
  27. //通过接口进行代理
  28. JDKAgentProxy jdkAgentProxy = new JDKAgentProxy();
  29. JDKAgent proxy = (JDKAgent)jdkAgentProxy.bind(new JDKAgentImpl());
  30. proxy.sayHello("JunSouth");
  31. }
  32. }


Mybatis 的基本流程:

(1)、定义一个Configuration对象,其中包含数据源、事务、mapper文件资源以及影响数据库行为属性设置 settings。

(2)、通过配置对象,则可以创建一个SqlSessionFactoryBuilder对象。

(3)、通过 SqlSessionFactoryBuilder 获得SqlSessionFactory 的实例。

(4)、SqlSessionFactory 的实例可以获得操作数据的SqlSession实例,通过这个实例对数据库进行操作。

SqlSessionFactoryBuilder(工厂构造器,生命周期只存于方法内部):

根据配置信息或代码来生成 SqlSessionFactory,通过输入Mybatis配置文件的字节流或字符流生成XMLConfigBuilder,XMLConfigBuilder创建一个Configuration,Configuration包含了mybatis的配置的一切信息,Mybatis的所有操作要根据Configuration的信息进行。

SqlSessionFactoryBuilder 有五个 build() 方法,每一种都允许从不同的资源中创建一个 
  1. SqlSessionFactory build(InputStream inputStream)
  2. SqlSessionFactory build(InputStream inputStream, String environment)
  3. SqlSessionFactory build(InputStream inputStream, Properties properties)
  4. SqlSessionFactory build(InputStream inputStream, String env, Properties props)
  5. SqlSessionFactory build(Configuration config)

SqlSessionFactory(工厂接口):

可通过SqlSessionFactoryBuilder对象类获得,SqlSessionFactoryBuilder可从XML文件或 Configuration 实例构出, SqlSessionFactory 是创建 SqlSession 的工厂。单个数据库映射关系经过编译后的内存镜像(一个数据对应一个实例),每个MyBatis的应用都以一个 SqlSessionFactory 对象的实例为核心,线程安全的,生命周期在整个Mybatis程序中。
  1. public interface SqlSessionFactory {
  2. SqlSession openSession();
  3. SqlSession openSession(boolean autoCommit);
  4. SqlSession openSession(Connection connection);
  5. SqlSession openSession(TransactionIsolationLevel level);
  6. SqlSession openSession(ExecutorType execType);
  7. SqlSession openSession(ExecutorType execType, boolean autoCommit);
  8. SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  9. SqlSession openSession(ExecutorType execType, Connection connection);
  10. Configuration getConfiguration();
  11. }
例:
  1. // 创建数据源
  2. DataSource dataSource = BaseDataTest.createBlogDataSource();
  3. TransactionFactory transactionFactory = new JdbcTransactionFactory();
  4. Environment environment = new Environment("development", transactionFactory, dataSource);
  5. Configuration configuration = new Configuration(environment);
  6. // 配置信息
  7. configuration.setLazyLoadingEnabled(true);
  8. configuration.setEnhancementEnabled(true);
  9. configuration.getTypeAliasRegistry().registerAlias(Blog.class);
  10. configuration.getTypeAliasRegistry().registerAlias(Post.class);
  11. configuration.getTypeAliasRegistry().registerAlias(Author.class);
  12. configuration.addMapper(BoundBlogMapper.class);
  13. configuration.addMapper(BoundAuthorMapper.class);
  14. // 创建 SqlSessionFactoryBuilder ——> SqlSessionFactory
  15. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  16. SqlSessionFactory factory = builder.build(configuration);

SqlSession(会话):

执行SQL操作,底层封装了JDBC连接,可用SqlSession实例直接执行被映射的SQL语句。每个线程都有自己的SqlSession实例,不能共享,线程不安全,用完后应关闭。

​​SqlSession四大对象

Executor(执行器):  用来调度 StatementHandler、ParameterHandler、ResultHandler等来执行对应的SQL。
StatementHandler(数据库会话处理器): 使用数据库的Statement执行操作。
ParameterHandler: 对Sql参数的处理。
ResultSetHandler: 对ResultSet结果集封装返回处理的。
生成SqlSession时,DefaultSqlSessionFactory中调用openSession,又调openSessionFromDataSource方法。
  1. DefaultSqlSessionFactory中openSessionFromDataSource方法:
  2. private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
  3. Transaction tx = null;
  4. try {
  5. final Environment environment = configuration.getEnvironment();
  6. final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
  7. tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
  8. // 生成执行器
  9. final Executor executor = configuration.newExecutor(tx, execType);
  10. return new DefaultSqlSession(configuration, executor, autoCommit);
  11. } catch (Exception e) {
  12. closeTransaction(tx); // may have fetched a connection so lets call close();
  13. throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
  14. } finally {
  15. ErrorContext.instance().reset();
  16. }
  17. }
  18. Configration的newExecutor方法中根据类型判断创建那种执行器,默认使用的是SimpleExecutor:
  19. public class Configuration {
  20. public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
  21. executorType = executorType == null ? defaultExecutorType : executorType;
  22. executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
  23. Executor executor;
  24. // 根据类型判断创建哪种类型的执行器
  25. if (ExecutorType.BATCH == executorType) {
  26. // 批量执行所有更新语句
  27. executor = new BatchExecutor(this, transaction);
  28. } else if (ExecutorType.REUSE == executorType) {
  29. // 重用预处理语句
  30. executor = new ReuseExecutor(this, transaction);
  31. } else {
  32. // 默认的执行器
  33. executor = new SimpleExecutor(this, transaction);
  34. }
  35. if (cacheEnabled) {
  36. executor = new CachingExecutor(executor);
  37. }
  38. executor = (Executor) interceptorChain.pluginAll(executor);
  39. return executor;
  40. }
  41. }

SqlSession接口源码:

  1. public interface SqlSession extends Closeable {
  2. <T> T selectOne(String statement);
  3. <T> T selectOne(String statement, Object parameter);
  4. <E> List<E> selectList(String statement);
  5. <E> List<E> selectList(String statement, Object parameter);
  6. <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
  7. <K, V> Map<K, V> selectMap(String statement, String mapKey);
  8. <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
  9. <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
  10. void select(String statement, Object parameter, ResultHandler handler);
  11. void select(String statement, ResultHandler handler);
  12. void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
  13. int insert(String statement);
  14. int insert(String statement, Object parameter);
  15. int update(String statement);
  16. int update(String statement, Object parameter);
  17. int delete(String statement);
  18. int delete(String statement, Object parameter);
  19. void commit();
  20. void commit(boolean force);
  21. void rollback();
  22. void rollback(boolean force);
  23. List<BatchResult> flushStatements();
  24. void close();
  25. void clearCache();
  26. Configuration getConfiguration();
  27. <T> T getMapper(Class<T> type);
  28. Connection getConnection();
  29. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/158226?site
推荐阅读
相关标签
  

闽ICP备14008679号