spring集成mybatis

spring集成mybatis的准备工作

有些项目的持久层框架会选择mybatis,若要更方便的控制事务就需要将mybatis与spring进行整合,本质就是将mybatis的SqlSessionFactory对象交由spring管理,事务方面也交由spring控制。

添加依赖

除了之前添加的spring依赖之外,还需添加下面依赖,因为这里要将mybatis与spring集成,所以需要mybatis-spring的依赖:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.13</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>3.0.1</version>
</dependency>

添加数据库配置文件db.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/learnspring?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=111111

使用全注解集成mybatis

创建User类

public class User {
    private int id;
    private String name;
    //省略构造等方法
}

创建mapper

@Mapper
public interface UserMapper {
    void addUser(User user);
}

创建service

@Service
public class UserServiceImpl implements UserService {

    @Inject
    private UserMapper userMapper;

    @Transactional//事务
    @Override
    public void addUser(User user){
        userMapper.addUser(user);
    }

}

在resources目录下创建文件夹mappers,然后创建UserMapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.monkey1024.mybatis.mapper.UserMapper">
    <insert id="addUser">
        INSERT INTO t_user(name) VALUES (#{name})
    </insert>
</mapper>

创建配置类,主要做了下面几件事情

  • 配置数据源
  • 配置事务管理器
  • 将SqlSessionFactoryBean对象交给spring容器管理
  • 配置MapperScannerConfigurer
/*
    数据库相关配置类
 */
@Configuration
@ComponentScan("com.monkey1024")
@PropertySource("db.properties")
@EnableTransactionManagement//开启事务管理
public class DBConfiguration {

    /*
        数据源
     */
    @Bean
    public DataSource getDataSource(@Value("${jdbc.driver}") String driver, @Value("${jdbc.url}") String url, @Value("${jdbc.user}") String username, @Value("${jdbc.password}") String password) {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(url,username,password);
        dataSource.setDriverClassName(driver);
        return dataSource;
    }


    /*
        事务管理器
     */
    @Bean
    public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager manager = new DataSourceTransactionManager();
        manager.setDataSource(dataSource);

        return manager;
    }

    /*
        将SqlSessionFactoryBean交给spring管理
     */
    @Bean
    public SqlSessionFactoryBean getSqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        //设置别名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.monkey1024.mybatis.bean");
        //告诉mybatis mapper.xml所在的位置
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
        return sqlSessionFactoryBean;
    }

    /*
        配置MapperScannerConfigurer
     */
    @Bean
    public MapperScannerConfigurer getMapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //扫描的包名
        mapperScannerConfigurer.setBasePackage("com.monkey1024.mybatis.mapper");

        return mapperScannerConfigurer;
    }

}

使用xml集成mybatis

添加mybatis.xml配置文件

这里将SqlSessionFactory交由spring管理,数据源也交由spring管理。mapper 映射文件的注册来使用spring的 MapperScannerConfigurer扫描器进行扫描。因此mybatis.xml的配置文件中只需要注册bean即可。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <typeAliases>
        <package name="com.monkey1024.mybatis.bean"/>
    </typeAliases>

</configuration>

添加spring-mybatis.xml配置文件

在该配置文件中,加载数据源,将sqlsessionfactory交由spring管理,使用MapperScannerConfigurer将将Mapper接口生成代理对象。需要注意的是,在注册组件扫描器的时候无需再扫描controller包下的类了,因为已经在springmvc的配置文件中扫描过了。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:db.properties" />

    <!-- 注册组件扫描器 -->
    <context:component-scan base-package="com.monkey1024.*">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
    </bean>

    <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 加载mybatis的全局配置文件 -->
        <property name="configLocation" value="classpath:mybatis.xml" />
        <!--配置mapper文件所在的路径-->
        <property name="mapperLocations" value="mappers/*.xml"/>
    </bean>
    <!-- 自动扫描 将Mapper接口生成代理对象 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.monkey1024.mybatis.mapper" />
    </bean>
</beans>

添加spring-tx.xml文件进行事务的管理

这里的事务管理原理实际上使用的就是aop,关于事务的具体配置信息下一节介绍。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 事务管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 传播行为 -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- 切面 -->
    <aop:config>
        <!--切入点必须是在service层-->
        <aop:advisor advice-ref="txAdvice"
                     pointcut="execution(* com.monkey1024.mybatis.service.*.*(..))" />
    </aop:config>
</beans>