MyBatis Generator幾種生成代碼方式彙總
- MyBatis Generator幾種生成代碼方式彙總
- java代碼+配置檔案生成
- 純Java代碼+模闆生成
- 指令行+XML生成
- MyBatis-plugin
- MyBatis-pageHelper
- 第一步:添加依賴
- 第二步:設定分頁
MyBatis Generator幾種生成代碼方式彙總
java代碼+配置檔案生成
- 編寫配置檔案
<?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="H2Tables" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.FluentBuilderMethodsPlugin" />
<plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
<plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin" />
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:mem:testdb"
userId="sa"
password="">
</jdbcConnection>
<javaModelGenerator targetPackage="geektime.spring.data.mybatis.model"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="geektime.spring.data.mybatis.mapper"
targetProject="./src/main/resources/mapper">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<javaClientGenerator type="MIXEDMAPPER"
targetPackage="geektime.spring.data.mybatis.mapper"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table tableName="t_coffee" domainObjectName="Coffee" >
<generatedKey column="id" sqlStatement="CALL IDENTITY()" identity="true" />
<columnOverride column="price" javaType="org.joda.money.Money" jdbcType="BIGINT"
typeHandler="geektime.spring.data.mybatis.handler.MoneyTypeHandler"/>
</table>
</context>
</generatorConfiguration>
- 編寫java代碼
private void generateArtifacts() throws Exception {
List<String> warnings = new ArrayList<>();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(
this.getClass().getResourceAsStream("/generatorConfig.xml"));
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
純Java代碼+模闆生成
public class AutoCodeGenerator {
// JDBC配置,請修改為你項目的實際配置,必須增加 nullCatalogMeansCurrent=true配置,否則生成的實體和xml檔案無法正常映射主鍵
private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC&nullCatalogMeansCurrent=true";
private static final String JDBC_USERNAME = "admin";
private static final String JDBC_PASSWORD = "admin";
private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver";
private static final String PROJECT_PATH = "D:\\admin";
// Model,Mapper所在項目的磁盤目錄
private static final String DATABASE_PROJECT_PATH = "D:\\database";
// 模闆位置
private static final String TEMPLATE_FILE_PATH = "generator\\template";
// java檔案路徑
private static final String JAVA_PATH = "/src/main/java";
// 資源檔案路徑
private static final String RESOURCES_PATH = "/src/main/resources";
// 生成的Service存放路徑
private static final String PACKAGE_PATH_SERVICE = packageConvertPath(ProjectConstant.SERVICE_PACKAGE);
// 生成的Service實作存放路徑
private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(ProjectConstant.SERVICE_IMPL_PACKAGE);
// 生成的Controller存放路徑
private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(ProjectConstant.CONTROLLER_PACKAGE);
// @author
private static final String AUTHOR = "auto";
// @date
private static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
private static final boolean isRestful = true;
private static boolean overwrite = false;
public static void main(final String[] args) {
final Scanner scanner = new Scanner(System.in);
System.out.print("可能已存在相關檔案,是否覆寫?y/n:");
if (scanner.next().equals("y")) {
overwrite = true;
}
genCode("table_name");
//genCodeByCustomModelName("輸入表名","輸入自定義Model名稱");
}
/**
* 通過資料表名稱生成代碼,Model 名稱通過解析資料表名稱獲得,下劃線轉大駝峰的形式。
* 如輸入表名稱 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ...
*
* @param tableNames 資料表名稱...
*/
private static void genCode(final String... tableNames) {
for (final String tableName : tableNames) {
genCodeByCustomModelName(tableName, null);
}
}
/**
* 通過資料表名稱,和自定義的 Model 名稱生成代碼
* 如輸入表名稱 "t_user_detail" 和自定義的 Model 名稱 "sysUser" 将生成 sysUser、UserMapper、UserService ...
*
* @param tableName 資料表名稱
* @param modelName 自定義的 Model 名稱
*/
private static void genCodeByCustomModelName(final String tableName, final String modelName) {
genModelAndMapper(tableName, modelName);
genService(tableName, modelName); //TODO;去除Service的生成
genController(tableName, modelName); //TODO;去除Service的生成
}
private static void genModelAndMapper(final String tableName, String modelName) {
final Context context = new Context(ModelType.FLAT);
context.setId("Potato");
context.setTargetRuntime("MyBatis3Simple");
context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
final JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
final PluginConfiguration pluginConfiguration = new PluginConfiguration();
pluginConfiguration.setConfigurationType("tk.mybatis.mapper.generator.MapperPlugin");
pluginConfiguration.addProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE);
context.addPluginConfiguration(pluginConfiguration);
final JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
javaModelGeneratorConfiguration.setTargetProject(DATABASE_PROJECT_PATH + JAVA_PATH);
javaModelGeneratorConfiguration.setTargetPackage(ProjectConstant.MODEL_PACKAGE);
context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
final SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
sqlMapGeneratorConfiguration.setTargetProject(DATABASE_PROJECT_PATH + RESOURCES_PATH);
sqlMapGeneratorConfiguration.setTargetPackage(ProjectConstant.XML_MAPPER_PACKAGE);
context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
final JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
javaClientGeneratorConfiguration.setTargetProject(DATABASE_PROJECT_PATH + JAVA_PATH);
javaClientGeneratorConfiguration.setTargetPackage(ProjectConstant.MAPPER_PACKAGE);
javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
final TableConfiguration tableConfiguration = new TableConfiguration(context);
tableConfiguration.setTableName(tableName);
//如果資料庫連接配接沒有增加 nullCatalogMeansCurrent=true配置,則必須要配置Catalog,否則生成的實體和xml檔案無法正常映射主鍵
//tableConfiguration.setCatalog("yaue");
if (StringUtils.isNotEmpty(modelName)) {
tableConfiguration.setDomainObjectName(modelName);
}
tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
context.addTableConfiguration(tableConfiguration);
final List<String> warnings;
final MyBatisGenerator generator;
try {
final Configuration config = new Configuration();
config.addContext(context);
config.validate();
final DefaultShellCallback callback = new DefaultShellCallback(overwrite);
warnings = new ArrayList<>();
generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
} catch (final Exception e) {
throw new RuntimeException("生成 Model和 Mapper 失敗", e);
}
if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
throw new RuntimeException("生成 Model 和 Mapper 失敗:" + warnings);
}
if (StringUtils.isEmpty(modelName)) {
modelName = tableNameConvertUpperCamel(tableName);
}
System.out.println(modelName + ".java 生成成功");
System.out.println(modelName + "Mapper.java 生成成功");
System.out.println(modelName + "Mapper.xml 生成成功");
}
private static void genService(final String tableName, final String modelName) {
try {
final freemarker.template.Configuration cfg = getConfiguration();
final Map<String, Object> data = new HashMap<>();
data.put("date", DATE);
data.put("author", AUTHOR);
final String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;
data.put("modelNameUpperCamel", modelNameUpperCamel);
data.put("modelNameLowerCamel", tableNameConvertLowerCamel(tableName));
data.put("servicePackage", ProjectConstant.SERVICE_PACKAGE);
data.put("serviceImplPackage", ProjectConstant.SERVICE_IMPL_PACKAGE);
data.put("modelPackage", ProjectConstant.MODEL_PACKAGE);
data.put("mapperPackage", ProjectConstant.MAPPER_PACKAGE);
final File file = new File(PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + modelNameUpperCamel + "Service.java");
if (!file.getParentFile().exists()) {
final boolean isMake = file.getParentFile().mkdirs();
if (!isMake) {
throw new IOException("建立檔案失敗");
}
}
cfg.getTemplate("service.ftl").process(data,
new FileWriter(file));
System.out.println(modelNameUpperCamel + "Service.java 生成成功");
final File file1 = new File(PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE_IMPL + modelNameUpperCamel + "ServiceImpl.java");
if (!file1.getParentFile().exists()) {
final boolean isMake = file1.getParentFile().mkdirs();
if (!isMake) {
throw new IOException("建立檔案失敗");
}
}
cfg.getTemplate("service-impl.ftl").process(data,
new FileWriter(file1));
System.out.println(modelNameUpperCamel + "ServiceImpl.java 生成成功");
} catch (final Exception e) {
throw new RuntimeException("生成 Service 失敗,", e);
}
}
private static void genController(final String tableName, final String modelName) {
try {
final freemarker.template.Configuration cfg = getConfiguration();
final Map<String, Object> data = new HashMap<>();
data.put("date", DATE);
data.put("author", AUTHOR);
final String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;
data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
data.put("modelNameUpperCamel", modelNameUpperCamel);
data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
data.put("controllerPackage", ProjectConstant.CONTROLLER_PACKAGE);
data.put("servicePackage", ProjectConstant.SERVICE_PACKAGE);
data.put("modelPackage", ProjectConstant.MODEL_PACKAGE);
final File file = new File(PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java");
if (!file.getParentFile().exists()) {
final boolean isMake = file.getParentFile().mkdirs();
if (!isMake) {
throw new IOException("建立檔案失敗");
}
}
if (isRestful) {
cfg.getTemplate("controller-restful.ftl").process(data, new FileWriter(file));
} else {
cfg.getTemplate("controller.ftl").process(data, new FileWriter(file));
}
System.out.println(modelNameUpperCamel + "Controller.java 生成成功");
} catch (final Exception e) {
throw new RuntimeException("生成 Controller 失敗,", e);
}
}
private static freemarker.template.Configuration getConfiguration() throws IOException {
final freemarker.template.Configuration cfg = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_23);
cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
return cfg;
}
private static String tableNameConvertLowerCamel(final String tableName) {
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase());
}
private static String tableNameConvertUpperCamel(final String tableName) {
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());
}
private static String tableNameConvertMappingPath(String tableName) {
tableName = tableName.toLowerCase();//相容使用大寫的表名
return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
}
private static String modelNameConvertMappingPath(final String modelName) {
final String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
return tableNameConvertMappingPath(tableName);
}
private static String packageConvertPath(final String packageName) {
return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
}
}
不同模闆
//controller.ftl
package ${controllerPackage};
import ${modelPackage}.${modelNameUpperCamel};
import ${servicePackage}.${modelNameUpperCamel}Service;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* description:
* author ${author}
* date ${date}
*/
@RestController
@RequestMapping("${baseRequestMapping}")
public class ${modelNameUpperCamel}Controller {
@Resource
private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
}
//controller-restful.ftl
package ${controllerPackage};
import ${modelPackage}.${modelNameUpperCamel};
import ${servicePackage}.${modelNameUpperCamel}Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* description:
* author ${author}
* date ${date}
*/
@RestController
@RequestMapping("${baseRequestMapping}")
public class ${modelNameUpperCamel}Controller {
@Resource
private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
}
//service.ftl
package ${servicePackage};
import ${modelPackage}.${modelNameUpperCamel};
import com.test.service.Service;
/**
* description:
* author ${author}
* date ${date}
*/
public interface ${modelNameUpperCamel}Service extends Service<${modelNameUpperCamel}> {
}
//service-impl.ftl
package ${serviceImplPackage};
import ${mapperPackage}.${modelNameUpperCamel}Mapper;
import ${modelPackage}.${modelNameUpperCamel};
import ${servicePackage}.${modelNameUpperCamel}Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* @description:
* @author ${author}
* @date ${date}
*/
@Service
public class ${modelNameUpperCamel}ServiceImpl extends AbstractService<${modelNameUpperCamel}> implements ${modelNameUpperCamel}Service {
@Resource
private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper;
}
指令行+XML生成
- 将下面的百度網盤位址下載下傳下來。并編寫generator.xml檔案,修改資料庫賬号密碼等。
- 示例代碼
<?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>
<!-- 資料庫驅動包位置 -->
<!-- <classPathEntry location="D:\software\lib\mysql-connector-java-5.1.21.jar" /> -->
<classPathEntry location="C:\oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar" />
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 資料庫連結URL、使用者名、密碼 -->
<!-- <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/sy" userId="sypro" password="sypro"> -->
<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost:1521:orcl" userId="msa" password="msa">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成模型的包名和位置 -->
<javaModelGenerator targetPackage="sy.model" targetProject="D:\mybatis\src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成的映射檔案包名和位置 -->
<sqlMapGenerator targetPackage="sy.mapping" targetProject="D:\mybatis\src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成DAO的包名和位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="sy.dao" targetProject="D:\study\mybatis\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 要生成那些表(更改tableName和domainObjectName就可以) -->
<table tableName="tbug" domainObjectName="Bug" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="tmenu" domainObjectName="Menu" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="tonline" domainObjectName="Online" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="tresource" domainObjectName="Resource" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="trole" domainObjectName="Role" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="trole_tresource" domainObjectName="RoleResource" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="tuser" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="tuser_trole" domainObjectName="UserRole" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
</context>
</generatorConfiguration>
- 執行以下語句。
java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite
- 将生成的檔案拷貝到項目中。并删除get,set方法,改成@Data注解;并增加@Builder注解。
連結:https://pan.baidu.com/s/1TrjcueIu0wKdlGxflPH1wg
提取碼:771i
MyBatis-plugin
MyBatis-plugin是可以快速定位接口對應的sql語句位置的一款插件。
安裝過程:點選settings --> Plugins --> Marketplace --> 搜尋Free MyBatis plugin --> install --> restart IDE。
在MyBatis-plugin沒有出現的時候,一般都是ctrl+F來定位接口和sql位置,有時候會出現多個比對選項,需要一一對比,出錯率還是挺高的,但是使用MyBatis-plugin既可以大大規避錯誤的風險。
MyBatis-pageHelper
第一步:添加依賴
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
第二步:設定分頁
//[pageNum, pageSize] 頁碼 每頁顯示數量
PageHelper.startPage(curPage,pageSize);
PageInfo<Order> pageInfo = new PageInfo<>(orderMapper.findAll());
在需要執行查詢之前,這是分頁資料(curPage&pageSize)。會傳回一個PageInfo對象,包含了分頁查詢的是以資訊資料,如下:
用pageHelper插件,它會攔截我們寫的sql語句,自己重新包裝一層,在後面添加limit。是以當資料量大的時候,就會出現limit深度分頁問題,解決辦法同深度分頁的方式一樣,利用索引的優勢,将SQL語句改寫成先滿足條件的id,然後根據id進行查找最近的分頁條數。如下所示。
//用pageHelper的查詢
select * from (select * from account where age >= 20)where limit 100,10;
//改寫後的深度分頁
SELECT * FROM account WHERE id >= (SELECT id FROM account WHERE age = 20 ORDER BY id LIMIT 10000, 1) LIMIT 10