Java IDEA 根据mybatis-generator-core自动生成代码支持sqlserver获取备注(二)
mybatis generator代码生成虽然好用,但是好像不支持sqlserver获取备注信息,这里我主要分享mybatis generator改写后支持sqlserver获取备注信息,mysql以及oracle数据库经过简单的配置再加以修改即可。针对sqlserver的命名规则,将字段NickName对应实体类的nickName,实现mysql以及sqlserver数据库共存情况下使用一个实体类。
项目结构如下:
1.这里主要需要添加的代码有:
引用的jar包
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </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> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency> <!-- MySQL Connector --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> <scope>runtime</scope> </dependency> <!--jdbc启动器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>8.3.1.jre8-preview</version> </dependency> <!-- https://mvnrepository.com/artifact/com.intellij/annotations --> <dependency> <groupId>com.intellij</groupId> <artifactId>annotations</artifactId> <version>12.0</version> </dependency> </dependencies>
sqlServerGeneratorConfig.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> <!-- 指定数据库驱动的jdbc驱动jar包的位置,这里需要写绝对位置 --> <classPathEntry location="D:\Java\myCodeMaven\maven-repository\com\microsoft\sqlserver\mssql-jdbc\8.3.1.jre8-preview\mssql-jdbc-8.3.1.jre8-preview.jar"/> <context id="mysql" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple" > <!-- 生成的 Java 文件的编码 --> <property name="javaFileEncoding" value="UTF-8"/> <!-- 格式化 Java 代码 --> <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/> <!-- 格式化 XML 代码 --> <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/> <!-- hasLombok --> <plugin type="org.mybatis.generator.plugins.LombokPlugin" > <property name="hasLombok" value="true"/> </plugin> <!--生成mapper.xml时覆盖原文件,防止追加--> <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" /> <!-- 自定义注释生成器 --> <commentGenerator type="com.zsy.codegenerato.mbgcomment.MySQLCommentGenerator"> <property name="author" value="zsy"/> <property name="dateFormat" value="yyyy/MM/dd"/> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!-- 配置数据库连接 --> <jdbcConnection driverClass="com.microsoft.sqlserver.jdbc.SQLServerDriver" connectionURL="jdbc:sqlserver://127.0.0.1;DatabaseName=User" userId="sa" password="123456"> <!-- Mysql数据库设置 useInformationSchema 属性为 true --> <property name="useInformationSchema" value="true" /> <!-- 针对oracle数据库 --> <property name="remarksReporting" value="true"/> <!--设置可以获取remarks信息--> <property name="allProceduresAreCallable" value="true"/> <!--解决多个数据库表同名导致的问题,这个配置也很重要--> <property name="nullCatalogMeansCurrent" value="true"/> </jdbcConnection> <!-- 生成实体的位置 --> <javaModelGenerator targetPackage="com.zsy.codegenerato.models" targetProject="code-generato/src/main/java"> <property name="enableSubPackages" value="true"/> <!--以下配置将所有的实体类都继承至该基类--> <!--<property name="rootClass" value=""/>--> </javaModelGenerator> <!-- 生成 Mapper XML 的位置 --> <sqlMapGenerator targetPackage="mybatis.mapper" targetProject="code-generato/src/main/resources"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!-- 生成 Mapper 接口的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.zsy.codegenerato.mapper" targetProject="code-generato/src/main/java"> <property name="enableSubPackages" value="true"/> <!-- <property name="rootInterface" value="java.io.Serializable"/>--> </javaClientGenerator> <!-- 设置数据库的表名和实体类名 --> <!-- <table tableName="t_trade" domainObjectName="Trade"></table>--> <table tableName="UserInfo" domainObjectName="UserInfo"></table> </context> </generatorConfiguration>
EmptyCommentGenerator.java
package com.zsy.codegenerato.mbgcomment; import org.mybatis.generator.api.CommentGenerator; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.api.dom.xml.XmlElement; import java.util.Properties; import java.util.Set; public class EmptyCommentGenerator implements CommentGenerator { @Override public void addConfigurationProperties(Properties properties) { } @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { } @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable) { } @Override public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { } @Override public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) { } @Override public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean b) { } @Override public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) { } @Override public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { } @Override public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { } @Override public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) { } @Override public void addJavaFileComment(CompilationUnit compilationUnit) { } @Override public void addComment(XmlElement xmlElement) { } @Override public void addRootComment(XmlElement xmlElement) { } @Override public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) { } @Override public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> set) { } @Override public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) { } @Override public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> set) { } @Override public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) { } }
MySQLCommentGenerator.java
package com.zsy.codegenerato.mbgcomment; import org.mybatis.generator.api.FullyQualifiedTable; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.dom.java.*; import org.mybatis.generator.api.dom.xml.Attribute; import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.config.TableConfiguration; import org.mybatis.generator.internal.db.ActualTableName; import java.sql.Connection; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.*; public class MySQLCommentGenerator extends EmptyCommentGenerator { private final Properties properties; private TopLevelClass topLevelClass; public MySQLCommentGenerator() { properties = new Properties(); } @Override public void addConfigurationProperties(Properties properties) { // 获取自定义的 properties this.properties.putAll(properties); } @Override public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { String author = properties.getProperty("author"); String dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd"); SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat); //导入包 //topLevelClass.addJavaDocLine("import javax.persistence.*;"); topLevelClass.addJavaDocLine("import java.io.Serializable;"); topLevelClass.addJavaDocLine("import io.swagger.annotations.*;"); topLevelClass.addJavaDocLine("import lombok.*;"); FullyQualifiedTable aa = introspectedTable.getFullyQualifiedTable(); // 获取表注释 String remarks = introspectedTable.getRemarks(); topLevelClass.addJavaDocLine(""); topLevelClass.addJavaDocLine("/**"); topLevelClass.addJavaDocLine(" * @Description " + remarks); topLevelClass.addJavaDocLine(" * @Author " + author); topLevelClass.addJavaDocLine(" * @Date " + dateFormatter.format(new Date())); topLevelClass.addJavaDocLine(" */"); topLevelClass.addJavaDocLine("@Data"); topLevelClass.addJavaDocLine("@ApiModel(description= \""+remarks+"\")"); //添加默认继承的接口(配置只有类继承类rootClass,接口继承接口rootInterface) topLevelClass.addSuperInterface(new FullyQualifiedJavaType("Serializable")); } @Override public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) { //获取列所处的位置 List<IntrospectedColumn> allColumnList = introspectedTable.getAllColumns(); int position = allColumnList.indexOf(introspectedColumn); if(position==0){ field.addJavaDocLine(""); field.addJavaDocLine(genSerialID()); } field.addJavaDocLine(""); // 获取列注释 String remarks = introspectedColumn.getRemarks(); field.addJavaDocLine("/**"); field.addJavaDocLine(" * " + remarks); field.addJavaDocLine(" */"); field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\", position = "+position+")"); //针对UserName 字段的处理,变成userName;userMessage还是userMessage //&& !Character.isLowerCase(columnName.charAt(0)) String columnName = introspectedColumn.getActualColumnName(); if(!columnName.contains("_") ){ columnName = (new StringBuilder()).append(Character.toLowerCase(columnName.charAt(0))).append(columnName.substring(1)).toString(); field.setName(columnName); } } private static String genSerialID() { return "private static final long serialVersionUID = "+Math.abs(new Random().nextLong())+"L;"; } }
LombokPlugin.java;这里是重点,去除了getter、setter,同时针对sqlserver数据库获取备注信息。
//这个包名保持这个 package org.mybatis.generator.plugins; import org.mybatis.generator.api.ConnectionFactory; import org.mybatis.generator.api.IntrospectedColumn; import org.mybatis.generator.api.IntrospectedTable; import org.mybatis.generator.api.PluginAdapter; import org.mybatis.generator.api.dom.java.Field; import org.mybatis.generator.api.dom.java.Method; import org.mybatis.generator.api.dom.java.TopLevelClass; import org.mybatis.generator.api.dom.xml.Attribute; import org.mybatis.generator.api.dom.xml.Element; import org.mybatis.generator.api.dom.xml.XmlElement; import org.mybatis.generator.config.JDBCConnectionConfiguration; import org.mybatis.generator.internal.JDBCConnectionFactory; import org.mybatis.generator.internal.ObjectFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; /** * @author zsy 20200706 */ public class LombokPlugin extends PluginAdapter { @Override public boolean validate(List<String> list) { return true; } @Override public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { //不生成getter return false; } @Override public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { //不生成setter return false; } @Override public boolean sqlMapResultMapWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) { List<Element> elist = element.getElements(); System.out.println("element.getName()="+element.getName()); Integer elistCount = elist.size(); for(Integer i=0;i<elistCount;i++){ XmlElement xmlElement = (XmlElement)(elist.get(i)); String columnName = ""; List<Attribute> attributes = xmlElement.getAttributes(); int attributeCount = attributes.size(); for(Integer j=0;j<attributeCount;j++){ Attribute attribute = attributes.get(j); Attribute attributeNew=null; if(attribute.getName().equals("column")){ columnName = attribute.getValue(); }else if(attribute.getName().equals("property")){ if(!"".equals(columnName) && attribute.getName().equals("property")){ // && !Character.isLowerCase(columnName.charAt(0)) if(!columnName.contains("_")){ attributeNew = new Attribute(attribute.getName(), (new StringBuilder()).append(Character.toLowerCase(columnName.charAt(0))).append(columnName.substring(1)).toString()); attributes.remove(attribute); attributes.add(attributeNew); } } } } } // XmlElement xe = new XmlElement("result"); // xe.addAttribute(new Attribute("column", "tablesite")); // xe.addAttribute(new Attribute("property", "tablesite")); // xe.addAttribute(new Attribute("jdbcType", "INTEGER")); // elist.add(xe); //return super.sqlMapResultMapWithoutBLOBsElementGenerated(element, introspectedTable); return true; } @Override public boolean sqlMapResultMapWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) { //将首字母大写改为小写,后面的大小写不变(不存在"_"的时候) List<Element> elist = element.getElements(); Integer elistCount = elist.size(); for(Integer i=0;i<elistCount;i++){ XmlElement xmlElement = (XmlElement)(elist.get(i)); String columnName = ""; List<Attribute> attributes = xmlElement.getAttributes(); int attributeCount = attributes.size(); for(Integer j=0;j<attributeCount;j++){ Attribute attribute = attributes.get(j); Attribute attributeNew=null; if(attribute.getName().equals("column")){ columnName = attribute.getValue(); }else if(attribute.getName().equals("property")){ if(!"".equals(columnName) && attribute.getName().equals("property")){ // && !Character.isLowerCase(columnName.charAt(0)) if(!columnName.contains("_")){ attributeNew = new Attribute(attribute.getName(), (new StringBuilder()).append(Character.toLowerCase(columnName.charAt(0))).append(columnName.substring(1)).toString()); attributes.remove(attribute); attributes.add(attributeNew); } } } } } return true; //return super.sqlMapResultMapWithoutBLOBsElementGenerated(element, introspectedTable); } @Override public void initialized(IntrospectedTable introspectedTable) { Connection connection = null; try { connection = getConnection(); ResultSet sqlServerResultSet = null; ResultSet sqlServerTableResultSet = null; boolean isSqlServer = connection.getMetaData().getDriverName().toUpperCase() .indexOf("SQL SERVER") != -1; if (isSqlServer) { //添加注释 //sqljdbc与sqljdbc4不同,sqlserver中间有空格 String sql = "SELECT\n" + "\tconvert(varchar(1000), D.value) AS TABLEREMARKS,\n"+ "\tB.name AS COLUMNNAME,\n"+ "\tconvert(varchar(1000), C.\n" + "VALUE)\n" + "\tAS REMARKS\n" + "FROM\n" + "\tsys.tables A\n" + "INNER JOIN sys.columns B ON B.object_id = A.object_id\n" + "LEFT JOIN sys.extended_properties C ON C.major_id = B.object_id\n" + "AND C.minor_id = B.column_id\n" + "LEFT JOIN sys.extended_properties D ON D.major_id = A.object_id AND D.minor_id = 0\n"+ "WHERE\n" + "\tA.name = ? "; PreparedStatement ps = connection.prepareStatement(sql); ps.setString(1, introspectedTable.getFullyQualifiedTable().getIntrospectedTableName()); sqlServerResultSet = ps.executeQuery(); if(sqlServerResultSet!=null){ List<IntrospectedColumn> allColumnList = introspectedTable.getAllColumns(); Integer index = 0; int length = allColumnList.size(); while (sqlServerResultSet.next()){ if(index == 0){ introspectedTable.setRemarks(sqlServerResultSet.getString("TABLEREMARKS")); index++; } for(Integer i=0;i<length;i++){ IntrospectedColumn columnInfo = allColumnList.get(i); if(sqlServerResultSet.getString("COLUMNNAME").equals(columnInfo.getActualColumnName())){ allColumnList.get(i).setRemarks(sqlServerResultSet.getString("REMARKS")); } } } } } } catch (SQLException e) { e.printStackTrace(); }finally { closeConnection(connection); } introspectedTable.getAllColumns().forEach(m->{ System.out.println(m.getActualColumnName()+"==="+m.getRemarks()); }); } private Connection getConnection() throws SQLException { Object connectionFactory; JDBCConnectionConfiguration jdbcConnectionConfiguration = context.getJdbcConnectionConfiguration(); if (jdbcConnectionConfiguration != null) { connectionFactory = new JDBCConnectionFactory(jdbcConnectionConfiguration); } else { connectionFactory = ObjectFactory.createConnectionFactory(context); } return ((ConnectionFactory)connectionFactory).getConnection(); } private void closeConnection(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException var3) { } } } }
SqlServerGenerator.java
package com.zsy.codegenerato; import org.mybatis.generator.api.MyBatisGenerator; import org.mybatis.generator.config.Configuration; import org.mybatis.generator.config.xml.ConfigurationParser; import org.mybatis.generator.internal.DefaultShellCallback; import java.io.File; import java.util.ArrayList; import java.util.List; /** * 使用 Java 的方式来运行 MBG * @see <a href="http://www.mybatis.org/generator/running/runningWithJava.html">Running MyBatis Generator With Java</a> */ public class SqlServerGenerator { public static void main(String[] args) throws Exception { List<String> warnings = new ArrayList<>(2); ConfigurationParser cp = new ConfigurationParser(warnings); File configFile = new File("sqlServerGeneratorConfig.xml"); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(true); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } }
2.将LombokPlugin.java文件生成的LombokPlugin.class放到本地仓库:D:\Java\myCodeMaven\maven-repository\org\mybatis\generator\mybatis-generator-core\1.3.7\mybatis-generator-core-1.3.7.jar\org\mybatis\generator\plugins下,需要用压缩文件打开mybatis-generator-core-1.3.7.jar,并将LombokPlugin.class文件复制到其中。
3.直接运行SqlServerGenerator.java即可。