SpringBoot - 整合MyBatis配置版(XML)并开启事务

本文介绍SpringBoot整合MyBatis配置版的具体步骤,包括MyBatis全局配置文件设置、SQL映射文件编写及Controller层测试。此外,还讨论了SpringBoot中的事务管理和MySQL8版本的兼容性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上一篇SpringBoot整合MyBatis注解版示例,这里简要学习MyBatis配置版如何使用。

项目中数据源、pojo、mapper等和上篇博客中一致。


【1】MyBatis的相关配置

有三个地方:MyBatis的全局配置文件,与mapper关联的sql xml配置文件以及在application.yml引入MyBatis的配置文件。

① 项目结构如下图:

这里写图片描述


② MyBatis的全局配置文件:mybatis-config.xml

  • 根据需要自定义配置
<?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>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

③ 与mapper类相关联的SQL配置文件

  • 这里以EmployeeMapper.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.springboot.datasource.mapper.EmployeeMapper">
   <!--    public Employee getEmpById(Integer id);

    public void insertEmp(Employee employee);-->
    <select id="getEmpById" resultType="com.atguigu.springboot.bean.Employee">
        SELECT * FROM employee WHERE id=#{id}
    </select>

    <insert id="insertEmp">
        INSERT INTO employee(lastName,email,gender,d_id) VALUES (#{lastName},#{email},#{gender},#{dId})
    </insert>
</mapper>

④ 在application.yml中对MyBatis进行配置

这个可以说是最重要的!

mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

这里说明一下mapper-locations中的配置:

classpath:/xxx 和 classpath:xxx是一样的 。
.
classpath:xxx 和 classpath*:xxx是不一样的,前者表示引入一个,后者表示引入多个。
.
而且classpath不仅包含class路径,还包括jar文件中(class路径)进行查找。
.
classpath:mapper/**/
.xml:查找类路径下mapper包下面所有子包中的所有xml。


【2】编写Controller进行测试

测试方法如下:

	@GetMapping("/emp/{id}")
    public Employee getEmp(@PathVariable("id") Integer id){
        return employeeMapper.getEmpById(id);
    }

测试结果如下:

这里写图片描述


【3】SpringBoot中对事务的支持

spring Boot 使用事务非常简单,首先在主程序上面使用注解 @EnableTransactionManagement开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。


@SpringBootApplication
@MapperScan({"com.XX.mapper","com.XX.dao"})
@EnableJms //ActiveMQ
@EnableCaching // redis-cache
@EnableTransactionManagement
@ServletComponentScan
public class HhProvinceApplication {

	public static void main(String[] args) {
		SpringApplication.run(HhProvinceApplication.class, args);
	}
}

关于事务管理器,不管是JPA还是JDBC等都实现自接口 PlatformTransactionManager 。如果你添加的是 spring-boot-starter-jdbc 依赖,框架会默认注入 DataSourceTransactionManager 实例。如果你添加的是 spring-boot-starter-data-jpa 依赖,框架会默认注入 JpaTransactionManager 实例。

你可以在启动类中添加如下方法,Debug测试,就能知道自动注入的是 PlatformTransactionManager 接口的哪个实现类。

@Bean
 public Object testBean(PlatformTransactionManager platformTransactionManager) {
     System.out.println(">>>>>>>>>>" + platformTransactionManager.getClass().getName());
     return new Object();
 }

由于mybatis-spring-boot-starter依赖了spring-boot-starter-jdbc,SpringBoot将会默认为我们注入DataSourceTransactionManager 。

在这里插入图片描述

Spring中事务支持默认是数据库产品的事务实现,如这里使用的MySQL。


【4】SpringBoot2.0与MySQL8

在SpringBoot2.0等更高版本时,如果MySQL驱动使用的是8版本,那么可能会出现如下异常:

java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized

并且还可能提示你驱动需要更换为如下:

com.mysql.cj.jdbc.Driver

此时只需要更改为如下则可:

spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

详细讲解参考博文:一文读懂Spring事务与MySQL事务和锁

<think>我们正在处理一个关于在Spring Boot 3项目中整合MyBatis-Plus实现多表联合查询的问题。根据用户需求,我们需要完成以下步骤: 1. 整合MyBatis-Plus到Spring Boot 3项目。 2. 实现多表联合查询的功能。 参考已有的引用信息,我们可以得到一些整合MyBatis-Plus的基本步骤和注意事项。但是,由于用户要求实现多表联合查询,我们需要特别注意MyBatis-Plus在处理多表查询时的方案,因为MyBatis-Plus主要专注于单表操作,多表查询通常需要自定义SQL。 ### 步骤1:创建Spring Boot 3项目添加依赖 首先,我们需要创建一个Spring Boot 3项目(使用Java 17或更高本),在`pom.xml`中添加MyBatis-Plus的Spring Boot Starter依赖。 根据引用[3]的提示,我们只需要添加`mybatis-plus-boot-starter`依赖,不要同时添加`mybatis-spring-boot-starter`(因为前者已经包含了必要的依赖)。 ```xml <dependencies> <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MyBatis-Plus Starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新本</version> <!-- 请使用与Spring Boot 3兼容的本,例如3.5.0以上 --> </dependency> <!-- 数据库驱动,例如MySQL --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <!-- Lombok(可选) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> ``` 注意:请确保使用与Spring Boot 3兼容的MyBatis-Plus本(目前推荐3.5.0以上)。 ### 步骤2:配置数据源 在`application.yml`或`application.properties`中配置数据库连接信息。例如: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver # MyBatis-Plus配置 mybatis-plus: configuration: map-underscore-to-camel-case: true # 开启驼峰命名自动映射 # 可以配置mapper.xml的位置,如果使用注解方式则不需要 # mapper-locations: classpath:mapper/*.xml # 配置日志 global-config: db-config: id-type: auto # 主键自增策略 ``` ### 步骤3:创建实体类和Mapper接口 假设我们有两个表:`user`和`order`,一个用户可以有多个订单。我们需要创建两个实体类:`User`和`Order`。 **User.java** ```java import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.List; @Data @TableName("user") public class User { @TableId private Long id; private String name; private Integer age; private String email; // 非数据库字段,用于关联查询结果 @TableField(exist = false) private List<Order> orders; } ``` **Order.java** ```java import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data @TableName("order") public class Order { @TableId private Long id; private String orderNo; private Long userId; private Double amount; } ``` 然后,为每个实体创建Mapper接口,继承MyBatis-Plus的`BaseMapper`。 **UserMapper.java** ```java import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import com.example.demo.entity.User; @Mapper public interface UserMapper extends BaseMapper<User> { // 自定义方法:查询用户及其订单(多表查询) User selectUserWithOrders(Long userId); } ``` **OrderMapper.java** ```java import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import com.example.demo.entity.Order; @Mapper public interface OrderMapper extends BaseMapper<Order> { } ``` ### 步骤4:实现多表联合查询 由于MyBatis-Plus本身不直接支持多表联合查询,我们需要自定义SQL语句来实现。这里有两种方式: 1. 使用XML文件编写SQL。 2. 使用注解方式编写SQL。 这里我们使用XML方式(因为多表查询SQL可能较长,使用XML更清晰)。 在`resources/mapper`目录下创建`UserMapper.xml`文件: ```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.example.demo.mapper.UserMapper"> <resultMap id="UserWithOrdersResultMap" type="com.example.demo.entity.User"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="age" property="age"/> <result column="email" property="email"/> <!-- 一对多关联:订单 --> <collection property="orders" ofType="com.example.demo.entity.Order"> <id column="order_id" property="id"/> <result column="order_no" property="orderNo"/> <result column="user_id" property="userId"/> <result column="amount" property="amount"/> </collection> </resultMap> <select id="selectUserWithOrders" resultMap="UserWithOrdersResultMap"> SELECT u.id, u.name, u.age, u.email, o.id as order_id, o.order_no, o.user_id, o.amount FROM user u LEFT JOIN order o ON u.id = o.user_id WHERE u.id = #{userId} </select> </mapper> ``` 注意:在`application.yml`中配置了`mybatis-plus.mapper-locations=classpath:mapper/*.xml`,这样MyBatis才能找到这个XML文件。 ### 步骤5:编写Service和Controller 创建UserService和UserController来调用这个多表查询方法。 **UserService.java** ```java import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserMapper userMapper; public User getUserWithOrders(Long userId) { return userMapper.selectUserWithOrders(userId); } } ``` **UserController.java** ```java 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.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/user/{userId}") public User getUserWithOrders(@PathVariable Long userId) { return userService.getUserWithOrders(userId); } } ``` ### 步骤6:启动类添加Mapper扫描 在Spring Boot启动类上添加`@MapperScan`注解,指定Mapper接口所在的包。 ```java import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.demo.mapper") // 替换成你的Mapper包路径 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` ### 注意事项 1. **表名和字段名映射**:确保数据库表名和字段名与实体类中的`@TableName`和`@TableField`(如果需要)匹配,或者开启驼峰命名转换(配置`map-underscore-to-camel-case: true`)。 2. **SQL注入**:使用MyBatis-Plus的条件构造器时,注意防止SQL注入。在自定义SQL中,使用`#{}`而不是`${}`来防止注入。 3. **性能问题**:多表查询尤其是连接查询可能影响性能,特别是数据量大时。注意合理设计查询和索引。 ### 总结 以上就是在Spring Boot 3中整合MyBatis-Plus实现多表联合查询的完整步骤。我们通过自定义SQL的方式实现了多表查询,利用MyBatis的`resultMap`进行结果映射。MyBatis-Plus提供了强大的单表操作能力,而多表查询则通过MyBatis的原生特性实现,两者结合可以满足大部分业务需求。 §§相关问题§§ 1. 如何在MyBatis-Plus中使用条件构造器进行复杂查询? 2. MyBatis-Plus如何实现分页查询? 3. 在Spring Boot中整合MyBatis-Plus时,如何处理事务?</think>### 在 Spring Boot 3 中整合 MyBatis-Plus 实现多表联合查询 #### 步骤 1:添加依赖 在 `pom.xml` 中添加 MyBatis-Plus 和数据库驱动依赖: ```xml <dependencies> <!-- MyBatis-Plus Starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.2</version> <!-- 确保与Spring Boot 3兼容 --> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> </dependencies> ``` > **注意**:不要同时添加 `mybatis-spring-boot-starter`,避免依赖冲突[^3]。 --- #### 步骤 2:配置数据源 在 `application.yml` 中配置数据库: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true # 开启驼峰命名映射 mapper-locations: classpath:mapper/*.xml # XML映射文件位置 ``` --- #### 步骤 3:创建实体类 假设有 `User` 和 `Order` 两个表: ```java // User.java @Data @TableName("user") public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; @TableField(exist = false) // 非数据库字段 private List<Order> orders; // 关联的订单 } ``` ```java // Order.java @Data @TableName("order") public class Order { @TableId(type = IdType.AUTO) private Long id; private String orderNo; private Long userId; // 关联用户ID } ``` --- #### 步骤 4:实现多表联合查询 ##### 方式 1:使用 XML 映射文件 1. **Mapper 接口**: ```java public interface UserMapper extends BaseMapper<User> { User selectUserWithOrders(@Param("userId") Long userId); } ``` 2. **XML 映射文件** (`resources/mapper/UserMapper.xml`): ```xml <select id="selectUserWithOrders" resultMap="UserWithOrdersResultMap"> SELECT u.*, o.id AS order_id, o.order_no FROM user u LEFT JOIN order o ON u.id = o.user_id WHERE u.id = #{userId} </select> <resultMap id="UserWithOrdersResultMap" type="User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <!-- 一对多映射 --> <collection property="orders" ofType="Order"> <id property="id" column="order_id"/> <result property="orderNo" column="order_no"/> </collection> </resultMap> ``` ##### 方式 2:使用注解 + Wrapper ```java @Select("SELECT u.*, o.id AS order_id, o.order_no " + "FROM user u LEFT JOIN order o ON u.id = o.user_id " + "${ew.customSqlSegment}") @ResultMap("UserWithOrdersResultMap") User selectUserWithOrders(@Param("ew") Wrapper wrapper); ``` --- #### 步骤 5:Service 层调用 ```java @Service public class UserService { @Autowired private UserMapper userMapper; public User getUserWithOrders(Long userId) { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("u.id", userId); return userMapper.selectUserWithOrders(wrapper); } } ``` --- #### 步骤 6:事务管理 在启动类添加注解: ```java @SpringBootApplication @MapperScan("com.example.mapper") // 扫描Mapper接口 @EnableTransactionManagement // 启用事务 public class Application { ... } ``` --- #### 关键注意事项 1. **实体类映射**:确保数据库字段名与实体类属性名匹配(开启驼峰命名映射)[^2]。 2. **SQL 注入防护**:使用 `#{}` 参数占位符,避免 `${}` 拼接 SQL[^2]。 3. **性能优化**:大数据量时启用分页: ```java Page<User> page = new Page<>(1, 10); userMapper.selectPage(page, wrapper); ``` 4. **多表查询限制**:MyBatis-Plus 的 `LambdaQueryWrapper` 主要用于单表操作,多表建议手写 SQL[^4]。 > 完整示例代码:[MyBatis-Plus 多表查询示例](https://github.com/baomidou/mybatis-plus-samples)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值