🎓博主介绍:Java、Python、js全栈开发 “多面手”,精通多种编程语言和技术,痴迷于人工智能领域。秉持着对技术的热爱与执着,持续探索创新,愿在此分享交流和学习,与大家共进步。
📖DeepSeek-行业融合之万象视界(附实战案例详解100+)
📖全栈开发环境搭建运行攻略:多语言一站式指南(环境搭建+运行+调试+发布+保姆级详解)
👉感兴趣的可以先收藏起来,希望帮助更多的人
SpringBoot整合MyBatis实战:手把手实现CRUD操作与多数据源切换
一、引言
在当今的软件开发领域,Spring Boot凭借其快速开发、简化配置等优势成为了Java开发的主流框架,而MyBatis作为一款优秀的持久层框架,以其灵活的SQL映射和简单易用的特点深受开发者喜爱。本文将带领技术人员详细了解如何在Spring Boot项目中整合MyBatis,并实现基本的CRUD(创建、读取、更新、删除)操作,同时还会介绍如何实现多数据源的切换。
二、项目环境搭建
2.1 创建Spring Boot项目
可以使用Spring Initializr(https://start.spring.io/ )来快速创建一个Spring Boot项目。在创建项目时,需要添加以下依赖:
- Spring Web
- MyBatis Framework
- MySQL Driver
在选择依赖完成后,点击“Generate”按钮下载项目压缩包,解压后导入到IDE中(如IntelliJ IDEA或Eclipse)。
2.2 配置数据库连接
在src/main/resources目录下找到application.properties文件,添加以下数据库连接配置:
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
将your_database_name、your_username和your_password替换为实际的数据库名、用户名和密码。
三、实现CRUD操作
3.1 创建实体类
在src/main/java目录下创建对应的实体类,例如创建一个User实体类:
package com.example.demo.entity;
public class User {
private Integer id;
private String name;
private Integer age;
// 构造函数、Getter和Setter方法
public User() {}
public User(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
3.2 创建Mapper接口
创建一个UserMapper接口,用于定义数据库操作方法:
package com.example.demo.mapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UserMapper {
// 查询所有用户
@Select("SELECT * FROM user")
List<User> getAllUsers();
// 根据ID查询用户
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(Integer id);
// 插入用户
@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);
// 更新用户
@Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
int updateUser(User user);
// 删除用户
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteUser(Integer id);
}
3.3 创建Service层
创建UserService接口和其实现类UserServiceImpl:
// UserService接口
package com.example.demo.service;
import com.example.demo.entity.User;
import java.util.List;
public interface UserService {
List<User> getAllUsers();
User getUserById(Integer id);
int insertUser(User user);
int updateUser(User user);
int deleteUser(Integer id);
}
// UserServiceImpl实现类
package com.example.demo.service.impl;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> getAllUsers() {
return userMapper.getAllUsers();
}
@Override
public User getUserById(Integer id) {
return userMapper.getUserById(id);
}
@Override
public int insertUser(User user) {
return userMapper.insertUser(user);
}
@Override
public int updateUser(User user) {
return userMapper.updateUser(user);
}
@Override
public int deleteUser(Integer id) {
return userMapper.deleteUser(id);
}
}
3.4 创建Controller层
创建UserController来处理HTTP请求:
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
// 获取所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
// 根据ID获取用户
@GetMapping("/{id}")
public User getUserById(@PathVariable Integer id) {
return userService.getUserById(id);
}
// 插入用户
@PostMapping
public int insertUser(@RequestBody User user) {
return userService.insertUser(user);
}
// 更新用户
@PutMapping
public int updateUser(@RequestBody User user) {
return userService.updateUser(user);
}
// 删除用户
@DeleteMapping("/{id}")
public int deleteUser(@PathVariable Integer id) {
return userService.deleteUser(id);
}
}
3.5 测试CRUD操作
启动Spring Boot应用程序,使用Postman或其他API测试工具对UserController的各个接口进行测试,验证CRUD操作是否正常。
四、实现多数据源切换
4.1 添加第二个数据源配置
在application.properties文件中添加第二个数据源的配置:
# 第二个数据源配置
spring.datasource.second.url=jdbc:mysql://localhost:3306/your_second_database_name?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.second.username=your_second_username
spring.datasource.second.password=your_second_password
spring.datasource.second.driver-class-name=com.mysql.cj.jdbc.Driver
同样,将相关信息替换为实际的值。
4.2 创建数据源配置类
创建DataSourceConfig类来配置多个数据源:
package com.example.demo.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.first", sqlSessionFactoryRef = "firstSqlSessionFactory")
public class DataSourceConfig {
// 主数据源
@Primary
@Bean(name = "firstDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource firstDataSource() {
return DataSourceBuilder.create().build();
}
// 第二个数据源
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
// 第一个数据源的SqlSessionFactory
@Primary
@Bean(name = "firstSqlSessionFactory")
public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/first/*.xml"));
return sessionFactory.getObject();
}
// 第二个数据源的SqlSessionFactory
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/second/*.xml"));
return sessionFactory.getObject();
}
}
4.3 创建动态数据源路由
创建DynamicDataSource类来实现动态数据源的切换:
package com.example.demo.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.Map;
public class DynamicDataSource extends AbstractRoutingDataSource {
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
4.4 创建数据源上下文持有者
创建DataSourceContextHolder类来保存当前使用的数据源:
package com.example.demo.config;
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
4.5 创建数据源切换注解
创建DataSourceSwitch注解,用于在方法上指定使用的数据源:
package com.example.demo.annotation;
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceSwitch {
String value() default "firstDataSource";
}
4.6 创建数据源切换切面
创建DataSourceSwitchAspect切面类,根据注解切换数据源:
package com.example.demo.aspect;
import com.example.demo.annotation.DataSourceSwitch;
import com.example.demo.config.DataSourceContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class DataSourceSwitchAspect {
@Before("@annotation(com.example.demo.annotation.DataSourceSwitch)")
public void before(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSourceSwitch dataSourceSwitch = method.getAnnotation(DataSourceSwitch.class);
if (dataSourceSwitch != null) {
DataSourceContextHolder.setDataSource(dataSourceSwitch.value());
}
}
@After("@annotation(com.example.demo.annotation.DataSourceSwitch)")
public void after(JoinPoint point) {
DataSourceContextHolder.clearDataSource();
}
}
4.7 使用数据源切换注解
在需要切换数据源的方法上添加@DataSourceSwitch注解,例如:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@DataSourceSwitch("secondDataSource")
public List<User> getUsersFromSecondDataSource() {
return userMapper.getAllUsers();
}
}
五、总结
通过以上步骤,我们完成了Spring Boot与MyBatis的整合,并实现了基本的CRUD操作和多数据源的切换。在实际开发中,我们可以根据业务需求灵活运用这些技术,提高系统的性能和可维护性。

1758

被折叠的 条评论
为什么被折叠?



