文章目錄
1、引言
本文一共提供了四種Spring整合MyBatis的方式分別是:
- 常規整合
- 使用
SqlSessionTemplate
整合 - 使用
SqlSessionDaoSupport
整合 - 使用
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、項目結構
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文件,看起來很簡潔
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、總結
- 第一種整合方式比較常見也比較常用
- 第二第三種整合方式比較靈活,也可以結合第一種方式使用
- 第四種方式配置比較少,但是工作中實際上是不常見的,因爲xml文件更加清晰,並且修改起來比修改代碼更加方便。