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即可。