通过Velocity模板引擎对Mysql表自动生成JavaBean实体类的Gradle插件
Posted open-Xu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过Velocity模板引擎对Mysql表自动生成JavaBean实体类的Gradle插件相关的知识,希望对你有一定的参考价值。
版权声明:本文为openXu原创文章【openXu的博客】,未经博主允许不得以任何形式转载
文章目录
1. 需求
最近遇到一个需求,需要写一段程序,监听mysql数据库数据变化,对Cassandra的数据进行同步。但是现在Mysql里面是有数据的,Cassandra中没有数据,如果要保持同步,就需要程序跑起来的时候首先将Mysql中的数据批量插入到Cassandra中,然后监听Mysql变化,对Cassandra做增量处理。
在写程序的时候碰到一个问题,需要对Mysql中的表创建对应的实体类JavaBean对象,最开始的时候是通过Mysql建表语句一个个手动写的,无奈表太多,所以需要写一个自动生成JavaBean的Gradle插件。这个插件能自动连接Mysql数据库,查询出所有的表及其字段,然后使用Velocity
模板引擎自动组建实体类文件,从而实现JavaBean类的自动生成。
深入学习Gradle相关知识,请移步《Gradle深度揭秘》
插件使用
2. 插件编写
2.1 gradle配置
//buildSrc下build.gradle
apply plugin: 'groovy'
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies
compile gradleApi()
compile localGroovy()
repositories
mavenCentral()
tasks.withType(JavaCompile)
options.encoding = "UTF-8"
tasks.withType(GroovyCompile)
options.encoding = "UTF-8"
dependencies
// https://mvnrepository.com/artifact/org.apache.velocity/velocity
implementation group: 'org.apache.velocity', name: 'velocity', version: '1.7'
//https://mvnrepository.com/artifact/mysql/mysql-connector-java
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.20'
2.2 JDBC
需要通过JDBC从mysql中查询所有表及字段
public class MysqlHelper
Connection conn;
BeanDataSource dataSource;
public MysqlHelper(BeanDataSource dataSource)
this.dataSource = dataSource;
try
Class.forName(dataSource.getDriver());
conn = DriverManager.getConnection(dataSource.getUrl(), dataSource.getUserName(), dataSource.getPassword());
catch (Exception e)
e.printStackTrace();
/**
* 查询mysql中所有的表
* @return
*/
List<String> getAllTable()
List<String> tables = new ArrayList<>();
String sql_gettables = String.format("select TABLE_NAME from information_schema.tables where table_schema='%s'",dataSource.getDbName());
try
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql_gettables);
while(resultSet.next())
tables.add(resultSet.getString("TABLE_NAME"));
catch (SQLException e)
e.printStackTrace();
return tables;
/**
* 查询指定表的字段集合
* @param tableName
* @return
*/
List<Column> getTableColumns(String tableName)
String sql_getCloumns = String.format("select COLUMN_NAME, COLUMN_TYPE, COLUMN_KEY from information_schema.columns" +
" where table_schema='%s' and table_name='%s'",dataSource.getDbName(), tableName);
List<Column> columnList = new ArrayList<>();
try
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql_getCloumns);
while(resultSet.next())
columnList.add(new Column(
resultSet.getString("COLUMN_NAME"),
resultSet.getString("COLUMN_TYPE")));
catch (SQLException e)
e.printStackTrace();
return columnList;
//mysql字段对象封装
class Column
String fieldName // 实体类属性名
String fieldType // 实体类属性类型
Column(String mysqlColumnName, String columnType)
this.fieldName = mysqlColumnName
this.fieldType = column2FieldType(columnType)
String column2FieldType(String columnType)...
2.3 Velocity模板引擎
首先在resources目录下定义一个.vm
格式的JavaBean类的模板文件
package $packageName;
import lombok.Data;
/**
* Author: openXu
* Time: $time
* class: $className
* Description:
*/
@Data
public class $className
#foreach($columnProperty in $columns)
private $columnProperty.fieldType $columnProperty.fieldName;
#end
编写工具类,使用Velocity
自动生成实体类文件内容,并写入对应.java
文件中
class VelocityFactory
static
//配置velocity的资源加载路径
Properties velocityPros = new Properties()
velocityPros.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath")
velocityPros.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName())
velocityPros.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8")
velocityPros.setProperty(Velocity.INPUT_ENCODING, "UTF-8")
velocityPros.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8")
Velocity.init(velocityPros)
/**
* 根据模板生成JavaBean文件内容
* @param packageName 包名
* @param tableName mysql表名
* @param columnList 表字段集合
* @return
*/
static String getVmContent(String packageName, String className, List<Column> columnList)
//绑定velocity数据
VelocityContext context = new VelocityContext()
context.put("packageName", packageName) //实体类分包 com.openxu.bean
context.put("time", new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date())) //实体类生成时间2020/3/30 14:31
context.put("className", className)
context.put("columns", columnList)
//根据模板生成java文件内容
Template template = Velocity.getTemplate("bean.vm")
StringWriter writer = new StringWriter()
template.merge(context, writer)
writer.flush()
writer.close()
return writer.toString()
2.4 定义Gradle插件
由于有一些内容需要我们使用插件时进行配置,比如mysql url用户名密码等,以及我们JavaBean存放的文件夹,所以创建一个扩展类,方便使用插件时对插件进行配置
class BeanDataSource
//需要配置项
String driver
String url
String userName
String password
String packageName //bean输出目录
//数据库名称(自动截取)
String dbName
BeanDataSource build()
dbName = url.substring(url.lastIndexOf("/")+1, url.lastIndexOf("?"))
System.out.println("---------数据库名称:"+dbName+" bean包名:"+packageName)
return this
定义一个插件类,在插件被应用时创建一个名为beanDataSource
的扩展对象,类型为上面定义的扩展类。然后创建一个名为autoBean
的Task,运行这个任务就可以自动连接Mysql生成对应JavaBean类文件
/**
* Author: openXu
* Time: 2020/5/15 11:07
* class: AutoBeanPlugin
* Description: 自定义Gradle插件,根据数据源自动生成JavaBean
*/
class AutoBeanPlugin implements Plugin<Project>
@Override
void apply(Project project)
// 创建一个名为beanDataSource的扩展,在build.gradle中配置它
def beanDataSource = project.extensions.create('beanDataSource', BeanDataSource.class)
// 创建一个名为autoBean的任务,用于读取Mysql数据,自动创建bean
project.task("autoBean", type:AutoBeanTask, group:"help")
project.tasks.getByName("autoBean").doFirst
//将配置信息作为Task的参数
ext.beanDataSource = beanDataSource.build()
class AutoBeanTask extends DefaultTask
/**任务执行体 */
@TaskAction
def generateBean()
String outPath = String.format("%s/src/main/java/%s",project.getProjectDir(), beanDataSource.packageName.replaceAll("\\\\.", "/"))
System.out.println("输出路径:"+outPath)
//从mysql中查询表及字段
MysqlHelper helper = new MysqlHelper(beanDataSource)
List<String> tableList = helper.getAllTable()
for(String tableName : tableList)
//获取表字段集合
List<Column> columnList = helper.getTableColumns(tableName)
//根据模板创建java文件
writeFile(outPath, tableName, columnList)
/**
* 根据Mysql表及字段集合,通过Velocity模板自动生成实体类代码,写入对应类文件中
* @param filePath 实体类存放路径
* @param tableName 表名
* @param columnList 字段集合
*/
void writeFile(String filePath, String tableName, List<Column> columnList)
//获取实体类名
String className = StringUtil.underline2PascalStyle(tableName)
//获取文件内容
String classContent = VelocityFactory.getVmContent(beanDataSource.packageName, className, columnList)
File dir = new File(filePath)
if (!dir.exists())
dir.mkdirs()
File file = new File(dir, className+".java")
java.io.FileWriter writer = null
try
writer = new java.io.FileWriter(file)
writer.write(classContent)
catch (IOException e)
throw new RuntimeException("Error creating file " + className, e)
finally
if (writer != null)
try
writer.close()
catch (IOException e)
2.5 插件发布到Maven
在resources.META-INF.gradle-plugins
下创建插件配置文件mysqlautobean.plugin.properties
implementation-class=com.openxu.autobean.AutoBeanPlugin
添加发布脚本
//插件发布
apply plugin: 'maven-publish'
publishing
publications
mavenJava(MavenPublication)
groupId = "msyql.auto.javabean"
artifactId = "plugin"
version = "1.0.0"
from components.java
//配置仓库目录
repositories
maven
url uri('../repos')
gradle配置完成之后,运行gradlew :buildSrc:publish
,插件就被发布到当前工程目录下的repos
文件夹中了
3. 插件使用
//root build.gradle
buildscript
repositories
...
maven
url uri('repos')
dependencies
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'msyql.auto.javabean:plugin:1.0.0'
//app build.gradle
apply plugin: 'com.android.application'
apply plugin: 'mysqlautobean.plugin'
android
...
// 配置插件
beanDataSource
driver = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://127.0.0.1:3306/openXu?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&useCursorFetch=true&defaultFetchSize=1000"
userName = "root"
password = "root"
packageName = "com.openxu.autobean" //实体类输出目录
dependencies
...
//lombok自动资源管理,可以为JavaBean自动生成getter、setter、equals、hashCode和toString等等
// https://mvnrepository.com/artifact/org.projectlombok/lombok
implementation group: 'org.projectlombok', name: 'lombok', version: '1.18.12'
4. 源码
深入学习Gradle相关知识,请移步《Gradle深度揭秘》
AutoBeanGradlePlugin on GitHub By openXu
以上是关于通过Velocity模板引擎对Mysql表自动生成JavaBean实体类的Gradle插件的主要内容,如果未能解决你的问题,请参考以下文章