Spring整合MyBatis

一、整合以前的環境準備

  1. 導入相關的jar包html

  • Junit測試java

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
  • MyBatismysql

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
  • MySQL數據庫web

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
  • Spring相關spring

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.3</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.3</version>
    </dependency>
  • aspectJ AOP 織入器sql

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.6</version>
    </dependency>
  • mybatis-spring整合包 【重點】數據庫

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

配置Maven靜態資源過濾問題!安全

<build>
   <resources>
       <resource>
           <directory>src/main/java</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>true</filtering>
       </resource>
   </resources>
</build>

二、回憶MyBatis

  1. 編寫一個實體類Usersession

    public class User {
        private Integer id;
        private String name;
        private String pwd;
        // getter and setter
        // 有參和無參
        // toString
    }
  2. 編寫MyBatis核心配置文件mybatis

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false
    jdbc.username=root
    jdbc.password=123456
    <?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>
        <properties resource="jdbc.properties"/>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"/>
                    <property name="url" value="${jdbc.url}"/>
                    <property name="username" value="${jdbc.username}"/>
                    <property name="password" value="${jdbc.password}"/>
                </dataSource>
            </environment>
        </environments>
    </configuration>
  3. 編寫UserMapper接口

    public interface UserMapper {
        List<User> userList();
    }
  4. 編寫接口對應的Mapper.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.jh.mapper.UserMapper">
        <select id="userList" resultType="com.jh.domain.User">
            select * from mybatis.user
        </select>
    </mapper>
  5. 註冊Mapper.xml文件

    <mappers>
        <mapper resource="com/jh/mapper/UserMapper.xml"/>
    </mappers>
  6. 編寫測試類

    @Test
    public void userList() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream stream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
        
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        List<User> userList = userMapper.userList();
        userList.forEach(System.out::println);
        
        sqlSession.close();
    }
  7. 輸出結果

    User{id=1, name='小王', pwd='123456'}
    User{id=2, name='張三', pwd='123456'}
    User{id=3, name='李四', pwd='123456'}

三、MyBatis-Spring學習

引入Spring以前須要瞭解mybatis-spring包中的一些重要類;

MyBatis-Spring中文官網:https://mybatis.org/spring/zh/index.html

image-20210122142600772

什麼是 MyBatis-Spring?

MyBatis-Spring 會幫助你將 MyBatis 代碼無縫地整合到 Spring 中。

知識基礎

在開始使用 MyBatis-Spring 以前,你須要先熟悉 Spring 和 MyBatis 這兩個框架和有關它們的術語。這很重要

MyBatis-Spring 須要如下版本:

MyBatis-Spring MyBatis Spring Framework Spring Batch Java
2.0 3.5+ 5.0+ 4.0+ Java 8+
1.3 3.4+ 3.2.2+ 2.1+ Java 6+

使用 Maven 做爲構建工具,僅須要在 pom.xml 中加入如下代碼便可:

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

和 Spring 一塊兒使用 MyBatis,須要在 Spring 應用上下文中定義至少兩樣東西:一個 SqlSessionFactory 和至少一個數據映射器類。

在 MyBatis-Spring 中,可以使用 SqlSessionFactoryBean來建立 SqlSessionFactory。 要配置這個工廠 bean,只須要把下面代碼放在 Spring 的 XML 配置文件中:

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

注意:SqlSessionFactory 須要一個 DataSource(數據源)。這能夠是任意的 DataSource,只須要和配置其它 Spring 數據庫鏈接同樣配置它就能夠了。經常使用第三方數據源:dbcp,c3p,druid

在基礎的 MyBatis 用法中,是經過 SqlSessionFactoryBuilder 來建立 SqlSessionFactory 的。而在 MyBatis-Spring 中,則使用 SqlSessionFactoryBean 來建立。

