SpringBoot整合Mybatis,解决TypeAliases配置失败的问题
问题描述
在应⽤MyBatis时,使⽤对象关系映射,将对象和Aliase映射起来。
在Mybatis的⽂档明确写出,如果你没有明确定义实体类的Aliase,框架会⾃动将Class Name⾃动作为别名。
那么问题来了,当使⽤java -jar xxx.jar&启动的时候,会报出以下错误,
Error resolving class. Cause: org.pe.TypeException: Could not resolve type alias 'XXXXX'.Cause: java.lang.ClassNotFoundException: Cannot find class: XXXXX 从异常信息来看,明显就是⽆法从本地检索到alise对应的类,并最终导致sqlSessionFactory等初始化失败。⽽且吊轨的是,直接在Idea中启动是没有问题的,启动jar包才会出现这个问题解决⽅法
参考博主A_Beaver的⽂章,原来mybatis的facroty需要加载SpringBoot独特的虚拟⽂件系统,才能识别类路径
public SpringBootVFS() {
}
从以上代码看,其实是通过PathMatchingResourcePatternResolver实现资源的加载
修复该问题只需要在mybatis的配置类中,设置⼀下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);//设置SpringBootVFS
bean.setTypeAliasesPackage("com.d");
...
}
SpringBoot整合Mybatis及遇到的坑
1. 搭建项⽬环境
1.1 创建项⽬
1.2 修改POM⽂件,添加相关依赖
修改l⽂件,在其中添加下⾯依赖。
<!--Thymeleaf启动器-->
<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启动器-->
<dependency>
<groupId&batis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--jdbc启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--数据库驱动坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<!--Druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
1.3 配置数据源
在l⽂件中配置如下代码。
spring:
datasource:
driver-class-name: sql.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插件坐标
<!--配置generator插件-->
<plugin>
<groupId&ator</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/l</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
2.2 添加generator配置⽂件
将⽂件命名为l,在src/main/resources中添加。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration胰腺在人体的哪个部位图解
PUBLIC "-////DTD MyBatis Generator Configuration 1.0//EN"
"/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除⾃动⽣成的注释 true:是: false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据库连接信息:驱动类、连接地址、⽤户名、密码-->
<jdbcConnection driverClass="sql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEnconding=utf-8&useSSL=false&serverTimezone=UTC"                            userId="root" password="root">
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL
和 NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!--targetProject:⽣成PO类的位置-->
<javaModelGenerator targetPackage="ample.springbootmybatis.pojo"
targetProject=".\src\main\java">
<!--enableSubPackages:是否让schema作为包的后缀-->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!--对应的l⽂件 -->
<sqlMapGenerator targetPackage="ample.springbootmybatis.mapper"
targetProject=".\src\main\java">
<!--enableSubPackages:是否让schema作为包的后缀-->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- 对应的Mapper接⼝类⽂件 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="ample.springbootmybatis.mapper" targetProject="./src/main/java">
<!--enableSubPackages:是否让schema作为包的后缀-->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<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⾃动添加。
2.4 运⾏generator插件⽣成代码
3. 配置资源拷贝插件
3.1 添加资源拷贝插件坐标
<!--配置资源拷贝插件-->
<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 修改启动类添加@MapperScan注解
ample.springbootmybatis;
batis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("ample.springbootmybatis.mapper")//指定扫描接⼝与映射配置⽂件的包名public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4. 其他配置项
mybatis:
# 扫描classpath中mapper⽬录下的映射配置⽂件,针对于映射⽂件放到了resources⽬录下
mapper-locations: classpath:/mapper/*.xml
# 定义包别名,使⽤pojo时可以直接使⽤pojo的类型名称不⽤加包名
type-aliases-package: ample.springbootmybatis.pojo
5. 添加⽤户功能
5.1 创建页⾯
<!DOCTYPE html>
<html lang="en" xmlns:th="">
<link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favion.ico}">
<head>
<meta charset="UTF-8">
<title>测试SpringBoot连接PostgreSQL数据库</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 创建Controller
5.2.1 PageController
ller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 页⾯跳转Controller
*/
@Controller
public class PageController {
赵忠祥董卿丑闻
/**
* 页⾯跳转⽅法
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
5.2.2 UsersController
ller;
ample.springbootmybatis.pojo.Users;
ample.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 创建Service 接⼝实现类Impl
/**
* ⽤户管理业务层
*/
@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);
}
遇到的错误
1. Mybatis Generator⾃动⽣成,数据库的同名表也会⽣产的问题
[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 在官⽹中对这⼀问题做出了解答。