【游戏开发】Sqlsession 的理解

2021-03-26
2713
0

MyBatis的持久化解决方案是将用户从原始的JDBC访问中解放出来,用户只需要定义需要操作的SQL语句,无须关注并对其的JDBC操作,就可以以面向对象的方式来进行持久化层操作。数据库连接的获取,数据访问的实现,事务控制等都无须用户关心,从而将应用程序从高层的JDBC / JTA API撤出。通过配置文件管理JDBC连接,让MyBatis解决持久化的实现。在MyBatis中的常见对象有SqlSessionFactory和SqlSession。

一,SqlSessionFactory

SqlSessionFactory是MyBatis的关键对象,它是一个单独的数据库映射关系并通过编译后的内存堆栈。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的配置的实例中放入SqlSessionFactory的实例。每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心。同时SqlSessionFactory是线程安全的,SqlSessionFactory一旦被创建,应该在应用执行期间都存在。使用单例模式.SqlSessionFactory是创建SqlSession的工厂。

包org.apache.ibatis.session;

导入java.sql.Connection;

公共接口SqlSessionFactory {

    SqlSession openSession(); //这个方法最经常用,创建了SqlSession对象。

    SqlSession openSession(boolean autoCommit);

    SqlSession openSession(连接连接);

    SqlSession openSession(TransactionIsolationLevel级别);

    SqlSession openSession(ExecutorType execType);

    SqlSession openSession(ExecutorType execType,boolean autoCommit);

    SqlSession openSession(ExecutorType execType,TransactionIsolationLevel级别);

    SqlSession openSession(ExecutorType execType,连接连接);

    配置getConfiguration();

}

二,SqlSession

SqlSession是MyBatis的关键对象,是执行持久化操作的独享,JDBCJDBC的Connection。它是应用程序与持久层之间执行交互操作的一个单线程对象,也是MyBatis执行持久化操作的关键对象.SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法,它的嵌套封装了JDBC连接,可以使用SqlSession实例来直接执行被映射的SQL语句。每个线程都应该有它自己的SqlSession实例。 SqlSession的实例不能被共享,同时SqlSession也是线程不安全的,绝对不能讲SqlSeesion实例的引用放在一个类的静态甚至是实例中断中。也绝不能将SqlSession实例的引用放在任何类型的管理范围内中,Servlet间的HttpSession对象中。使用完SqlSeesion之后关闭会话很重要,应该确保使用finally块来关闭它。

1 // SqlSession接口原始代码如下所示:2 3包org.apache.ibatis.session; 4 5 import java.io.Closeable; 6导入java.sql.Connection; 7导入java.util.List; 8导入java.util.Map; 9 10导入org.apache.ibatis.executor.BatchResult; 11 12公共接口SqlSession扩展Closeable {13 14 <T> T selectOne(String statement); 15 16 <T> T selectOne(String语句,Object参数); 17 18 <E>列表<E> selectList(String statement); 19 20 <E>列表<E> selectList(String语句,Object参数); 21 22 <E>列表<E> selectList(String语句,Object参数,RowBounds rowBounds); 23 24 <K,V> Map <K,V> selectMap(String语句,String mapKey); 25 26 <K,V> Map <K,V> selectMap(String语句,Object参数,String mapKey); 27 28 <K,V>映射<K,V> selectMap(String语句,Object参数,String mapKey,RowBounds rowBounds); 29 30 void select(String语句,Object参数,ResultHandler处理程序); 31 32 void select(String语句,ResultHandler处理程序); 33 34 void select(String语句,Object参数,RowBounds rowBounds,ResultHandler处理程序); 35 36 int insert(String语句); 37 38 int insert(String语句,Object参数); 39 40 int update(String语句); 41 42 int update(String语句,Object参数); 43 44 int delete(字符串语句); 45 46 int delete(String语句,Object参数); 47 48 void commit(); 49 50 void commit(布尔力); 51 52 void rollback(); 53 54无效的回滚(布尔力); 55 56 List <BatchResult> flushStatements(); 57 58 void close(); 59 60 void clearCache(); 61 62配置getConfiguration(); 63 64 <T> T getMapper(Class <T>类型); 65 66连接getConnection(); 67}

三,SqlSessionFactory和SqlSession实现过程

 

mybatis框架主要是围绕着SqlSessionFactory进行的,创建过程大概如下:

(1),定义一个配置对象,其中包含数据源,事务,mapper文件资源以及影响数据库行为属性设置的设置(2),通过配置对象,则可以创建一个SqlSessionFactoryBuilder对象(3),通过SqlSessionFactoryBuilder获得SqlSessionFactory的实例。(4),SqlSessionFactory的实例可以操作数据的SqlSession实例,通过这个实例对数据库进行操作

并且如果想按照上述方式得到SqlSessionFactory,最好使用下面的mybatis-config.xml类似的配置。在这里mybatis-config.xml配置文件是没有和Spring配置文件合并过得好,如果项目中mybaits的配置文件和Spring配置文件整合过了,则下面的代码运行估计会出错,因为一般spring和mybatis整合过之后,mybatis的配置文件基本没有存在的必要了,然后在mybatis中配置的数据源和事务这两个方面,一般的规范都会spring的配置文件,则下面的代码加载mybatis-config.xml的时候,得不到必要的信息,创建的过程中会有问题。所以在这里先给一份mybatis-config.xml单独的配置文件。 

