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

<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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值