MyBatis Generator Core – Introduction to MyBatis Generator
MyBatis Generator 详解_enablesubpackages_isea533的博客-CSDN博客
一文解析 MyBatis Generator 的使用及配置 - 掘金
MyBatis Generator (MBG) 是 MyBatis MyBatis的代码生成器。它将生成所有版本的 MyBatis 的代码。它将内省(introspect)数据库表(或许多表)并生成可用于访问表的工件。这减少了设置对象和配置文件以与数据库表交互的初始麻烦。MBG 力求对大部分简单 CRUD(创建、检索、更新、删除)的数据库操作产生重大影响。您仍然需要为连接查询或存储过程手动编写 SQL 和对象代码。
MyBatis Generator (MBG) 根据其配置方式生成不同风格的代码。
<!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="simple" targetRuntime="MyBatis3">
<jdbcConnection driverClass="org.hsqldb.jdbcDriver"
connectionURL="jdbc:hsqldb:mem:aname" />
<javaModelGenerator targetPackage="example.model" targetProject="src/main/java"/>
<sqlMapGenerator targetPackage="example.mapper" targetProject="src/main/resources"/>
<javaClientGenerator type="XMLMAPPER" targetPackage="example.mapper" targetProject="src/main/java"/>
<table tableName="FooTable" />
</context>
</generatorConfiguration>
文档需要包含以下DOCTYPE
<!DOCTYPE generatorConfiguration PUBLIC
"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
generatorConfiguration节点没有任何属性,直接写节点即可,如下:
<generatorConfiguration>
<!-- 具体配置内容 -->
</generatorConfiguration>
子元素:
<properties> 元素用于指定用于解析配置的外部属性文件。引入属性文件后,可以在配置中使用 ${property}
这种形式的引用,通过这种方式引用属性文件中的属性值。
One, and only one, of the following attributes is required.
Attribute | Description |
resource | The qualified name of the property file. When specifying the resource, the classpath will be searched for the properties file. So a file specified as com/myproject/generatorConfig.properties must exist in the com.myproject package. |
url | A URL value to use for the property file. This can be used to specify a property file in a specific place on the file system when used in a form like file:///C:/myfolder/generatorConfig.properties. |
<classPathEntry> 元素用于将类路径位置添加到 MyBatis Generator (MBG) 运行的类路径中。
MBG 在这些实例中从这些位置加载类:
<context>元素用于指定生成一组对象的环境。子元素用于指定要连接的数据库、要生成的对象类型以及要内省的表。可以在<generatorConfiguration>元素内列出多个 <context> 元素 ,以允许在 MyBatis Generator (MBG) 的同一次运行中从不同数据库生成对象,或使用不同的生成参数生成对象。
该元素只有一个必选属性id
,用来唯一确定一个<context>元素
defaultModelType
:定义了MBG如何生成实体类。This attribute is ignored if the target runtime is "MyBatis3Simple", "MyBatis3DynamicSql", or "MyBatis3Kotlin"
这个属性有以下可选值:
targetRuntime
:此属性用于指定生成的代码的运行时环境
目标运行时 | 评论 |
MyBatis3DynamicSql | 这是默认值
|
MyBatis3Kotlin |
|
MyBatis3 | 这是原始的运行时。在MBG 1.3.6版本之前,MBG的大多数用法都使用这种代码风格。
|
MyBatis3Simple | 这是 MyBatis3 运行时的简化版本。
|
sample:
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
......
</context>
每个<context>元素都需要一个 <connectionFactory> 或 <jdbcConnection> 元素。
该元素需要指定jdbc连接时所需的驱动类名、URL、userId、password:
Property Name | Property Values |
driverClass | This property is used to specify the fully qualified class name of the JDBC driver. This property is required for the default connection factory. |
connectionURL | This property is used to specify the JDBC connection URL for the database. This property is required for the default connection factory. |
userId | This property is used to specify the User ID for the connection. |
password | This property is used to specify the password for the connection. |
sample:
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 配置MBG要连接的数据库信息 -->
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">
</jdbcConnection>
</context>
<javaModelGenerator> 元素用于定义 Java 模型生成器的属性。该元素是<context>元素必需的子元素。
Attribute | Description |
targetPackage | 将放置生成的类的包 |
targetProject | 为生成的对象指定指定一个已存在的目录 |
可以配置 0 或 1 个,用于配置关于 Mapper 接口的生成,如果没有配置该元素,那么默认不会生成 Mapper 接口。
元素 javaClientGenerator 有 3 个属性,其中 targetPackage 和 targetProject 属性的配置与 javaModelGenerator 元素的原理相同,只不过这里指的是 java 目录下存放 Mapper 接口的路径。关于 type 属性,有 3 个可选值:
注意,如果 context 元素的 defaultModelType 属性设置为 MyBatis3Simple,那么就只支持 ANNOTATEDMAPPER 和 XMLMAPPER 的方式。一般建议将 type 设置成 XMLMAPPER。
需要注意的是,当你的项目中有多个 Module 时,在配置 javaModelGenerator、sqlMapGenerator 和 javaClientGenerator 元素的 targetProject 属性时,需要在前面加上当前的 Module 名称。
<!-- 用于控制Mapper接口的生成 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.macro.mall.tiny.mbg.mapper"
targetProject="mall-tiny-generator\src\main\java"/>
可以配置 0 或 1 个,生成 SQL Map 的 xml 文件生成器。如果 javaClientGenerator 元素中配置了需要生成 xml 的话,这个元素就必须配置。
<sqlMapGenerator targetPackage="com.macro.mall.tiny.mbg.mapper" targetProject="mall-tiny-generator\src\main\resources"/>
用于给出该context的其他特性,官网列出了很多:context property,常用的如下:
Property Name | Property Values |
beginningDelimiter | 指定数据库标识符的开始定界符。数据库标识符(如表名、列名等)可能包含关键字、特殊字符或空格,这可能导致SQL语句出现语法错误。为了避免这种情况,可以使用开始定界符和结束定界符将标识符括起来,告诉数据库解析器这是一个标识符而不是关键字。举个例子,假设数据库中有一个名为 "order" 的表,但 "order" 是SQL关键字。如果你在 MBG 的配置中设置了 beginningDelimiter 为反引号`,那么生成的 SQL 就会像这样:SELECT * FROM `order`,数据库会将 order 视为标识符而不是关键字,从而避免了潜在的语法错误。 默认为双引号",且不同的数据库不同,Mysql为反引号`,Oracle为双引号" |
endingDelimiter | 标识符的结束定界符,与beginningDelimiter对应 |
javaFileEncoding | 如果未指定,则将使用平台默认编码 |
Sample:
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 配置SQL语句中的前置分隔符 -->
<property name="beginningDelimiter" value="`"/>
<!-- 配置SQL语句中的后置分隔符 -->
<property name="endingDelimiter" value="`"/>
<!-- 配置生成Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8"/>
</context>
<plugin> 元素用于定义插件,该元素是<context>的子元素。
<context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
<!-- 为模型生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 为生成的Java模型创建一个toString方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
</context>
UnmergeableXmlMappersPlugin
介绍:
该插件将生成的 XML 映射器文件标记为不可合并。这将导致生成器覆盖文件,或以新名称保存文件,具体取决于覆盖设置的配置方式。
一个 table 元素对应一张数据库表,如果想同时为多张表生成代码,需要配置多个 table 元素;或者可以将 tableName 设置为 % 来为全部表生成代码。
必须属性:tableName
,即指定数据库表名称
<table>有很多可选属性,但是可能很多都不太常用,具体参见官网:<table>标签
Sample:
<table tableName="ums_admin">
<!-- 生成主键的方法-->
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
以下配置文件置于maven项目的resources资源目录中:
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/mall_tiny?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.userId=root
jdbc.password=root
<?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="generator.properties"/>
<context id="mysql" targetRuntime="MyBatis3" defaultModelType="flat">
<!-- 配置SQL语句中的前置分隔符 -->
<property name="beginningDelimiter" value="`"/>
<!-- 配置SQL语句中的后置分隔符 -->
<property name="endingDelimiter" value="`"/>
<!-- 配置生成Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8"/>
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
<!-- 为模型生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 为生成的Java模型创建一个toString方法 -->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 配置MBG要连接的数据库信息 -->
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.connectionURL}"
userId="${jdbc.userId}"
password="${jdbc.password}">
</jdbcConnection>
<javaModelGenerator targetPackage="com.codepanda.backendlearning.mbg.model"
targetProject="src\main\java">
</javaModelGenerator>
<sqlMapGenerator targetPackage="com.codepanda.backendlearning.mbg.mapper"
targetProject="src\main\resources">
</sqlMapGenerator>
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.codepanda.backendlearning.mbg.mapper"
targetProject="src\main\java">
</javaClientGenerator>
<table tableName="ums_admin">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
</context>
</generatorConfiguration>
Running MyBatis Generator With Java
public class Generator {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
for(String warning:warnings){
System.out.println(warning);
}
}
}
Running MyBatis Generator With Maven
Java client generator为我们生成的Mapper中有以下接口方法:
官网介绍了每个接口和对应XML含义和使用:
MyBatis Generator Core – MyBatis Generator Generated SQL Map XML Files
MyBatis Generator Core – Example Class Usage Notes
Generator为生成Example类,比如UmsAdminExample,可以把它理解为一个条件构建器,用于构建SQL语句中的各种条件。当没有条件时,可以为selectByExample传入null。
如实现查询全部:
public List<PmsBrand> selectAll() {
return pmsBrandMapper.selectByExample(null);
}
Examples类指定如何创建动态的where子句,表中每个非BLOB字段都能被添加到where子句中,该类几乎可以添加无限的where子句。Example类中包含一个Criteria静态内部类,它包含了一系列可添加的条件语句。Criteria类对象可以通过Examples类的createCriteria()
方法或者or()
方法创建,通过createCriteria()
方法创建的第一个Criteria
实例会被自动的添加到oredCriteria
列表中。
Important We recommend that you only use the or method for creating Criteria classes. We believe that this method makes for more readable code.
官网推荐使用or
方法创建Criteria
,这样代码可读性更好。
官方示例:
This example shows how to generate a simple WHERE clause using the generated example class:
TestTableExample example = new TestTableExample();
example.createCriteria().andField1EqualTo(5);
Alternatively, the following syntax also works:
TestTableExample example = new TestTableExample();
example.or().andField1EqualTo(5);
In either above example, the dynamically generated where clause will effectively be:
where field1 = 5
insert会将全部字段插入,包括为null的字段,这样如果在数据库中设置了默认值字段,会被null覆盖。而insertSelective只会插入实体类中不为null的字段,因此更为推荐。
@Service
public class BrandServiceImpl implements BrandService {
@Autowired
private PmsBrandMapper pmsBrandMapper;
@Override
public List<PmsBrand> selectAll() {
return pmsBrandMapper.selectByExample(null);
}
@Override
public List<PmsBrand> selectByPage(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<PmsBrand> allBrands = pmsBrandMapper.selectByExample(null);
PageInfo<PmsBrand> pageInfo = new PageInfo<>(allBrands);
return pageInfo.getList();
}
@Override
public PmsBrand selectByPrimaryKey(long id) {
return pmsBrandMapper.selectByPrimaryKey(id);
}
@Override
public int insert(PmsBrand brand) {
return pmsBrandMapper.insertSelective(brand);
}
@Override
public int delete(long id) {
return pmsBrandMapper.deleteByPrimaryKey(id);
}
@Override
public int update(long id, PmsBrand brand) {
brand.setId(id);
return pmsBrandMapper.updateByPrimaryKeySelective(brand);
}
}