SpringMVC學習(六)——Spring四種方式整合MyBatis

1、引言

本文一共提供了四種Spring整合MyBatis的方式分別是:

  1. 常規整合
  2. 使用SqlSessionTemplate整合
  3. 使用SqlSessionDaoSupport整合
  4. 使用org.apache.ibatis.annotations提供註解方式整合
    本文的相關源碼請參考:
    chapter-6-springmvc-mybatis1(常規整合)
    chapter-6-springmvc-mybatis2(使用SqlSessionTemplate整合)
    chapter-6-springmvc-mybatis3( 使用SqlSessionDaoSupport整合)
    chapter-6-springmvc-mybatis4(使用org.apache.ibatis.annotations提供註解方式整合)
    https://gitee.com/leo825/spring-framework-learning-example.git

2、Spring整合Mybatis

建表語句

-- 創建一個簡單的用戶表
DROP TABLE IF EXISTS USER_INFO;

CREATE TABLE USER_INFO (
	ID INT (11) PRIMARY KEY AUTO_INCREMENT COMMENT '用戶ID',
	NAME VARCHAR (20) COMMENT '用戶名稱',
	GENDER VARCHAR (2) COMMENT '用戶性別:0女1男',
	AGE VARCHAR (3) COMMENT '用戶年齡',
	REMARKS VARCHAR (100) COMMENT '備註信息'
) COMMENT = '用戶信息表'

pom.xml配置相同

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-framework-learning-parents</artifactId>
        <groupId>spring-framework-learning-example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>chapter-6-springmvc-mybatis1</artifactId>
    <packaging>war</packaging>
    <description>Spring集成mybatis</description>

    <!-- 工程展示名稱 -->
    <name>chapter-6-springmvc-mybatis1</name>
    <!-- 工程的地址 -->
    <url>https://gitee.com/leo825/spring-framework-learning-example.git</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>4.3.25.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- springmvc核心依賴 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- aspectJ AOP 織入器 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <!--mybatis-spring適配器 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!-- mybatis ORM框架 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--c3p0 連接池 -->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!-- tomcat中存在此web運行的jar包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <!-- 使用SpringJDBC進行數據庫配置 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- mysql數據庫連接的驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>


        <!-- Spring-test配合junit使用 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- SpirngMVC支持文件上傳的工具包 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>

        <!--log4j2支持集成日誌框架-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>chapter-6-springmvc-mybatis1</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>
2.1、常規整合
2.1.1、項目的結構

項目結構

2.1.2、applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:cache="http://www.springframework.org/schema/cache" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.0.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
     http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">


    <!--1 引入屬性文件,在配置中佔位使用 -->
    <context:property-placeholder location="classpath*:application.properties"/>

    <!--2 配置C3P0數據源 -->
    <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <!--驅動類名 -->
        <property name="driverClass" value="${datesource.driverClassName}"/>
        <!-- url -->
        <property name="jdbcUrl" value="${datesource.url}"/>
        <!-- 用戶名 -->
        <property name="user" value="${datesource.username}"/>
        <!-- 密碼 -->
        <property name="password" value="${datesource.password}"/>
        <!-- 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數  -->
        <property name="acquireIncrement" value="5"></property>
        <!-- 初始連接池大小 -->
        <property name="initialPoolSize" value="10"></property>
        <!-- 連接池中連接最小個數 -->
        <property name="minPoolSize" value="5"></property>
        <!-- 連接池中連接最大個數 -->
        <property name="maxPoolSize" value="20"></property>
    </bean>

    <!--3 會話工廠bean sqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 數據源 -->
        <property name="dataSource" ref="datasource"></property>
        <!-- 別名 -->
        <property name="typeAliasesPackage" value="com.leo.model"></property>
        <!-- sql映射文件路徑 -->
        <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"></property>
    </bean>

    <!--4 自動掃描對象關係映射 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定會話工廠,如果當前上下文中只定義了一個則該屬性可省去 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <!-- 指定要自動掃描接口的基礎包,實現接口 -->
        <property name="basePackage" value="com.leo.mapper"></property>
    </bean>

    <!--5 聲明式事務管理 -->
    <!--定義事物管理器,由spring管理事務 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    <!--支持註解驅動的事務管理,指定事務管理器 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <!--6 容器自動掃描IOC組件  -->
    <context:component-scan base-package="com.leo"></context:component-scan>

    <!--7 aspectj支持自動代理實現AOP功能 -->
    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