在 MyBatis 中,你可使用 SqlSessionFactory 來建立 SqlSession。一旦你得到一個 session 以後,你可使用它來執行映射了的語句,提交或回滾鏈接,最後,當再也不須要它的時候,你能夠關閉 session。

SqlSessionFactory有一個惟一的必要屬性:用於 JDBC 的 DataSource。這能夠是任意的 DataSource 對象,它的配置方法和其它 Spring 數據庫鏈接是同樣的。

一個經常使用的屬性是 configLocation,它用來指定 MyBatis 的 XML 配置文件路徑。它在須要修改 MyBatis 的基礎配置很是有用。一般,基礎配置指的是 < settings> 或 < typeAliases>元素。

須要注意的是,這個配置文件並不須要是一個完整的 MyBatis 配置。確切地說,任何環境配置(

SqlSessionTemplate 是 MyBatis-Spring 的核心。做爲 SqlSession 的一個實現,這意味着可使用它無縫代替你代碼中已經在使用的 SqlSession。

模板能夠參與到 Spring 的事務管理中,而且因爲其是線程安全的,能夠供多個映射器類使用,你應該老是用 SqlSessionTemplate 來替換 MyBatis 默認的 DefaultSqlSession 實現。在同一應用程序中的不一樣類之間混雜使用可能會引發數據一致性的問題。

可使用 SqlSessionFactory 做爲構造方法的參數來建立 SqlSessionTemplate 對象。

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <!-- 只能使用構造器注入sqLSessionFactory,由於它沒有set方法- -->
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

如今,這個 bean 就能夠直接注入到你的 DAO bean 中了。你須要在你的 bean 中添加一個SqlSessionTemplate 屬性,就像下面這樣:

public class UserMapperImpl implements UserMapper {
    private SqlSessionTemplate sessionTemplate;

    public void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
        this.sessionTemplate = sessionTemplate;
    }

    @Override
    public List<User> userList() {
        UserMapper mapper = sessionTemplate.getMapper(UserMapper.class);
        return mapper.userList();
    }
}

按下面這樣,注入 SqlSessionTemplate:

<bean id="userMapper" class="com.jh.mapper.UserMapperImpl">
    <property name="sessionTemplate" ref="sqlSessionTemplate"/>
</bean>

四、實現整合方式一

  1. 編寫Spring配置文件applicationContext.xml

    <?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: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/context 
           https://www.springframework.org/schema/context/spring-context.xsd">
    </beans>
  2. 配置數據源替換mybaits的數據源

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false
    jdbc.username=root
    jdbc.password=123456
    <!-- 導入數據庫鏈接信息 -->
    <context:property-placeholder location="classpath*:jdbc.properties"/>
    <!-- 數據源:DataSource;使用Spring的數據源替換Mybatis的配置  c3p,dbcp druid spring-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
  3. 配置SqlSessionFactory,關聯MyBatis

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 綁定MyBatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 註冊Mapper文件 -->
        <property name="mapperLocations" value="classpath*:com/jh/mapper/*.xml"/>
    </bean>
  4. 註冊sqlSessionTemplate,關聯sqlSessionFactory;

    <!-- SqlSessionTemplate:就是咱們使用的sqlSession -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 只能使用構造器注入sqLSessionFactory,由於它沒有set方法- -->
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
  5. 增長Dao接口的實現類;私有化sqlSessionTemplate

    public class UserMapperImpl implements UserMapper {
        private SqlSessionTemplate sessionTemplate;
    
        public void setSessionTemplate(SqlSessionTemplate sessionTemplate) {
            this.sessionTemplate = sessionTemplate;
        }
    
        @Override
        public List<User> userList() {
            UserMapper mapper = sessionTemplate.getMapper(UserMapper.class);
            return mapper.userList();
        }
    }
  6. 註冊bean實現;

    <!-- 註冊UserMapperImpl到Spring -->
    <bean id="userMapper" class="com.jh.mapper.UserMapperImpl">
        <property name="sessionTemplate" ref="sqlSessionTemplate"/>
    </bean>
  7. 測試;

    @Test
    public void userList() throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        List<User> userList = userMapper.userList();
        userList.forEach(System.out::println);
    }

