SpringBoot & MyBatis 3 & MySQL
重新整理了一下 MyBatis 的使用,以作备忘。
Eclipse vs IntelliJ IDEA
作为开发的 IDE 来讲我更喜欢用 IntelliJ IDEA ,不过在通过 Maven 运行 MyBatis Generator 插件时,java client 文件(即 Mapper 文件)总是会被覆盖。如果在 Mapper 中增加了自定义的接口定义,重新生成时就没有了。
根据官方文档中的说法,Eclipse 插件会根据方法备注中的 @mbg.generated 标签来识别哪些是自动生成的方法,哪些不是,从而避免自定义的方法被替换掉,但是 IDEA 中貌似没有类似的插件。
没有办法,最好还是通过 Eclipse 来运行 MyBatis Generator。通过 Eclipse 菜单的 Help ⇒ Eclipse Marketplace 安装 MyBatis Generator 1.4.0 插件。另外因为创建的是 Spring Boot 项目,所以另外还安装了 Spring Tools 4 (aka Spring Tool Suite 4) 插件。
下面是最终使用的配置文件:
mybatis-generator.xml
这里使用了 MapperAnnotationPlugin 插件,貌似是 1.4.0 版本里才有的,如果运行出错的话可以删掉。其对应的功能可以通过在 Application 启动类上添加 @MapperScan("liujiajia.me.mybatis3sample.mapper")
注解来实现。
<?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>
<properties resource="mybatis-generator.properties" />
<context id="TestDB" targetRuntime="MyBatis3">
<property name="javaFileEncoding" value="UTF-8" />
<plugin
type="org.mybatis.generator.plugins.MapperAnnotationPlugin"></plugin>
<commentGenerator>
<property name="suppressDate" value="true" />
<!-- suppressAllComments 为 true 时,多次执行 MyBatis Generator 会生成重复的代码 -->
<!-- <property name="suppressAllComments" value="true"/> -->
<property name="addRemarkComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="${test.driver}"
connectionURL="${test.url}" userId="${test.username}"
password="${test.password}">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="true" />
</javaTypeResolver>
<!-- generate Model -->
<javaModelGenerator
targetPackage="${javaModelGenerator.targetPackage}"
targetProject="${javaModelGenerator.targetProject}">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 自动生成xml -->
<sqlMapGenerator
targetPackage="${sqlMapGenerator.targetPackage}"
targetProject="${sqlMapGenerator.targetProject}">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 自动生成mapper接口, 可以是 ANNOTATEDMAPPER(注解), XMLMAPPER(xml), MIXEDMAPPER -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="${javaClientGenerator.targetPackage}"
targetProject="${javaClientGenerator.targetProject}">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table tableName="country">
</table>
</context>
</generatorConfiguration>
mybatis-generator.properties
部分配置是放在 mybatis-generator.properties 文件中的,示例如下:
test.driver=com.mysql.cj.jdbc.Driver
test.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
test.username=root
test.password=root
javaModelGenerator.targetPackage=liujiajia.me.mybatis3sample.model
javaModelGenerator.targetProject=MyBatisSample/src/main/java
sqlMapGenerator.targetPackage=liujiajia.me.mybatis3sample.mapper
sqlMapGenerator.targetProject=MyBatisSample/src/main/resources
javaClientGenerator.targetPackage=liujiajia.me.mybatis3sample.mapper
javaClientGenerator.targetProject=MyBatisSample/src/main/java
关于 targetProject 的值,在 IDEA 中是不需要带上项目名(MyBatisSample)的,在 Eclipse 中需要加上去,否则会报找不到 src 项目的错误(Eclipse 用的少,不确定是不是哪边配置不对导致的)。
另外 sqlMapGenerator 和 javaClientGenerator 的 targetPackage 貌似一定要一致,否则运行时会报错。
运行 MyBatis Generator 插件
右键 mybatis-generator.xml 然后选择 Run As ⇒ Run MyBatis Generator。生成的代码根据 targetRuntime 的不同会有很大的不同,这里就不贴了。
项目代码
这部分是项目中使用到的 Maven 配置文件等。
pom.xml
因为用到了 Swagger-UI ,所以添加了 springfox-swagger-ui 和 springfox-swagger2 包。
数据库是 MySQL,需要添加 mysql-connector-java 包。
plugins 中还配置了 mybatis-generator-maven-plugin 插件,不过如果只通过 Eclipse 中的插件来生成的话,这段配置就用不到了。
<?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.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>liujiajia.me</groupId>
<artifactId>mybatis3sample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis3sample</name>
<description>Demo project for MyBatis3</description>
<properties>
<java.version>1.8</java.version>
<swagger.version>2.9.2</swagger.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.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<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.20</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.4</version>
</dependency>
</dependencies>
<configuration>
<!--允许移动生成的文件 -->
<verbose>true</verbose>
<!-- 是否覆盖 -->
<overwrite>true</overwrite>
<!-- 自动生成的配置 -->
<configurationFile>src/main/resources/mybatis-generator.xml</configurationFile>
</configuration>
</plugin>
</plugins>
</build>
</project>
applicationContext.xml
这里是代码中需要用到的配置文件,在启动文件中指定。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--数据源-->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--Sql Session Factory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
Mybatis3sampleApplication.java
上面提到过如果 MapperAnnotationPlugin 插件找不到的话,可以在这里通过添加 @MapperScan("liujiajia.me.mybatis3sample.mapper")
注解的方式来实现相同的功能。
package liujiajia.me.mybatis3sample;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml")
@EnableSwagger2
public class Mybatis3sampleApplication {
public static void main(String[] args) {
SpringApplication.run(Mybatis3sampleApplication.class, args);
}
}
CountryController.java
这是一个默认的示例,可以用来做参考。
package liujiajia.me.mybatis3sample.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import liujiajia.me.mybatis3sample.mapper.CountryMapper;
import liujiajia.me.mybatis3sample.model.Country;
import liujiajia.me.mybatis3sample.model.CountryExample;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@Api(tags = { "国家操作接口" })
@RestController
@RequestMapping("api/country")
public class CountryController {
@Resource
private CountryMapper mapper;
@ApiOperation(value = "根据主键获取国家信息", notes = "接口备注信息")
@RequestMapping(value = "pk/{id}", method = RequestMethod.GET)
public Country findByPrimaryKey(@PathVariable("id") int id) {
return mapper.selectByPrimaryKey(id);
}
@ApiOperation(value = "根据主键获取国家信息(自定义 Mapper 方法)", notes = "接口备注信息(自定义 Mapper 方法)")
@RequestMapping(value = "customize/{id}", method = RequestMethod.GET)
public Country findById(@PathVariable("id") int id) {
return mapper.findById(id);
}
@ApiOperation(value = "根据主键获取国家信息(Example)", notes = "接口备注信息(Example)")
@RequestMapping(value = "example/{id}", method = RequestMethod.GET)
public List<Country> findByExample(@PathVariable("id") int id) {
CountryExample example = new CountryExample();
example.createCriteria().andIdEqualTo(id);
return mapper.selectByExample(example);
}
}
官方示例 是通过 sqlSession.getMapper 方法来获取 Mapper 实例的,不过我感觉通过 @Resource
注解的方式也挺方便的。
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
MyTableMapper mapper = sqlSession.getMapper(MyTableMapper.class);
List<MyTable> allRecords = mapper.selectByExample(null);
} finally {
sqlSession.close();
}
附
time zone 错误
连接 MySQL 数据库时报如下错误:
Failed to execute goal org.mybatis.generator:mybatis-generator-maven-plugin:1.3.5:generate (default-cli) on project mybatis3sample: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
把 url 从 jdbc:mysql://localhost:3306/test 后面添加 ?serverTimezone=UTC 就好了。
参考
- MyBatis-Spring SqlSession:之前写的一篇博客
- Spring Initializr:可以很方便的初始化一个 Spring 项目代码
- Mvn Repository:查询 Maven 依赖的网站
- MySQL 的 driverClassName、url
- github/gitignore:包含常用的开发语言、IDE 对应的 .gitignore 文件的常规写法
- Mybatis Generator 生成代码重复
- eclipse 集成 MybatisGenerator 及使用
- MyBatis Generator Generated Java Client Objects