1 <?xml版本=“ 1.0” encoding =“ UTF-8”?> 2 2 <!DOCTYPE配置PUBLIC“-// mybatis.org//DTD Config 3.0 // EN”“ http://mybatis.org/dtd/mybatis-3-config.dtd”> 

3 3 <配置> 4 4 5 5 <!-加载数据库属性文件-> 6 6 <属性resource =“ jdbc.properties”> 7 7 </ properties> 
 8 8 <!-可以配置多个运行环境,但是每个SqlSessionFactory实例只能选择一个运行环境一,开发:开发模式二,工作:工作模式-> 
 9 9 <environments default =“ development”> 
10 10 <!-id属性必须和上面的默认一样-> 
11 11 <environment id =“ development”> 
12 12 <transactionManager type =“ JDBC” /> 13 13 <!-dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象源-> 14 14 <数据源类型=“ POOLED”> 15 15 <属性名称=“驱动程序”值=“ $ {jdbc.driver}” /> 16 16 <属性名称=“ url”值=“ $ {jdbc.url}” / > 17 17 <属性名称=“username“ value =” $ {jdbc.username}“ /> 18 18 <属性名=” password“ value =” $ {jdbc.password}“ /> 19 19 </ dataSource>
20 20 </ environment> 21 21 </ environments> 
22 22 <!-在配置文件中关联包下的接口类->

23 23 <mappers> 
24 24 <mapper resource =“ com / ys / mapper / userMapper.xml” /> 
25 25 </ mappers> 
26 26 </ configuration>“

 

下面的这行代码功能是通过配置文件mybatis-config.xml,创建SqlSessionFactory对象,然后产生SqlSession,执行SQL语句。而mybatis的初始化发生在:

 

SqlSessionFactory sqlSessionFactory =新的SqlSessionFactoryBuilder()。build(resourceAsStream);

 

如果是spring和mybaits整合后的配置文件,通常
以这种方式实现,
SqlSessionFactory的创建:<bean id =“ sqlSessionFactory” class =“ org.mybatis.spring.SqlSessionFactoryBean”> <属性名称=“ dataSource” ref = “ dataSource”> </ property> 
        <!-自动扫描mapping.xml文件-> 
        <property name =“ mapperLocations” value =“ classpath:com / cn / mapper 
/ *。xml”> </ property> 
</豆> * /

 

/ ** 
*关于SqlSessionFactory和SqlSession两个对象给一个具体的使用过程:
* / 
1个包com.cn.testIUserService; 
2 3 import java.io.IOException; 
4导入java.io.InputStream; 
5导入org.apache.ibatis.io.Resources; 
6导入org.apache.ibatis.session.SqlSession; 
7导入org.apache.ibatis.session.SqlSessionFactory; 
8导入org.apache.ibatis.session.SqlSessionFactoryBuilder; 
9 10导入com.cn.entity.User; 
11 12 public class MyBatisTest { 
    13 14 public static void main(String [] args){ 
        15 
        try { 
            16 //读取mybatis-config.xml文件
            17 InputStream resourceAsStream = Resources.getResourceAsStream(“ mybatis-config.xml”);
            18 //初始化mybatis,创建SqlSessionFactory类的实例
            19 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()。build(resourceAsStream); 
            20 //创建session实例
            21 SqlSession session = sqlSessionFactory.openSession(); 
            22 
            / * 
23 *接下来在这里做很多事情,立即,目的已经达到了SqlSession对象。通过调用SqlSession里面的方法,
24 *可以测试MyBatis和Dao层接口方法之间的正确性,当然也可以做别的很多事情,在这里就不双层了
25 * / 
            26 //插入数据
            27 User user = new User(); 
            28 user.setC_password(“ 123”); 
            29 user.setC_username(“ 123”); 
            30 user.setC_salt(“ 123”);
            31 //第一个参数为方法的完全限定名称:位置信息映射文件当中的id 
            32 session.insert(“ com.cn.dao.UserMapping.insertUserInformation”,user); 
            33 //提交事务
            34 session.commit(); 
            35 //关闭会话
            36 session.close(); 
            37 
        } catch(IOException e){ 
            38 e.printStackTrace(); 
            39 
        } 
        40 
    } 
    41 
}

 

结合上述SqlSessionFactory和SqlSession使用过程和结构图,
涉及到的方法为下面的步骤,
结合二进制中的方法为下面的步骤:初始SqlSessionFactoryBuilder去读取mybatis的配置文件,然后构建一个DefaultSqlSessionFactory,
即得到SqlSessionFactory

 

//涉及中包的包装和具体方法为:
//涉及中包的包装:org.apache.ibatis.session; 
// 
public SqlSessionFactory build(InputStream inputStream){ 
    return build(inputStream,null,null); //返回第一个类为:SqlSessionFactoryBuilder,设计到此类的方法为下面的部分:public SqlSessionFactory build(InputStream inputStream){ return build(inputStream,null,null); 
}

