SpringBoot整合Mybatis,解決TypeAliases配置失敗的問題
問題描述
在應(yīng)用MyBatis時(shí),使用對(duì)象關(guān)系映射,將對(duì)象和Aliase映射起來。
在Mybatis的文檔明確寫出,如果你沒有明確定義實(shí)體類的Aliase,框架會(huì)自動(dòng)將Class Name自動(dòng)作為別名。
那么問題來了,當(dāng)使用java -jar xxx.jar&啟動(dòng)的時(shí)候,會(huì)報(bào)出以下錯(cuò)誤,
Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'XXXXX'.Cause: java.lang.ClassNotFoundException: Cannot find class: XXXXX
從異常信息來看,明顯就是無法從本地檢索到alise對(duì)應(yīng)的類,并最終導(dǎo)致sqlSessionFactory等初始化失敗。而且吊軌的是,直接在Idea中啟動(dòng)是沒有問題的,啟動(dòng)jar包才會(huì)出現(xiàn)這個(gè)問題
解決方法
參考博主A_Beaver的文章,原來mybatis的facroty需要加載SpringBoot獨(dú)特的虛擬文件系統(tǒng),才能識(shí)別類路徑
public SpringBootVFS() {
this.resourceResolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader());
}
從以上代碼看,其實(shí)是通過PathMatchingResourcePatternResolver實(shí)現(xiàn)資源的加載
修復(fù)該問題只需要在mybatis的配置類中,設(shè)置一下factory即可,
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setVfs(SpringBootVFS.class);//設(shè)置SpringBootVFS
bean.setTypeAliasesPackage("com.fulan.domain.red");
...
}
SpringBoot整合Mybatis及遇到的坑
1. 搭建項(xiàng)目環(huán)境
1.1 創(chuàng)建項(xiàng)目

1.2 修改POM文件,添加相關(guān)依賴
修改pom.xml文件,在其中添加下面依賴。
<!--Thymeleaf啟動(dòng)器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--mybatis啟動(dòng)器--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.3</version> </dependency> <!--jdbc啟動(dòng)器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--數(shù)據(jù)庫驅(qū)動(dòng)坐標(biāo)--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.12</version> </dependency> <!--Druid數(shù)據(jù)源依賴--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
1.3 配置數(shù)據(jù)源
在application.yml文件中配置如下代碼。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEnconding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
2. 配置Maven的generator插件
2.1 添加generator插件坐標(biāo)
<!--配置generator插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
</dependencies>
<!--指定配置文件的路徑-->
<configuration>
<configurationFile>${project.basedir}/src/main/resources/generator.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
2.2 添加generator配置文件
將文件命名為generator.xml,在src/main/resources中添加。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自動(dòng)生成的注釋 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 數(shù)據(jù)庫連接信息:驅(qū)動(dòng)類、連接地址、用戶名、密碼-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEnconding=utf-8&useSSL=false&serverTimezone=UTC"
userId="root" password="root">
</jdbcConnection>
<!-- 默認(rèn)false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer true,把JDBC DECIMAL
和 NUMERIC 類型解析為java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--targetProject:生成PO類的位置-->
<javaModelGenerator targetPackage="com.example.springbootmybatis.pojo"
targetProject=".\src\main\java">
<!--enableSubPackages:是否讓schema作為包的后綴-->
<property name="enableSubPackages" value="false" />
<!-- 從數(shù)據(jù)庫返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--對(duì)應(yīng)的mapper.xml文件 -->
<sqlMapGenerator targetPackage="com.example.springbootmybatis.mapper"
targetProject=".\src\main\java">
<!--enableSubPackages:是否讓schema作為包的后綴-->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 對(duì)應(yīng)的Mapper接口類文件 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.example.springbootmybatis.mapper" targetProject="./src/main/java">
<!--enableSubPackages:是否讓schema作為包的后綴-->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定數(shù)據(jù)庫表 -->
<table schema="" tableName="users"></table>
<!-- 列出要生成代碼的所有表,這里配置的是不生成Example文件 -->
<!-- <table tableName="userinfo" domainObjectName="UserInfoPO" -->
<!-- enableCountByExample="false" enableUpdateByExample="false" -->
<!-- enableDeleteByExample="false" enableSelectByExample="false" -->
<!-- selectByExampleQueryId="false"> -->
<!-- <property name="useActualColumnNames" value="false" /> -->
<!-- </table> -->
</context>
</generatorConfiguration>
2.3 添加generator配置文件的DTD文件
可以在工具欄中的File->Settings中添加,也可以直接在文件中按alt+shift自動(dòng)添加。

2.4 運(yùn)行g(shù)enerator插件生成代碼


