Spring 整合 MyBatis

HuDu發表於2020-06-30

回顧MyBatis開發流程

首先回顧一下MyBatis的開發流程

  • 匯入 jar 包
    • junit
    • mybatis
    • mysql
    • spring相關
    • aop織入
    • mybatis-spring(new)
  • 配置xml檔案
  • 建立對應資料庫表的實體類
  • 建立介面和方法
  • 配置對應介面的xml檔案,繫結方法
  • 測試

整合思路

  • xml編寫資料來源DataSource
  • SqlSessionFactory
  • SqlSessionTemplate
  • 需要給介面加一個額外的實現類
  • 將自己寫的實現類注入到Spring中
  • 測試使用

專案整體架構

對應資料庫中的 user 表有一對應的 User pojo 類,欄位名如下。

public class User {
    private int id;
    private String name;
    private String pwd;
}

對應 pojo 類有對映介面 UserMapper

public interface UserMapper {
    List<User> selectById(Map<String,Integer> map);
}

對應UserMapper類有一個 XML 對映檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hudu.mapper.UserMapper">
    <select id="selectById" parameterType="map" resultType="user">
        select * from user
        <where>
            <if test="uid != null">
                id = #{uid}
            </if>
            <if test="uname != null">
                and name = #{uname}
            </if>
        </where>
    </select>
</mapper>

外部 properties 檔案

#db.properties檔案
#注意 mysql 8.0 之後 driver 為 com.mysql.cj.jdbc.Driver
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username=username
password=password

mybatis-config.xml 配置檔案,註釋掉的部分,包括 properties 引入外部檔案、environment 環境配置等都是可以通過 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>

<!--    <properties resource="db.properties"/>-->

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <package name="com.hudu.pojo"/>
    </typeAliases>

<!--        <environments default="development">-->
<!--            <environment id="development">-->
<!--                <transactionManager type="JDBC"/>-->
<!--                <dataSource type="POOLED">-->
<!--                    <property name="driver" value="${driver}"/>-->
<!--                    <property name="url" value="${url}"/>-->
<!--                    <property name="username" value="${username}"/>-->
<!--                    <property name="password" value="${password}"/>-->
<!--                </dataSource>-->
<!--            </environment>-->
<!--        </environments>-->
<!--        <mappers>-->
<!--            <mapper resource="com/hudu/mapper/UserMapper.xml"/>-->
<!--        </mappers>-->
</configuration>

三種Spring整合MyBatis的方式

  • 第一種,通過 SqlSessionTemplate

UserMapperImpl 繼承 UserMapper 介面,實現其中的方法。通過 Set 方法注入 SqlSessionTemplate,即SqlSession。

public class UserMapperImpl implements UserMapper {

    private SqlSessionTemplate sqlSession;

    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    public List<User> selectById(Map<String, Integer> map) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectById(map);
    }
}

配置spring-mybatis.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:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="szy10086"/>
    </bean>

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

        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/hudu/mapper/UserMapper.xml"/>
    </bean>

    <!--SqlSessionTemplate就是我們使用的SqlSession-->
    <bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--只能使用構造器注入sqlSessionFactory,因為它沒有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

    <bean id="userMapper" class="com.hudu.mapper.UserMapperImpl">
        <property name="sqlSession" ref="SqlSession"/>
    </bean>

</beans>

測試

@Test
public void test2() {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-mapper.xml");
    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
    HashMap<String,Integer> map = new HashMap<String, Integer>();
    map.put("uid",1);
    List<User> users = userMapper.selectById(map);
    for (User user : users) {
        System.out.println(user);
    }

}
  • 第二種,主要改變在 Impl 實現類和 XML 配置檔案

原先是通過 SqlSessionTemplate,這裡通過繼承 SqlSessionDaoSupport,裡面有 getSqlSession 這個方法,可以直接獲取到 SqlSession。

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
    public List<User> selectById(Map<String, Integer> map) {

        return getSqlSession().getMapper(UserMapper.class).selectById(map);
    }
}
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
    public List<User> selectById(Map<String, Integer> map) {

        return getSqlSession().getMapper(UserMapper.class).selectById(map);
    }
}

配置 xml 檔案,可以對比上兩種方法,檢視他們的不同之處。

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="szy10086"/>
    </bean>

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

        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/hudu/mapper/UserMapper.xml"/>
    </bean>

    <bean id="userMapper" class="com.hudu.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
  • 第三種,通過包自動掃描
    這就不需要再建立 Impl 實現類了,只需要在 xml 檔案中新增包掃描,底層就會自動幫你做之前的事情。
<!--配置dao按口掃描包,動態的實現了Dao介面可以注入到Spring容器中! -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--注入sqlSessionFactory-->
        <property name="basePackage" value="com.hudu.mapper"/>
    </bean>

測試

@Test
public void test2() {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-mapper.xml");
    UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
    HashMap<String,Integer> map = new HashMap<String, Integer>();
    map.put("uid",1);
    List<User> users = userMapper.selectById(map);
    for (User user : users) {
        System.out.println(user);
    }

}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章