Spring整合MyBatis实现用户CRUD学习笔记
一、学习目标
二、项目核心结构梳理
src/
├── main/
│ ├── java/
│ │ └── com/sy/
│ │ ├── pojo/ // 实体类(User)
│ │ ├── mapper/ // MyBatis映射接口(UserMapper)
│ │ ├── service/ // 服务层接口(UserService)
│ │ │ └── impl/ // 服务层实现类(UserServiceImpl)
│ │ └── utils/ // MyBatis工具类(非Spring整合时用)
│ └── resources/
│ ├── com/sy/mapper/ // MyBatis映射文件(UserMapper.xml)
│ ├── db.properties // 数据库连接配置
│ ├── mybatis-config.xml // MyBatis基础配置
│ ├── log4j.properties // 日志配置
│ └── applicationContext.xml // Spring核心配置(整合MyBatis关键)
└── test/
└── java/com/sy/test/
├── UserMapperTest.java // 纯MyBatis测试
└── UserMapper_SpringTest.java // Spring整合测试
三、核心配置文件解析
1. 数据库配置(db.properties)
作用:统一管理数据库连接参数,解耦配置与代码
# MySQL驱动(8.0+版本用com.mysql.cj.jdbc.Driver,5.x用com.mysql.jdbc.Driver)
jdbc.driver=com.mysql.cj.jdbc.Driver
# 数据库连接URL(指定库名、编码、时区、关闭SSL等)
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true
jdbc.username=root
jdbc.password=akitomiya1.
2. MyBatis基础配置(mybatis-config.xml)
作用:配置MyBatis核心特性(日志、延迟加载、缓存、别名等)
<?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>
<!– 日志实现(log4j) –>
<settings>
<setting name="logImpl" value="log4j"/>
<setting name="lazyLoadingEnabled" value="true"/> <!– 全局延迟加载 –>
<setting name="aggressiveLazyLoading" value="false"/> <!– 按需加载 –>
<setting name="cacheEnabled" value="true"/> <!– 开启二级缓存 –>
</settings>
<!– 实体类别名(扫描包方式,简化Mapper.xml中类型书写) –>
<typeAliases>
<package name="com.sy.pojo"/> <!– 包下所有类别名默认为类名小写 –>
</typeAliases>
<!– 数据库环境(Spring整合后,此部分移到applicationContext.xml) –>
<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>
<!– Mapper映射文件扫描(Spring整合后移到applicationContext.xml) –>
<mappers>
<package name="com.sy.mapper"/>
</mappers>
</configuration>
3. Spring核心配置(applicationContext.xml)
核心:整合MyBatis+数据源+事务管理,是Spring与MyBatis整合的关键
关键配置项:
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
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/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!– 1. 注解扫描(扫描Service/Controller等注解) –>
<context:component-scan base-package="com.sy"></context:component-scan>
<!– 2. 加载数据库配置文件 –>
<context:property-placeholder location="db.properties"></context:property-placeholder>
<!– 3. 配置数据源(C3P0连接池) –>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!– 4. 配置SqlSessionFactory(MyBatis核心工厂,Spring整合后由Spring管理) –>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property> <!– 注入数据源 –>
<property name="mapperLocations" value="classpath:com/sy/mapper/*.xml"></property> <!– Mapper.xml扫描 –>
<property name="typeAliasesPackage" value="com.sy.pojo"></property> <!– 实体类别名 –>
<!– MyBatis特性配置(替代mybatis-config.xml的settings) –>
<property name="configuration">
<bean class="org.apache.ibatis.session.Configuration">
<property name="mapUnderscoreToCamelCase" value="true"></property> <!– 驼峰命名映射 –>
<property name="lazyLoadingEnabled" value="true"></property> <!– 延迟加载 –>
<property name="aggressiveLazyLoading" value="false"></property>
<property name="cacheEnabled" value="true"></property> <!– 二级缓存 –>
</bean>
</property>
</bean>
<!– 5. Mapper接口扫描(自动创建Mapper实现类,注入Spring容器) –>
<bean id="scannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sy.mapper"></property>
</bean>
<!– 6. 事务管理器(基于数据源的JDBC事务) –>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!– 7. 事务通知(配置事务规则) –>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!– 查询方法:只读事务 –>
<tx:method name="find*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<!– 增删改方法:非只读事务 –>
<tx:method name="insert*"/>
<tx:method name="update*"/>
<tx:method name="delete*"/>
<!– 其他方法默认事务 –>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!– 8. AOP配置(事务切面与切入点结合) –>
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* com.sy.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"></aop:advisor>
</aop:config>
</beans>
四、核心代码实现
1. 实体类(User.java)
使用Lombok简化get/set/构造方法:
package com.sy.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data // 生成get/set/toString等
@NoArgsConstructor // 无参构造
@AllArgsConstructor // 全参构造
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
}
2. MyBatis映射层(Mapper)
(1)UserMapper接口(无需实现类,MyBatis自动代理)
package com.sy.mapper;
import com.sy.pojo.User;
import java.util.List;
public interface UserMapper {
// 根据ID查询
User findUserById(int id);
// 查询所有
List<User> findAllUser();
// 新增
int insertUser(User user);
// 修改
int updateUserById(User user);
// 删除
int deleteUserById(int id);
}
(2)UserMapper.xml(SQL映射文件)
<?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.sy.mapper.UserMapper">
<!– 根据ID查询 –>
<select id="findUserById" parameterType="integer" resultType="user">
select * from t_user where id=#{id}
</select>
<!– 查询所有 –>
<select id="findAllUser" resultType="user">
select * from t_user
</select>
<!– 新增(获取自增ID) –>
<insert id="insertUser" parameterType="user">
<selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO `t_user`(`username`, `password`, `age`, `sex`, `email`)
VALUES (#{username}, #{password}, #{age}, #{sex}, #{email})
</insert>
<!– 修改 –>
<update id="updateUserById">
UPDATE `t_user` SET `email` = #{email} WHERE `id` = #{id}
</update>
<!– 删除 –>
<delete id="deleteUserById">
DELETE FROM `t_user` WHERE `id` = #{id}
</delete>
</mapper>
3. 服务层(Service)
(1)UserService接口
package com.sy.service;
import com.sy.pojo.User;
import java.util.List;
public interface UserService {
User findUserById(int id);
List<User> findAllUser();
int insertUser(User user);
int updateUserById(User user);
int deleteUserById(int id);
}
(2)UserServiceImpl实现类(Spring注解管理)
package com.sy.service.impl;
import com.sy.mapper.UserMapper;
import com.sy.pojo.User;
import com.sy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("userService") // 注入Spring容器
public class UserServiceImpl implements UserService {
@Autowired // 自动注入Mapper(Spring扫描Mapper后生成的代理对象)
private UserMapper userMapper;
@Override
public User findUserById(int id) {
return userMapper.findUserById(id);
}
@Override
public List<User> findAllUser() {
return userMapper.findAllUser();
}
@Override
public int insertUser(User user) {
return userMapper.insertUser(user);
}
@Override
public int updateUserById(User user) {
return userMapper.updateUserById(user);
}
@Override
public int deleteUserById(int id) {
return userMapper.deleteUserById(id);
}
}
4. 纯MyBatis工具类(MyBatisUtils.java)
非Spring整合时使用,手动管理SqlSession:
package com.sy.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
// 全局唯一SqlSessionFactory(静态初始化,只加载一次)
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("MyBatis配置文件加载失败!", e);
}
}
// 获取SqlSession(自动提交事务)
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true);
}
// 关闭SqlSession
public static void closeSqlSession(SqlSession sqlSession) {
if (sqlSession != null) {
sqlSession.close();
}
}
}
五、测试环节
1. 纯MyBatis测试(UserMapperTest.java)
package com.sy.test;
import com.sy.mapper.UserMapper;
import com.sy.pojo.User;
import com.sy.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
public class UserMapperTest {
@Test
public void findUserById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
System.out.println(user);
MyBatisUtils.closeSqlSession(sqlSession);
}
}
2. Spring整合MyBatis测试(UserMapper_SpringTest.java)
使用SpringJUnit4ClassRunner,自动加载Spring容器:
package com.sy.test;
import com.sy.pojo.User;
import com.sy.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class) // Spring测试运行器
@ContextConfiguration(value = "classpath:applicationContext.xml") // 加载Spring配置
public class UserMapper_SpringTest {
@Autowired // 自动注入Service
private UserService userService;
// 根据ID查询
@Test
public void findUserById(){
User user = userService.findUserById(1);
System.out.println(user);
}
// 查询所有
@Test
public void findAllUser(){
List<User> userList = userService.findAllUser();
for (User user : userList) {
System.out.println(user);
}
}
// 新增
@Test
public void insertUser(){
User user = new User();
// 手动设置user属性…
int i = userService.insertUser(user);
if (i > 0){
System.out.println("新增成功");
}
}
// 修改
@Test
public void updateUserById(){
User user = new User();
user.setId(5);
user.setEmail("baby@126.com");
int i = userService.updateUserById(user);
if (i > 0){
System.out.println("修改成功");
}
}
// 删除
@Test
public void deleteUserById(){
int i = userService.deleteUserById(5);
if (i > 0){
System.out.println("删除成功");
}
}
}
六、关键知识点总结
1. Spring整合MyBatis核心步骤
- 注解扫描 + 加载配置文件
- 数据源(C3P0/Druid)
- SqlSessionFactory(注入数据源、Mapper路径、MyBatis特性)
- Mapper扫描(自动创建Mapper代理对象)
- 事务管理器 + 事务通知 + AOP切面
2. 事务管理关键点
- 事务管理器:DataSourceTransactionManager(基于JDBC事务)
- 事务通知:通过tx:advice配置不同方法的事务规则(查询只读、增删改非只读)
- AOP切面:将事务规则应用到Service实现类的所有方法
3. MyBatis特性
- 别名配置:扫描包方式简化类型书写
- 驼峰命名映射:mapUnderscoreToCamelCase(数据库字段user_name映射到实体类userName)
- 延迟加载:按需加载关联数据,提升性能
- 二级缓存:开启后,Mapper级别缓存,减少数据库查询
4. 核心区别(纯MyBatis vs Spring整合MyBatis)
| SqlSession管理 | 手动通过工具类获取/关闭 | Spring自动管理 |
| 依赖注入 | 手动创建Mapper | @Autowired自动注入 |
| 事务管理 | 手动调用commit/rollback | Spring声明式事务(AOP) |
| 配置方式 | 依赖mybatis-config.xml | 核心配置移到applicationContext.xml |


