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文件更加清晰,并且修改起来比修改代码更加方便。

猜你喜欢

转载自blog.csdn.net/u011047968/article/details/106246609