公共SqlSessionFactory构建(InputStream inputStream,字符串环境,属性属性){
    试试{ 
        //通过XMLConfigBuilder解析配置文件,解析配置相关信息都会封装为一个配置对象
        XMLConfigBuilder解析器= new XMLConfigBuilder(inputStream,环境,属性);
        //然后返回一个DefaultSqlSessionFactory 
        return build(parser.parse()); 
    } catch(Exception e){ 
        throw ExceptionFactory.wrapException(“建立SqlSession时出错。”,e); 
    }最后{ 
        ErrorContext.instance()。reset(); 
        尝试{ 
            inputStream.close(); 
        } catch(IOException e){ 
            //故意忽略。更喜欢以前的错误。
        }
    } 
}

//获得DefaultSqlSessionFactory 
public SqlSessionFactory build(Configuration config){ 
    return new DefaultSqlSessionFactory(config); 
}

//第二个类为:DefaultSqlSessionFactory,涉及的方法为:
public DefaultSqlSessionFactory(Configuration configuration){ 
    this.configuration = configuration; 
}

 

第二步,获取到SqlSessionFactory之后,就可以利用SqlSessionFactory方法的openSession来获取SqlSession对象了。

 

得到SqlSession对象之后就可以利用SqlSession内部的方法进行CRUD操作了。

注意一点,Connection对象是在SqlSession对象创建之后进行CURD操作中创建的。深入查找之后发现在ManagedTransaction类中找到获取Connection对象的关键代码如下:

私有SqlSession openSessionFromDataSource(ExecutorType execType,TransactionIsolationLevel级别,布尔值autoCommit){ 
    2事务tx = null; 
    3 
    try { 
        4 //通过配置对象去获取Mybatis相关配置信息,环境对象包含了数据源和事务的配置
        5 // execType为执行器类型,配置文件中定义
        6 // SimpleExecutor-SIMPLE就是普通的执行器
        。7 // ReuseExecutor-执行器会重用预处理语句(prepared statement)
        8 // BatchExecutor-它是批量执行器
        9 final Environment environment = configuration.getEnvironment();。
        10最后的TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); 
        11 tx = transactionFactory.newTransaction(environment.getDataSource(),level,autoCommit);
        12 //定义执行器,是对声明的封装
        13 final Executor executor = configuration.newExecutor(tx,execType); 
        14 //最后返回一个SqlSession 
        15
        返回新的DefaultSqlSession(configuration,executor,autoCommit); 
        16 
    } catch(Exception e){ 
        17 closeTransaction(tx); //可能获取了连接,所以让我们调用close()
        18 
        throw ExceptionFactory.wrapException(“打开会话时出错。原因:” e,e); 
        19 
    }最后{ 
        20 ErrorContext.instance()。reset(); 
        21 
    } 
    22 
}

 

1受保护的void openConnection()引发SQLException { 
    2
    如果(log.isDebugEnabled()){ 
        3 log.debug(“ Opening JDBC Connection”); 
        4 
    } 
    5 // dataSource来源有三种,JndiDatasource,PooledDataSource,UnpooledDataSource,配置文件中定义
    6 this.connection = this.dataSource.getConnection(); 
    7 
    if(this.level!= null){ 
        8 this.connection.setTransactionIsolation(this.level.getLevel()); 7 
        9 
    } 
    10 
}

 

PooledDataSource和UnPooledDataSource的区别是PooledDataSource使用了连接池。为什么使用连接池呢?因为创建一个Connection对象的过程,在底层就相当于和数据库建立的通信连接,在建立通信连接的过程,消耗了非常多的时间,而往往我们建立连接后(即创建Connection对象后),就执行一个简单的SQL语句,然后就要抛弃掉,这是一个非常大的资源浪费!mybatis针对这一个问题提出的PooledDataSource使用了连接池。

 

 

转载声明:本文来源于网络,不作任何商业用途

免责声明:本文内部分内容来自网络,所涉绘画作品及文字版权与著作权归原作者,若有侵权或异议请联系我们处理。
收藏

全部评论

您还没登录

暂无留言,赶紧抢占沙发
王氏教育是国内专业的CG数字艺术设计线上线下学习平台,在王氏教育,有原画、插画、漫画、影视、3D模型等培训课程,也有学习资源下载、行业社区交流。CG数字艺术学习,来王氏教育。
绘学霸iOS端二维码

IOS下载

绘学霸安卓端二维码

安卓下载

绘学霸微信小程序二维码

小程序

版权声明
本网站所有产品设计、功能及展示形式,均已受版权或产权保护,任何公司及个人不得以任何方式复制部分或全部,违者将依法追究责任,特此声明。
热线电话
18026259035
咨询时间:9:00~21:00
在线客服
联系网站客服
客服微信:18026259035
公司地址
中国·广州
广州市海珠区晓港中马路130号之19
绘学霸客户端(权限暂无,用于CG资源与教程交流分享)
王氏教育 王氏教育