</beans>
2.1.3、UserInfoMapper接口的定義
public interface UserInfoMapper {
    /**
     * 增加用戶信息
     * @param userInfo
     */
    void insertUserInfo(UserInfo userInfo);

    /**
     * 刪除用戶信息
     * @param id
     */
    void deleteUserInfo(Integer id);

    /**
     * 修改用戶信息
     * @param newUserInfo
     */
    void updateUserInfo(UserInfo newUserInfo);

    /**
     * 查詢用戶信息
     * @return
     */
    List<UserInfo> getUserInfoList();
}
2.1.4、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.leo.mapper.UserInfoMapper">

    <sql id="BaseSql">
        ID id, NAME name, GENDER gender,AGE age,REMARKS remarks
    </sql>

    <!-- 增加 -->
    <insert id="insertUserInfo" parameterType="com.leo.model.UserInfo">
      INSERT INTO USER_INFO(NAME,GENDER,AGE,REMARKS) VALUES(#{name},#{gender},#{age},#{remarks})
    </insert>

    <!-- 刪除 -->
    <delete id="deleteUserInfo" parameterType="integer">
        DELETE FROM USER_INFO WHERE ID=#{ID}
    </delete>

    <!-- 修改 -->
    <update id="updateUserInfo" parameterType="com.leo.model.UserInfo">
        UPDATE USER_INFO
        <if test="name!=null">
            SET NAME = #{name},
        </if>
        <if test="gender!=null">
            SET GENDER = #{gender},
        </if>
        <if test="age!=null">
            SET AGE = #{age},
        </if>
        <if test="remarks!=null">
            SET REMARKS = #{remarks},
        </if>
        WHERE ID=#{ID}
    </update>

    <select id="getUserInfoList" resultType="com.leo.model.UserInfo">
        SELECT
        <include refid="BaseSql"/>
        FROM USER_INFO WHERE 1=1
    </select>

</mapper>
2.1.5、UserService定義和實現
public interface UserInfoService {
    /**
     * 增加用戶信息
     * @param userInfo
     */
    void insertUserInfo(UserInfo userInfo);

    /**
     * 刪除用戶信息
     * @param id
     */
    void deleteUserInfo(Integer id);

    /**
     * 修改用戶信息
     * @param newUserInfo
     */
    void updateUserInfo(UserInfo newUserInfo);

    /**
     * 查詢用戶信息
     * @return
     */
    List<UserInfo> getUserInfoList();
}

實現層

@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Resource
    UserInfoMapper userInfoMapper;

    @Override
    public void insertUserInfo(UserInfo userInfo) {
        userInfoMapper.insertUserInfo(userInfo);
    }

    @Override
    public void deleteUserInfo(Integer id) {
        userInfoMapper.deleteUserInfo(id);
    }

    @Override
    public void updateUserInfo(UserInfo newUserInfo) {
        userInfoMapper.updateUserInfo(newUserInfo);
    }

    @Override
    public List<UserInfo> getUserInfoList() {
        return userInfoMapper.getUserInfoList();
    }
}

2.2、使用SqlSessionTemplate整合
2.2.1、項目結構

結構

2.2.2、新增加sqlSessionTemplate配置

在applicationContext.xml中新增

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
2.2.3、實現UserInfoMapper接口

這種方式,UserMapper.xml和第一個一樣,不在重複贅述了,需要自己通過sqlSessionTemplate去實現數據庫操作的增、刪、改、查。
UserInfoMapperImpl.java

@Service
public class UserInfoMapperImpl implements UserInfoMapper {
    
    @Autowired
    SqlSessionTemplate sqlSessionTemplate;
    
    @Override
    public void insertUserInfo(UserInfo userInfo) {
        sqlSessionTemplate.insert("com.leo.mapper.UserInfoMapper.insertUserInfo", userInfo);
    }

    @Override
    public void deleteUserInfo(Integer id) {
        sqlSessionTemplate.delete("com.leo.mapper.UserInfoMapper.deleteUserInfo", id);
    }

    @Override
    public void updateUserInfo(UserInfo newUserInfo) {
        sqlSessionTemplate.update("com.leo.mapper.UserInfoMapper.updateUserInfo", newUserInfo);
    }

    @Override
    public List<UserInfo> getUserInfoList() {
        return sqlSessionTemplate.selectList("com.leo.mapper.UserInfoMapper.getUserInfoList");
    }
}
2.3、使用SqlSessionDaoSupport整合
2.3.1、項目結構

項目結構3

2.3.2、新增BaseMapper配置

