# opay **Repository Path**: weijinhao/opay ## Basic Information - **Project Name**: opay - **Description**: 支付项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-06-10 - **Last Updated**: 2023-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mybatis 使用指南(全) 关于 mybatis 的generator 的代码自动生成,官网为我们提供了多种整合方式,具体使用那个整合方式,视我们具体情况决定,这里 我们采用 maven插件的形式,关于插件配置属性的参数,可以点进maven 连接中查看具体参数配置。说明参考官网说明。 ![](https://img-blog.csdnimg.cn/img_convert/f8fa39240df02ad998e17e2c6f731d91.png) ```xml org.mybatis.generator mybatis-generator-maven-plugin 1.4.0 src/main/resources/generatorConfig.xml true Generate MyBatis Artifacts generate mysql mysql-connector-java 5.1.39 ``` 配置中我们制定了代码生成器的具体配置,所以该插件会根据我么的配置文件进行代码生成。 # 关于generatorConfig.xml ```xml
``` 我们已经将具体的配置抽出为配置文件了,可以灵活配置文件路径等相关参数。 ```properties spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://101.34.136.47:3306/renren?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 spring.datasource.username=root spring.datasource.password=123456 generated.domain.dir.targetPackage=com.example.springcloudstreamtest.domain generated.mapper.dir.targetPackage=mappers generated.dao.dir.targetPackage=com.example.springcloudstreamtest.dao # 切记 一定是\\ 转义 generated.domain.dir=D:\\code\\springcloudstreamtest generated.mapper.dir=D:\\code\\springcloudstreamtest generated.dao.dir=D:\\code\\springcloudstreamtest ``` 关于targetRuntime 的不同,官网已经为我们详细介绍了,参考如下 ![](https://img-blog.csdnimg.cn/img_convert/967e5ae3c9ae9c6e238e3ca45b192ce6.png) # 其他配置 参考 ![](https://img-blog.csdnimg.cn/img_convert/22e565a3b69656620cb78282fa9dcb9a.png) # spring boot 使用mybatis ```java @SpringBootApplication //扫描该包 @MapperScan(basePackages={"com.example.springcloudstreamtest.dao"}) public class SpringcloudstreamtestApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudstreamtestApplication.class, args); } } ``` ```properties spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://101.34.136.47:3306/renren?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 spring.datasource.username=root spring.datasource.password=123456 mybatis.mapper-locations=classpath*:mappers/*Mapper.xml ``` # 关于springboot xml文件存储在 非resources中打包不进去问题 ```xml src/main/java **/*.xml src/main/resources **/*.xml **/* true ``` # mybatis generator 遇到到问题 1. 使用mybatis generator 插件方式的话有一定的局限性,比如,我们我们在配置文件中使用了自定义的SimpleCommentGenerator来生成代码注解 并在配置文件中指定了,接下来就会出现如下问题. ![](https://img-blog.csdnimg.cn/img_convert/4d42d8f6a92f8ac18f2500be361f4e7b.png) 导致改异常的原因也很简单,就是插件相当于是一个java 程序,那么她也有自己的classpath 但是我们配置文件中指定的是我们当前项目中的classpath 下的SimpleCommentGenerator,所以会找不到,解决方案有两种,一种是提供一个jar 就跟mysql一样添加进依赖中 另一中是通过配置文件将指定文件夹加载进classpath中,但是文件中的SimpleCommentGenerator一定要是编译后的。所以局限性啊 ```xml ``` 考虑到这种局限性,我们还是老老实实的用代码写吧!! ```java public class GeneratorTest { public static void main(String[] args) throws Exception { InputStream configFile = GeneratorTest.class.getResourceAsStream("/generatorConfig.xml"); List warnings = new ArrayList(); boolean overwrite = true; ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } } ``` 2. 如果我们使用生成mybatis mapper xml的话,会发现一个问题,就是无论我们如何设置想要进行文件的覆盖操作,都不会生效,比如 ```xml ``` ```java boolean overwrite = true; ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); ``` 种种尝试都不会生效文件的覆盖,还是会追加,为啥类,找了半天源码才发现是代码里面写死的,咱就话说,这不是bug吗 ```java private void writeGeneratedXmlFile(GeneratedXmlFile gxf, ProgressCallback callback) throws InterruptedException, IOException { File directory = shellCallback.getDirectory(gxf .getTargetProject(), gxf.getTargetPackage()); targetFile = new File(directory, gxf.getFileName()); if (targetFile.exists()) { //永远都会进入到这里面,原因是 这个is mergeable 是他喵写死的 if (gxf.isMergeable()) { source = XmlFileMergerJaxp.getMergedSource(gxf, targetFile); //这个方法根本就来不及执行 } else if (shellCallback.isOverwriteEnabled()) { } } } public List getGeneratedXmlFiles() { if (xmlMapperGenerator != null) { //兄弟们,看见了吗,true 这不是bug吗 GeneratedXmlFile gxf = new GeneratedXmlFile(document, getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(), context.getSqlMapGeneratorConfiguration().getTargetProject(), true, context.getXmlFormatter()); } return answer; } ``` 解决方案就是使用 plugin 进行复写,不过现在有现成的plugin 了 ```xml ``` 3. 讲一点经验之谈 关于 MapperScan 和 mapper xml 配置文件大家老是拿不定配置是否正确,那我来告诉大家一个常事, 其实这两部分是分开的,我们只要确保,mapper xml 通过配置文件加载进了config,然后使用MapperScan注解扫描了所有的interface(其实就是一个session的代理)[mybatis 源码总结](https://blog.csdn.net/c1523456/article/details/124833215) 然后再确定两者的命名空间没问题,就绝逼他喵没问题。 4. 因为引入了覆盖xml 文件的问题,所以我们一定要把手写的代码领出来单写(如果不解决覆盖,就会有追加重复代码的问题) 具体的应用案例,我放到了这个博客上面,大家可以参考一下。 [mybatis总结](https://blog.csdn.net/c1523456/article/details/120124095) 5. 为了注释我们自己实现了一个简单的注释给mybatis generator使用 ```java public class SimpleCommentGenerator extends DefaultCommentGenerator { /** * 生成模型注释 * * @param topLevelClass 类 * @param introspectedTable 表 */ public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { String remarks = introspectedTable.getRemarks(); remarks = isEmpty(remarks) ? "" : remarks + ":"; remarks = remarks.replace("\n", " "); topLevelClass.addJavaDocLine("/**"); topLevelClass.addJavaDocLine(" * " + remarks + introspectedTable.getFullyQualifiedTable()); topLevelClass.addJavaDocLine(" */"); } /** * 生成字段注释 * * @param field 字段 * @param introspectedTable 表 * @param introspectedColumn 表列 */ @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { String remarks = introspectedColumn.getRemarks(); remarks = isEmpty(remarks) ? "" : remarks + ":"; remarks = remarks.replace("\n", " "); field.addJavaDocLine("/**"); field.addJavaDocLine(" * " + remarks + introspectedColumn.getActualColumnName()); field.addJavaDocLine(" */"); } /** * 是否为空 * * @param value * @return */ private boolean isEmpty(String value) { if (value != null && value.length() > 0) { return false; } return true; } } ```