文档章节

ORM框架 hibernate和mybatis 连接数据详解

LYQ1990
 LYQ1990
发布于 2016/04/28 11:51
字数 1096
阅读 65
收藏 2

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

工作中,需要学习一下MyBatis sqlSession的产生过程,翻看了mybatis-spring的源码,阅读了一些mybatis的相关doc,对mybatis sqlSession有了一些认知和理解,这里简单的总结和整理一下。

 

    首先, 通过翻阅源码,我们来整理一下mybatis进行持久化操作时重要的几个类:

  • SqlSessionFactoryBuilder:build方法创建SqlSessionFactory实例。

  • SqlSessionFactory:创建SqlSession实例的工厂。

  • SqlSession:用于执行持久化操作的对象,类似于jdbc中的Connection。

  • SqlSessionTemplate:MyBatis提供的持久层访问模板化的工具,线程安全可通过构造参数或依赖注入SqlSessionFactory实例。

 

    Hibernate是与MyBatis类似的orm框架,这里与Hibernate进行一下对比,Hibernate中对于connection的管理,是通过以下几个重要的类:

  • SessionFactory:创建Session实例的工厂,类似于MyBatis中的SqlSessionFactory。

  • Session:用来执行持久化操作的对象,类似于jdbc中的Connection。

  • HibernateTemplate:Hibernate提供的持久层访问模板化的工具,线程安全,可通过构造参数或依赖注入SessionFactory实例。

 

    在日常的开发中,我们经常需要这样对MyBatis和Spring进行集成,把sqlSessionFactory交给Spring管理,通常情况下,我们这样配置:

?

1
2
3
< bean  id = "sqlSessionFactory"  class = "org.mybatis.spring.SqlSessionFactoryBean" >
     < property  name = "dataSource"  ref = "dataSource"  />
</ bean >

    通过上面的配置,Spring将自动创建一个SqlSessionFactory对象,其中使用到了org.mybatis.spring.SqlSessionFactoryBean,其 是MyBatis为Spring提供的用于创建SqlSessionFactory的类,将在Spring应用程序的上下文建议一下可共享的 MyBatis SqlSessionFactory实例,我们可以通过依赖注入将SqlSessionFactory传递给MyBatis的一些接口。

 

    如果通过Spring进行事务的管理,我们需要增加Spring注解的事务管理机制,如下配置:

?

1
2
3
4
5
< bean  id = "transactionManager"  class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
     < property  name = "dataSource"  ref = "dataSource"  />
</ bean >
  
