Mybatis数据源与连接池(一)介绍创建过程

来源:互联网 发布:淘宝助理怎么改价格 编辑:程序博客网 时间:2024/05/04 12:48

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">小白学习技术,总会遇到各种新知识扑面而来,而未曾深究过的尴尬局面,比如从一开始自学Servlet,JDBC的时候就碰到过数据源和连接池的概念,只是懵懂理解为数据库就是数据源,连接池可以提高性能,节省应用程序与数据库连接的建立与释放的时间。最近看到一篇博客说ORM框架中数据源的组织直接影响到框架的性能问题,也就是说数据源的组织工作是在框架中完成的,而不是数据库本身完成的。下面的主要内容也基本上是参考前辈的博客然后实际操作完成的。我们下载MyBatis的jar包和源码jar包,发现关于数据源DataSource的package:org.apache.itbtis.datasource。</span>


个人感觉不管是怎么样,应该都要经历我们最初学的JDBC代码,建立连接Connection

,创建Statement或者PreparedStatement等操作。只是一些技术把这些封装好了。

上图其中的unpooled是不使用连接池的数据源,pooled是使用连接池的数据源,jndi是使用JNDI实现的数据源,它是通过JNDI上下文中取值。

而且还看到了熟悉的MyBatis定义的抽象工厂接口:org.apache.ibatis.datasource.DataSourceFactory,又是通过工厂模式创建数据源DataSource对象的,对于我们这种小白,都还不清楚工厂模式到底有什么好处,只知道用来创建对象。



通过看MyBatis的官方文档的入门介绍的mybatis配置文件代码:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration        PUBLIC "-//mybatis.org/dtd/mybatis-3-config.dtd"        "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <environments default="development">        <enviroment 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>        </enviroment>    </environments>    <mappers>        <mapper resource="org/mybatis/example/BlogMapper.xml" />    </mappers></configuration>

它是使用dataSource元素配置数据源,DataSource对象的创建发生在MyBatis初始化的过程中。

其中type属性根据上面介绍推敲出可以设置三个值:

【1】POOLED   MyBatis会创建PooledDataSource实例

【2】UNPOOLED  MyBatis会创建UnpooledDataSource实例

【3】JNDI   MyBatis会从JNDI服务上查找DataSource实例,然后返回使用

MyBatis在初始化时,会解析MyBatis配置文件,根据dataSource元素的type属性创建相应类型的数据源DataSource。这里有个疑问:三种类型的数据源到底有什么区别??

MyBatis是通过工厂模式创建数据源DataSource对象的。

抽象工厂接口org.apache.ibatis.datasource.DataSourceFactory很简单:



通过它的getDataSource()方法返回数据源DataSOurce


MyBatis创建了DataSource实例后,会将其放到Configuration对象内的Environment对象中, 供以后使用。这一点正如MyBatis官方文档中介绍的通过代码方式创建SqlSessionFactory


那DataSource什么时候创建Connection对象给我们用呢?使我们需要的时候才会创建,也就是说我们要执行SQL语句的时候才会创建。比如以下代码:

String resource = "mybatis-config.xml";  Reader reader = Resources.getResourceAsStream(resource);  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  SqlSession sqlSession = sqlSessionFactory.openSession();  sqlSession.selectList("SELECT * FROM STUDENTS"); 
只当当执行sqlSession.selectList的时候才会创建Connection对象
protected void openConnection() throws SQLException {      if (log.isDebugEnabled()) {        log.debug("Opening JDBC Connection");      }      connection = dataSource.getConnection();      if (level != null) {        connection.setTransactionIsolation(level.getLevel());      }      setDesiredAutoCommit(autoCommmit);    } 
上面介绍的是使用连接池的数据源对象,那UNPOOLED的呢?同样的步骤:

MyBatis首先会实例化一个UnpooledDataSourceFactory工厂实例,然后通过.getDataSource()方法返回一个UnpooledDataSource实例对象引用,我们假定为dataSource。

使用UnpooledDataSourcegetConnection(),每调用一次就会产生一个新的Connection实例对象。

UnPooledDataSource的getConnection()方法实现如下:

/* UnpooledDataSource的getConnection()实现 */  public Connection getConnection() throws SQLException  {      return doGetConnection(username, password);  }    private Connection doGetConnection(String username, String password) throws SQLException  {      //封装username和password成properties      Properties props = new Properties();      if (driverProperties != null)      {          props.putAll(driverProperties);      }      if (username != null)      {          props.setProperty("user", username);      }      if (password != null)      {          props.setProperty("password", password);      }      return doGetConnection(props);  }    /*  *  获取数据连接  */  private Connection doGetConnection(Properties properties) throws SQLException  {      //1.初始化驱动      initializeDriver();      //2.从DriverManager中获取连接,获取新的Connection对象      Connection connection = DriverManager.getConnection(url, properties);      //3.配置connection属性  :例如是否自动提交autoCommit和隔离级别isolationLevel    configureConnection(connection);      return connection;  }  
本质就是我们平时写的最普通的JDBC代码



总结:从上述的代码中可以看到,我们每调用一次getConnection()方法,都会通过DriverManager.getConnection()返回新的java.sql.Connection实例。
0 0
原创粉丝点击