SpringBoot集成Mybatis可能会遇到的问题

SpringBoot之集成Mybatis踩的各种坑

0.概述

使用SpringBoot集成Mybatis曾经踩了各种坑,也花费了很久找解决方案才把坑填上.只是时间久了,很容易健忘,导致过一段时间就会出现,遇到同样的问题还是不得不花费时间去找解决方案.所以索性就一次把错误犯个遍,写一遍文章记录一下.

1.项目构建

使用SpringBoot搭建项目,由于是测试mybatis出现的错误,因此引入可以不引入web依赖.

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>demo</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>

        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
#mybatis:
  mapper-locations: classpath:/mapper/*Mapper.xml

mysql数据库

这是转出的sql文件内容

/*
 Navicat Premium Data Transfer

 Source Server         : test
 Source Server Type    : MySQL
 Source Server Version : 80027
 Source Host           : localhost:3306
 Source Schema         : test

 Target Server Type    : MySQL
 Target Server Version : 80027
 File Encoding         : 65001

 Date: 14/03/2022 09:30:54
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '李四', '123456');
INSERT INTO `user` VALUES (2, '朱六', '123zhuliu');

SET FOREIGN_KEY_CHECKS = 1;

实体类

package com.example.demo.entity;

import lombok.Data;

@Data
public class User {
    private Integer id;
    private String name;
    private String pwd;
}

Mapper

package com.example.demo.mapper;

import com.example.demo.entity.User;

public interface UserMapper {
    public User getUserById(Integer id);
}
<?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">
    <select id="getUserById" resultType="com.example.demo.entity.User">
        select * from user where id=#{id}
    </select>
</mapper>

Service

接口:

package com.example.demo.service;
import com.example.demo.entity.User;

public interface UserService {
    public User queryUserById(Integer id);
}

接口实现类:

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;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User queryUserById(Integer id) {
        return userMapper.getUserById(id);
    }
}

测试类

package com.example.demo;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class Test {
    @Autowired
    private UserService userService;
    @org.junit.jupiter.api.Test
    public void testById(){
        System.out.println("开始测试");
        User user = userService.queryUserById(1);
        System.out.println(user.toString());
    }
}

2.踩坑

2.1 pom.xml文件踩坑

第一个坑就是pom.xml文件没配置资源插件,导致target目录下只有UserMapper.java,没有UaerMapper.xml

此时会出现什么呢?

注释调pom.xml中相关代码:

image-20220314094259603

清理项目后重新编译运行,得到结果:

image-20220314094944819

target下没有UserMapper文件,自然发现不了.

2.2 application.yml踩坑(此处无坑,是我学艺不精搞错了)

将注释去掉,配置好资源插件,接着踩application.yml的坑.

先清理再运行.

image-20220314100307033

image-20220314101004467

结果运行之后没有坑,好尴尬.

2.3 SpringBoot启动类未添加注解@MapperScan

image-20220314102721641

运行结果:

image-20220314103506722

2.4 ServiceImpl忘记加@Service注解

说起来这是一个低级错误,但是经常出现光顾着敲Service实现类的代码,忘记最后加上@Service注解;

将@Service注释:

image-20220314103718977

运行结果:

image-20220314104013346

报错信息为:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘com.example.demo.Test’: Unsatisfied dependency expressed through field ‘userService’; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.example.demo.service.UserService’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

2.5 xxxxMapper.xml文件的内部错误

1.namespace对应的路径写错

image-20220314104603776

详细报错信息:

org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'com/example/demo/mapper/UserMapper.xml'. Cause: org.apache.ibatis.builder.BuilderException: Wrong namespace. Expected 'com.example.demo.mapper.UserMapper' but found 'com.example.mapper.UserMapper'.
	

提示信息很详细,相对容易排查.

2. 对应的映射结果类写错

image-20220314105001375

报错信息:

org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'com/example/demo/mapper/UserMapper.xml'. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'com.example.demo.entity.Users'.  Cause: java.lang.ClassNotFoundException: Cannot find class: com.example.demo.entity.Users
3.sql标签中的id值与xxxMapper.java中的方法名对不上

image-20220314105342313

4. sql语句有语法错误

image-20220314105716756

报错信息:
org.springframework.jdbc.BadSqlGrammarException: 
### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'id=1' at line 1
### The error may exist in com/example/demo/mapper/UserMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select * from user wher id=?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'id=1' at line 1
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'id=1' at line 1

5.可能犯得错误

image-20220314105950806

6.使用Oracle可能出现错误

java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK

在pom文件添加依赖:

<!-- 用于解决: uncategorized SQLException; SQL state [99999]; error code [17056]; 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK; nested exception is java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK] with root cause
			java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK -->
	<!-- https://mvnrepository.com/artifact/com.oracle/orai18n -->
	<dependency>
		<groupId>com.oracle</groupId>
		<artifactId>orai18n</artifactId>
		<version>11.2.0.3</version>
	</dependency>

参考CSDN博主「是夏天呀!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40555277/article/details/103139648

3.一些建议

使用Mybatis正确的步骤为:

  1. 在pom.xml配置资源插件,确保能够将xxxMapper.xml文件复制到target目录下

  2. SpringBoot启动类一定要加@MapperScan注解

  3. Service实现类不要忘记添加@Service注解

  4. 注意XXXMapper.xml文件的编写,不要写错namspace,映射的类名,注意resultMap,resultType,注意sql语句的id与方法名是否对应,注意sql与语法是否正确等等.

  5. 注意Oracle数据库出现java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK,记得在pom文件中添加相关依赖,参考文章:https://blog.csdn.net/qq_40555277/article/details/103139648

  6. 建议安装mybatis插件,能够在一定程度上减少XXXMapper.xml文件的错误:

    image-20220314111046112

4.结语

以上内容是我遇到的SpringBoot整合Mybaits可能出现的问题,但不可能将所有的问题都罗列在内,以后根据需要再进行修改补充.最后想说一句编程中刚接触自己不会的技术,肯定会出现各种各样的问题,不要怕,勇敢试错,做好总结,最终总能掌握.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值