< tx:annotation-driven />

    

    这样,我们就可以使用Spring @Transactional注解,进行事务的控制,表明所注释的方法应该在一个事务中运行。 Spring将在事务成功完成后提交事务,在事务发生错误时进行异常回滚,而且,Spring会将产生的MyBatis异常转换成适当的 DataAccessExceptions,从而提供具体的异常信息。

 

    下面,我们通过分析SqlSessionUtils中getSession的源码,来详细的了解一下sqlSession的产生过程,源码如下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public  static  SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
  
   notNull(sessionFactory,  "No SqlSessionFactory specified" );
   notNull(executorType,  "No ExecutorType specified" );
  
   SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory);
  
   if  (holder !=  null  && holder.isSynchronizedWithTransaction()) {
     if  (holder.getExecutorType() != executorType) {
       throw  new  TransientDataAccessResourceException( "Cannot change the ExecutorType when there is an existing transaction" );
     }
  
     holder.requested();
  
     if  (logger.isDebugEnabled()) {
       logger.debug( "Fetched SqlSession ["  + holder.getSqlSession() +  "] from current transaction" );
     }
  
     return  holder.getSqlSession();
   }
  
   if  (logger.isDebugEnabled()) {
     logger.debug( "Creating a new SqlSession" );
   }
  
   SqlSession session = sessionFactory.openSession(executorType);
  
   // Register session holder if synchronization is active (i.e. a Spring TX is active)
   //
   // Note: The DataSource used by the Environment should be synchronized with the
   // transaction either through DataSourceTxMgr or another tx synchronization.
   // Further assume that if an exception is thrown, whatever started the transaction will
   // handle closing / rolling back the Connection associated with the SqlSession.
   if  (isSynchronizationActive()) {
     Environment environment = sessionFactory.getConfiguration().getEnvironment();
  
     if  (environment.getTransactionFactory()  instanceof  SpringManagedTransactionFactory) {
       if  (logger.isDebugEnabled()) {
         logger.debug( "Registering transaction synchronization for SqlSession ["  + session +  "]" );
       }
  
       holder =  new  SqlSessionHolder(session, executorType, exceptionTranslator);
       bindResource(sessionFactory, holder);
       registerSynchronization( new  SqlSessionSynchronization(holder, sessionFactory));
       holder.setSynchronizedWithTransaction( true );
       holder.requested();
     else  {
       if  (getResource(environment.getDataSource()) ==  null ) {
         if  (logger.isDebugEnabled()) {
           logger.debug( "SqlSession ["  + session +  "] was not registered for synchronization because DataSource is not transactional" );
         }
       else  {
         throw  new  TransientDataAccessResourceException(
             "SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization" );
       }
     }
   else  {
     if  (logger.isDebugEnabled()) {
       logger.debug( "SqlSession ["  + session +  "] was not registered for synchronization because synchronization is not active" );
     }
   }
  
   return  session;
}

    上面的getSession方法,会从Spring的事务管理器中获取一个SqlSession或创建一个新的SqlSession,将试图从当前事务中得到一个SqlSession,然后,如果配置有事务管理器的工厂并且Spring 的事务管理器是活跃的,它将会锁定当前事务的SqlSession,保证同步。主要是通过以下几个步骤进行SqlSession的创建:

  1. 它会首先获取SqlSessionHolder,SqlSessionHolder用于在TransactionSynchronizationManager中保持当前的SqlSession。

  2. 如果holder不为空,并且holder被事务锁定,则可以通过holder.getSqlSession()方法,从当前事务中获取sqlSession,即 Fetched SqlSession from current transaction。

  3. 如果不存在holder或没有被事务锁定,则会创建新的sqlSession,即 Creating a new SqlSession,通过sessionFactory.openSession()方法。

  4. 如果当前线程的事务是活跃的,将会为SqlSession注册事务同步,即 Registering transaction synchronization for SqlSession。

© 著作权归作者所有

LYQ1990
粉丝 9
博文 238
码字总数 206220
作品 0
东城
私信 提问
Hibernate-ORM:01.Hibernate恍如隔世般初见

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 对于学过ORM框架的朋友来说,上手HibernateORM来说,既熟悉有有一点陌生,熟悉无非是灵魂相通,陌生的只是一些语言罢了 1....

晨曦dawn
2018/05/25
0
0
Java专家之路(二)---数据访问和数据持久化框架的总结

Java数据访问和持久化(SQL) 方案一:JDBC 什么是JDBC? Java语言访问数据库的一种规范,是一套API。JDBC (Java Database Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的...

u011500356
2017/12/20
0
0
MyBatis|JDBC编程中的问题、MyBatis介绍与第一个程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/darlingwood2013/article/details/89328053 MyBatis|JDBC编程中的问题、MyBatis介绍与第一个程序 学习内容来自...

叶晚林
04/16
0
0
Jav ORM框架--Darks ORM

Darks ORM框架是多年前开发的一个Java web ORM框架,现在整理更新后发布。Darks ORM框架综合了hibernate及mybatis的特点,同时也加入了很多新元素。它可以像hibernate一样通过简单易用的API...

小编辑
2014/09/12
733
0
mybatis学习总结-mybatis初体验

从开始工作到现在,用到的ORM框架都是Hibernate,听说过ibatis,但是一直为看过具体的用法。 前段时间面试的时候,发现好几个公司都问会不会ibatis,所以最近几天对其进行了一下学习,然后在...

qq58edf1d989a2d
2018/06/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

密码加密与微服务鉴权JWT详细使用教程

[TOC] 1.1、了解微服务状态 微服务集群中的每个服务,对外提供的都是Rest风格的接口,而Rest风格的一个最重要的规范就是:服务的无状态性。 什么是无状态? 1.服务端不保存任何客户端请求者信...

庭前云落
20分钟前
6
0
Xamarin.FormsShell基础教程(9)Shell相关类体系

Xamarin.FormsShell基础教程(9)Shell相关类体系 在Shell中,最为主要的类是Shell类。Shell类实现了大多数应用程序所需的基本UI功能的页面。除此以外,常用的类还有ShellContent、Tab、Fly...

大学霸
22分钟前
4
0
聊聊MVC、MVP、MVVM吧

先来介绍下本文结构: 三种框架的具体概念 在安卓开发上的写法、优缺点 1.概念 1.1 MVC MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模...

二营长的意大利炮手
39分钟前
4
0
如果解释Python,什么是.pyc文件?

我已经了解Python是一种解释型语言......但是,当我查看我的Python源代码时,我看到.pyc文件,Windows将其识别为“编译的Python文件”。 这些来自哪里? #1楼 Python代码经历了两个阶段。 第...

javail
44分钟前
4
0
.NET Core初览

初览的应用场景为游戏服务器开发。所以测试在侧重点上更强于IO和密集型计算 TODO

梦想游戏人
47分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部