3. 配置資源拷貝插件
3.1 添加資源拷貝插件坐標(biāo)
<!--配置資源拷貝插件--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> </includes> </resource> </resources>
3.2 修改啟動(dòng)類添加@MapperScan注解
package com.example.springbootmybatis;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.springbootmybatis.mapper")//指定掃描接口與映射配置文件的包名
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4. 其他配置項(xiàng)
mybatis: # 掃描classpath中mapper目錄下的映射配置文件,針對(duì)于映射文件放到了resources目錄下 mapper-locations: classpath:/mapper/*.xml # 定義包別名,使用pojo時(shí)可以直接使用pojo的類型名稱不用加包名 type-aliases-package: com.example.springbootmybatis.pojo
5. 添加用戶功能
5.1 創(chuàng)建頁面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favion.ico}">
<head>
<meta charset="UTF-8">
<title>測試SpringBoot連接PostgreSQL數(shù)據(jù)庫</title>
</head>
<body>
<form th:action="@{/user/addUser}" method="post">
<input type="text" name="userid"><br>
<input type="text" name="username"><br>
<input type="text" name="usersex"><br>
<input type="submit" value="添加"><br>
</form>
</body>
</html>
5.2 創(chuàng)建Controller
5.2.1 PageController
package com.example.springbootmybatis.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 頁面跳轉(zhuǎn)Controller
*/
@Controller
public class PageController {
/**
* 頁面跳轉(zhuǎn)方法
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
5.2.2 UsersController
package com.example.springbootmybatis.controller;
import com.example.springbootmybatis.pojo.Users;
import com.example.springbootmybatis.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 用戶管理Controller
*/
@RestController
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
* 添加用戶
*/
@PostMapping("/addUser")
public String addUsers(Users users){
try {
this.usersService.addUsers(users);
} catch (Exception e){
e.printStackTrace();
return "error";
}
return "redirect:/ok";
}
}
5.3 創(chuàng)建Service 接口實(shí)現(xiàn)類Impl
/**
* 用戶管理業(yè)務(wù)層
*/
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
@Override
@Transactional
public void addUsers(Users users) {
this.usersMapper.insert(users);
}
}
接口
public interface UsersService {
void addUsers(Users users);
}
遇到的錯(cuò)誤
1. Mybatis Generator自動(dòng)生成,數(shù)據(jù)庫的同名表也會(huì)生產(chǎn)的問題
[WARNING] Table Configuration users matched more than one table (test..users,performance_schema..users)
[WARNING] Cannot obtain primary key information from the database, generated objects may be incomplete
在 MyBatis Generator官網(wǎng) 中對(duì)這一問題做出了解答。

翻譯如下:Mysql 無法正常支持 SQL catalogs 和 schema。因此,最好不要在 generator 配置文件中指定 catalog 以及schema,僅需指定數(shù)據(jù)表的名字并在 JDBC URL 中指定數(shù)據(jù)庫即可。如果使用 mysql-connector-java 8.x 版本,generator 會(huì)為MySql中信息數(shù)據(jù)庫(sys, information_schema, performance_schema)的表生成代碼,若要避免這種操作,請?jiān)?JDBC URL 中加入屬性“nullCatalogMeansCurrent=true”。
修改配置文件generator.xml
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEnconding=utf-8&useSSL=false&serverTimezone=UTC"
userId="username" password="password">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
2. 頁面出現(xiàn)500錯(cuò)誤


2020-06-27 14:23:42.459 ERROR 19676 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Circular view path [addUsers]: would dispatch back to the current handler URL [/addUsers] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause
javax.servlet.ServletException: Circular view path [addUsers]: would dispatch back to the current handler URL [/addUsers] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:210) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at
解決方法
查了很多博客,但是都不是自己的問題,自己的問題是在pom.xml配置文件中的資源路徑中,沒有寫所有,而是單獨(dú)的xml和yml配置文件。要加載所有的靜態(tài)資源。
<!--原本的-->
<!--資源文件的路徑-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.xml</include>
</includes>
<!-- <filtering>false</filtering>-->
</resource>
<!--修改后的-->
<!--資源文件的路徑-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<!-- <filtering>false</filtering>-->
</resource>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- springboot下mybatis-plus開啟打印sql日志的配置指南
- springboot整合mybatis的超詳細(xì)過程(配置模式+注解模式)
- springboot mybatis druid配置多數(shù)據(jù)源教程
- springboot配置多數(shù)據(jù)源后mybatis攔截器失效的解決
- springboot項(xiàng)目整合mybatis并配置mybatis中間件的實(shí)現(xiàn)
- SpringBoot多數(shù)據(jù)源配置詳細(xì)教程(JdbcTemplate、mybatis)
- 詳解Springboot-MyBatis配置-配置端口號(hào)與服務(wù)路徑(idea社區(qū)版2023.1.4+apache-maven-3.9.3-bin)
相關(guān)文章
踩坑批量更新sql報(bào)錯(cuò),實(shí)際sql能夠正常執(zhí)行的問題
在項(xiàng)目工程遷移過程中,遇到了一個(gè)批量更新接口在新工程中報(bào)錯(cuò)的問題,通過分析,排除了代碼錯(cuò)誤的可能,最終發(fā)現(xiàn)是由于數(shù)據(jù)庫連接配置不當(dāng)導(dǎo)致的,在jdbc連接字符串中加入allowMultiQueries=true參數(shù)后,問題得以解決,這個(gè)參數(shù)的作用是允許SQL批量執(zhí)行2022-12-12
Java二維碼登錄流程實(shí)現(xiàn)代碼(包含短地址生成,含部分代碼)
近年來,二維碼的使用越來越風(fēng)生水起,本篇文章主要介紹了Java二維碼登錄流程實(shí)現(xiàn)代碼,其中包含短地址生成,有興趣的可以了解一下。2016-12-12
詳談hibernate,jpa與spring?data?jpa三者之間的關(guān)系
這篇文章主要介紹了hibernate,jpa與spring?data?jpa三者之間的關(guān)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(29)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07