這塊是定義一個父類,這個父類繼承SqlSessionDaoSupport,然後覆蓋這個父類的etSqlSessionFactory將我們的sqlSessionFactory注入進來,這樣我們的子類只要繼承這個父類就自動把sqlSessionFactory注進來了。

public class BaseMapperImpl extends SqlSessionDaoSupport{

	//初始化注入sqlSessionFactory
    BaseMapperImpl(SqlSessionFactory sqlSessionFactory){
        super.setSqlSessionFactory(sqlSessionFactory);
    }
}

然後在applicationContext.xml中增加配置

    <!-- 定義一個父類,並且將sqlSessionFactory注入,子類繼承這個父類-->
    <bean id="baseMapper" class="com.leo.mapper.impl.BaseMapperImpl" lazy-init="false">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
2.3.3、實現UserInfoMapper接口

繼承我們的BaseMapperImpl,並實現UserInfoMapper

@Service
public class UserInfoMapperImpl extends BaseMapperImpl implements UserInfoMapper {

    UserInfoMapperImpl(SqlSessionFactory sqlSessionFactory) {
        super(sqlSessionFactory);
    }

    @Override
    public void insertUserInfo(UserInfo userInfo) {
        this.getSqlSession().insert("com.leo.mapper.UserInfoMapper.insertUserInfo", userInfo);
    }

    @Override
    public void deleteUserInfo(Integer id) {
        this.getSqlSession().delete("com.leo.mapper.UserInfoMapper.deleteUserInfo", id);
    }

    @Override
    public void updateUserInfo(UserInfo newUserInfo) {
        this.getSqlSession().update("com.leo.mapper.UserInfoMapper.updateUserInfo", newUserInfo);
    }

    @Override
    public List<UserInfo> getUserInfoList() {
        return this.getSqlSession().selectList("com.leo.mapper.UserInfoMapper.getUserInfoList");
    }
}

如果不使用這種方式,那麼我們的每一個Mapper接口的實現類寫到配置文件中然後將sqlSessionFactory注入。一個Mapper就要寫一個,多個的話需要配置很多

    <bean id="userInfoMapper" class="com.leo.mapper.impl.UserInfoMapperImpl">
       <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

相應的實現類UserInfoMapperImpl,其他代碼跟上面一樣,所以省略了。

@Service
public class UserInfoMapperImpl extends SqlSessionDaoSupport implements UserInfoMapper {
2.4、使用org.apache.ibatis.annotations提供註解方式整合
2.4.1、項目結構

結構圖中,少了Mapper的實現類,也少了Mapper.xml文件,看起來很簡潔
結構圖4

2.4.2、關鍵配置

配置文件的org.mybatis.spring.mapper.MapperScannerConfigurer不能少,注意要掃描的Mapper接口的包名basePackage,不需要配置Mapper.xml路徑了,通過配置實現不需要了。

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--指定會話工廠,如果當前上下文中只定義了一個則該屬性可省去 -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 指定要自動掃描接口的基礎包,實現接口 -->
        <property name="basePackage" value="com.leo.mapper"/>
    </bean>
2.4.3、UserInfoMapper的定義

UserInfoMapper.java定義如下:

public interface UserInfoMapper {
    /**
     * 增加用戶信息
     *
     * @param userInfo
     */
    @Insert("INSERT INTO USER_INFO(NAME,GENDER,AGE,REMARKS) VALUES(#{name},#{gender},#{age},#{remarks})")
    void insertUserInfo(UserInfo userInfo);

    /**
     * 刪除用戶信息
     *
     * @param id
     */
    @Delete("DELETE FROM USER_INFO WHERE ID=#{ID}")
    void deleteUserInfo(Integer id);

    /**
     * 修改用戶信息
     *
     * @param newUserInfo
     */
    @Update("UPDATE USER_INFO SET NAME = #{name},GENDER = #{gender},AGE = #{age},REMARKS = #{remarks}")
    void updateUserInfo(UserInfo newUserInfo);

    /**
     * 查詢用戶信息
     *
     * @return
     */
    @Select("SELECT ID id, NAME name, GENDER gender,AGE age,REMARKS remarks FROM USER_INFO WHERE 1=1")
    List<UserInfo> getUserInfoList();
}

通過org.apache.ibatis.annotations提供給我們的註解,加上sql語句就可以實現以前在Mapper.xml配置中實現的功能。

3、總結

  1. 第一種整合方式比較常見也比較常用
  2. 第二第三種整合方式比較靈活,也可以結合第一種方式使用
  3. 第四種方式配置比較少,但是工作中實際上是不常見的,因爲xml文件更加清晰,並且修改起來比修改代碼更加方便。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章