美文网首页
MyBatis-Spring -- 集成

MyBatis-Spring -- 集成

作者: saoraozhe3hao | 来源:发表于2018-08-24 14:07 被阅读0次

文档:http://www.mybatis.org/spring/index.html
Github:https://github.com/mybatis/spring
DBCP:DataBase Connection Pool,数据库连接池
JNDI:Java Naming and Directory Interface,Java命名和目录接口;给JNDI工具类提供一个资源配置,就可以得到资源的连接,例如数据库连接
JAT:Java Transaction API,JAT工具类提供跨数据库连接的事务管理能力
DTD:Document Type Definition,文档类型定义
XSD:XML Schema Definition,XML模式定义,用于代替DTD
xmlns:XML Namespaces,XML命名空间
一个框架所需的 xmlns和xsi:schemaLocation,在该框架的jar包下的 META-INF目录 中可以找到

术语
Mapper:SQL操作接口 的 子实例
Repository:DAO相关代码
Service:业务层,即调用Mapper的类

IDEA 配置 MyBatis-Spring
1、Maven增加依赖

<!-- 整合SpringMVC -->
<dependency>
     <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>    <!-- Spring连接数据库相关 -->
    <version>5.0.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>    <!-- 整合MyBatis和Spring,包含SqlSessionFactoryBean、MapperFactoryBean -->
    <version>1.3.2</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>    <!-- 数据库连接池,包含BasicDataSource、TransactionInterceptor -->
    <version>2.5.0</version>
</dependency>
<!-- 整合SpringBoot -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>    <!-- mysql需要在配置文件里配置时区,default-time-zone='+08:00' -->
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.16</version>    <!-- 版本得跟mysql版本一致 -->
</dependency>
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.12</version>
</dependency>

MyBatis-Spring应用的组成
1-0、整合SpringMVC配置,spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">  <!-- 数据源 -->
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/world"/>
        <property name="username" value="root"/>
        <property name="password" value="wowo000"/>
        <property name="maxTotal" value="255"/> <!-- 最大连接数 -->
        <property name="maxIdle" value="5"/>  <!-- 最大等待连接中的数量 -->
        <property name="maxWaitMillis" value="10000"/> <!-- 最大等待毫秒数-->
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>  <!-- 引入MyBatis基础配置,进而引入整个MyBatis应用 -->
    </bean>
    <bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface"  value="com.maven.hogen.CityMapper"/>
        <property name="SqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>

1-1、整合SpringBoot配置,application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    username: root
    password: xxxx
    driver-class-name: com.mysql.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 5
      maximum-pool-size: 15
      auto-commit: true
      idle-timeout: 30000
      pool-name: DatebookHikariCP
      max-lifetime: 500000
      connection-timeout: 30000
      connection-test-query: SELECT 1
mybatis:
  config-location:  classpath:mybatis-config.xml
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: com.hong.xm.pojo

2、使用

@Autowired      // 自动注入Mapper
private CityMapper cityMapper;  

City city = cityMapper.getCity(1L);

事务

丢失更新
第一类丢失更新:事务A更新成功,事务B回滚,回滚到了事务A更新之前的状态,导致事务A的更新丢失;这种丢失已被数据库管理系统解决,即回滚不会回滚掉其他事务的更新
第二类丢失更新:事务A更新成功,事务B在A更新成功之前的基础上更新,导致事务A的更新丢失

隔离级别
脏读:dirty read,允许一个事务去读取另一个事务未提交的数据
出错场景:事务B在事务A更新的基础上进行更新,但后来A回滚了
读/写提交:read commit,一个事务只能读取另一个事务已经提交的数据
出错场景:事务A在事务B提交之前读取一条记录,事务B更新了这条记录,事务A在事务B提交之后再读取同一条记录,事务A两次读取的记录不一致。所以在这个隔离级别下,不可重复读取数据(unrepeatable read)
可重复读:repeatable read,事务之间对同一条数据库记录的读写,排队进行,而不会交叉进行
出错场景:事务A在事务B提交之前统计记录数,事务B增减了记录,在事务B提交之后再统计记录数,两次记录数不同。因此这种隔离级别下,会出现幻读(phantom read )
序列化:Serializable,事务之间对数据库的读写,排队进行,而不会交叉进行

MySQL支持对应的4个隔离级别:READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ(默认),SERIALIZABLE
隔离级别越高,并行能力越差

传播行为
一个方法的传播行为用来描述这个方法支不支持事务,以及是否新开事务
REQUIRED(默认):没有在事务内,则在新建子事务内执行
SUPPORTS:可以在事务内执行
MANDATORY:必须在事务内执行
REQUIRES_NEW:在新建子事务内执行
NOT_SUPPORTED:在事务内,则挂起事务,执行完后,再恢复事务
NEVER:不能在事务内执行
NESTED:嵌套事务,在REQUIRES_NEW的基础上,如果子事务发生回滚,不回滚父事务

Spring 数据库事务
事务模板TransactionTemplate,通过AOP自动为业务代码 获取连接、提交事务、回滚事务
事务管理器PlatformTransactionManager:事务模板持通过调用事务管理器,来完成事务提交、事务回滚
DataSourceTransactionManager:是PlatformTransactionManager的实现类

Spring 数据库事务 应用的组成
1-0、SpringMVC配置,spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="dataSource">同上</bean>
    <bean id="sqlSessionFactory">同上</bean>

    <!-- 扫描basePackage,为@Repository注解的接口创建子实例,并装载入容器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.maven.hogen"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <property name="annotationClass" value="org.springframework.stereotype.Repository"/>
    </bean>

    <!-- 扫描base-package,为@Service和@Component注解的类创建实例,并装载入容器 -->
    <context:annotation-config/>  <!-- 需要引入context命名空间 和 xsd -->
    <context:component-scan base-package="com.maven.hogen"/>
    
    <!-- 事务管理器 -->
    <bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
        <property name="dataSource" ref="dataSource"></property>
    </bean>
     <!-- 启用注解驱动,即将事务模板应用于@Transactional注解的方法 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>  <!-- 需要引入tx命名空间 和 xsd -->

</beans>

1-1、SpringBoot配置,给主类增加注解 @MapperScan("com.hong.xm.dao")

2、Mapper接口

@Repository   // 把Mapper实例装载入容器
public interface CityMapper {
    public City getCity(long id);
}

3、Service类

@Service
public class CityServiceImpl {
    @Autowired              // 自动注入Mapper
    private CityMapper cityMapper = null;  
    // @Transactional只能注解 非static的public方法;方法里调用 @Async 方法,依然会阻塞事务提交
    @Transactional(propagation = Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED)
    public City getCity(long id){
        return cityMapper.getCity(1);
    }
}

4、使用

@Autowired     
private CityServiceImpl cityService = null;  

City city = cityService.getCity(1L);

相关文章

网友评论

      本文标题:MyBatis-Spring -- 集成

      本文链接:https://www.haomeiwen.com/subject/aubbiftx.html