結果成功輸出!如今咱們的Mybatis配置文件的狀態!發現均可以被Spring整合!

<?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>

</configuration>

四、實現整合方式二

mybatis-spring1.2.3版以上的纔有這個。

官方文檔截圖:

dao繼承Support類,直接利用 getSqlSession() 得到,而後直接注入SqlSessionFactory。比起方式1,不須要管理SqlSessionTemplate,並且對事務的支持更加友好。可跟蹤源碼查看

image-20210122153422674

具體實現:

  1. 修改上面寫的UserMapperImpl

    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
        @Override
        public List<User> userList() {
            return super.getSqlSession().getMapper(UserMapper.class).userList();
        }
    }
  2. 修改applicationContext.xml的配置

    <bean id="userMapper" class="com.jh.mapper.UserMapperImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
  3. 測試

    @Test
    public void userList() throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        List<User> userList = userMapper.userList();
        userList.forEach(System.out::println);
    }

五、實現整合方式三

爲了代替手工使用SqlSessionDaoSupport或SqlSessionTemplate編寫數據訪問對象(DAO)的代碼,使用動態代理實現,MapperFactoryBean出現了。

這個類 可讓你直接注入數據映射器接口到你的 service 層 bean 中。當使用映射器時,你僅僅如調用你的DAO同樣調用它們就能夠了,可是你不須要編寫任何 DAO 實現的代碼,由於 MyBatis-Spring 將會爲你建立代理。

先查看官網的配置:

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

org.mybatis.spring.sample.mapper.UserMapper是一個接口,咱們建立一個MapperFactoryBean實例,而後注入這個接口和sqlSessionFactory(mybatis中提供的SqlSessionFactory接口,MapperFactoryBean會使用SqlSessionFactory建立SqlSession)這兩個屬性。

以後想使用這個UserMapper接口的話,直接經過spring注入這個bean,而後就能夠直接使用了,spring內部會建立一個這個接口的動態代理。

當發現要使用多個MapperFactoryBean的時候,一個一個定義確定很是麻煩,因而mybatis-spring提供了MapperScannerConfigurer這個類,它將會查找類路徑下的映射器並自動將它們建立成MapperFactoryBean。

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="org.mybatis.spring.sample.mapper" />
</bean>

這段配置會掃描org.mybatis.spring.sample.mapper下的全部接口,而後建立各自接口的動態代理類。

具體代碼實現:

  1. 編寫Mapper接口

    public interface UserMapper {
        List<User> userList();
    }
  2. 編寫Service方法和對應實現類

    public interface UserService {
        List<User> userList();
    }
    public class UserServiceImpl implements UserService {
        private UserMapper userMapper;
    
        public void setUserMapper(UserMapper userMapper) {
            this.userMapper = userMapper;
        }
    
        @Override
        public List<User> userList() {
            return null;
        }
    }
  3. 編寫spring配置文件

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 指定掃描的包,即mapper包 -->
        <property name="basePackage" value="com.jh.mapper"/>
    </bean>
    
    <!-- 註冊UserServiceImpl到Spring -->
    <bean id="userService" class="com.jh.service.impl.UserServiceImpl">
        <!-- userMapper由MapperScannerConfigurer自動建立,並注入到UserServiceImpl -->
        <property name="userMapper" ref="userMapper"/>
    </bean>
  4. 測試

    @Test
    public void userList() throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = context.getBean("userService", UserService.class);
        List<User> userList = userService.userList();
        userList.forEach(System.out::println);
    }

【總結】 :整合到spring之後能夠徹底不要mybatis的配置文件,除了這些方式能夠實現整合以外,咱們還可使用註解來實現,這個等咱們後面學習SpringBoot的時候還會測試整合!

相關文章
相關標籤/搜索