电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

动态表单及动态建表实现原理


发布日期:2022/4/16
 

应用场景

项目中往往需要动态的创建一个表单或者添加一个新的数据模板这时候因为需要在运行时动态的创建表以及动态的维护表字段甚至表关系 使得普通java解决方案变得困难重重

实现工具

Hibernate + Spring + Groovy +Freemarker

Hibernate 作用很简单负责创建数据库表这样可以避免我们自己去写复杂的sql和判断

Spring 作为桥梁起到连接纽带的作用

Groovy做为动态语言在项目运行时根据模板创建访问数据库或者控制层代码

Freamker 可以根据提前定义好的模板生成 hibernate配置文件以及Groovy代码

实现原理

首先创建Form 和 FromAttribute 两张表关系一对多Form表记录表单的名称类别甚至是作为在动态生成表单时的css样式信息FromAttribute记录表单字段信息如名称类别等有了表单以及表单项的信息后就可以创建数据库表了

测试代码

public void testGenerator(){

Form form = formServicegetAll()get(

List list = formAttributeService

getAttributeListByFormId(formgetId())formsetFormAttributeList(list)DbGenerator dg = new DbGenerator(form dataSource)dggenerator()

}

DbGenerator

import javaioIOExceptionimport javaioStringWriterimport javaioWriterimport javasqlSQLExceptionimport javautilHashMapimport javautilMapimport javautilProperties

import javaxsqlDataSource

import orghibernatetoolhbmddlSchemaExportimport orgslfjLoggerimport orgslfjLoggerFactory

import freemarkertemplateConfigurationimport freemarkertemplateTemplateimport freemarkertemplateTemplateException

public class DbGenerator {

private DataSource dataSource

protected Map root = new HashMap()

private static Logger log = LoggerFactorygetLogger(FormGeneratorclass)

protected String path

protected String packageName

private Form form

protected Configuration getConfig(String resource){

Configuration cfg = new Configuration()

cfgsetDefaultEncoding(UTFcfgsetClassForTemplateLoading(thisgetClass() resource)

return cfg

}

public DbGenerator(Form form DataSource dataSource) { thisform = formthisdataSource = dataSource

}

public void generator(){

if(null == formgetFormAttributeList() || formgetFormAttributeList()size() == ){

return

}

Template t

try {

t = getConfig(/templategetTemplate(hibernateftl

Writer out = new StringWriter()

tprocess(getMapContext() out)String xml = outtoString()

createTable(xml)

logdebug(xml)

} catch(IOException e){

eprintStackTrace()

} catch(TemplateException e){

eprintStackTrace()

}

@SuppressWarnings(unchecked

Map getMapContext(){

rootput(entity form)

return root

}

public void createTable(String xml){

orghibernatecfgConfiguration conf = new orghibernatecfgConfiguration()nfigure(/hibernate/hibernatecfgxml

Properties extraProperties = new Properties()

extraPropertiesput(hibernatehbmddlauto createconfaddProperties(extraProperties)

confaddXML(xml)

SchemaExport dbExport

try {

dbExport = new SchemaExport(conf dataSourcegetConnection())// dbExportsetOutputFile(path)dbExportcreate(false true)

} catch(SQLException e){

// TODO Autogenerated catch block

eprintStackTrace()

}

}

class hibernateGenerator {

}hibernateftl

hibernatecfgxml

orghibernatedialectSQLServerDialect

netsourceforgejtdsjdbcDriver

jdbcjtdssqlserver://databasename=strutsSelectMethod=cursor

sa

sa

true

update

——>

创建好数据库后就要利用groovy动态创建访问代码了先看测试代码再看具体实现

public void testGroovy(){

Form form = formServiceget(

List list = formAttributeService

getAttributeListByFormId(formgetId())formsetFormAttributeList(list)

FormGenerator fg = new FormGenerator(form)

String groovycode = fggenerator()ClassLoader parent = getClass()getClassLoader()

GroovyClassLoader loader = new GroovyClassLoader(parent)

Class groovyClass = loaderparseClass(groovycode)

GroovyObject groovyObject = null

try {

groovyObject = (GroovyObject) groovyClassnewInstance()

} catch(InstantiationException e){

eprintStackTrace()

} catch(IllegalAccessException e){

eprintStackTrace()

}

// map中key为formAttribute中描述该表单字段在数据库中的名称c_columnName

//具体情况根据formAttribute而定

Map map = new HashMap()

mapput(name limq

//调用insert方法插入数据

int c = (Integer) groovyObjectinvokeMethod(insert map)

//调用getAll方法获得所有动态表中的数据

Object o = groovyObjectinvokeMethod(getAll null)

List list =(List)o

Object obj = listget(

try {

String tname = (String) BeanUtilsgetDeclaredProperty(obj nameSystemoutprintln(tname)

} catch(IllegalAccessException e){

eprintStackTrace()

} catch(NoSuchFieldException e){

eprintStackTrace()

}

//调用search方法查询动态表

List returnList = (List) groovyObjectinvokeMethod(search map)

for(Map mapreturnList){

//同理此处根据FromAttribute而定

Systemoutprintln(mapget(id))Systemoutprintln(mapget(name))Systemoutprintln(mapget(type))

}

}FormGenerator创建访问数据库Groovy代码

public class FormGenerator {

protected Map root = new HashMap()

private static Logger log = LoggerFactorygetLogger(FormGeneratorclass)

protected String path

protected String packageName

private Form form

protected Configuration getConfig(String resource){

Configuration cfg = new Configuration()

cfgsetDefaultEncoding(UTFcfgsetClassForTemplateLoading(thisgetClass() resource)

return cfg

}

public FormGenerator(Form form){

thisform = form

}

public String generator(){

String returnstr = null

Template t

try {

t = getConfig(/templategetTemplate(FormServiceftl//Writer out = new OutputStreamWriter(new FileOutputStream(new File(path))UTF

Writer out = new StringWriter()

tprocess(getMapContext() out)returnstr = outtoString()logdebug(returnstr)

} catch(IOException e){

eprintStackTrace()

} catch(TemplateException e){

eprintStackTrace()

}

return returnstr

}

@SuppressWarnings(unchecked

Map getMapContext(){

rootput(entity form)rootput(insert SqlHelperbuildInsertStatement(form))rootput(update SqlHelperbuildUpdateStatement(form))

rootput(insertParameter SqlHelperbuildInsertparameter(form))rootput(updateParameter SqlHelperbuildUpdateparameter(form))

rootput(delete SqlHelperbuildDeleteStatement(form))rootput(query SqlHelperbuildQueryStatement(form))

return root

}

}FormServiceftl import javasqlResultSet import javasqlSQLException import javasqlTypes import orgsprireRowMapper import orgsprireRowMapperResultSetExtractor import redaoDataSourceFactory import monslangbuilderToStringBuilderimport monslangbuilderToStringStyle

class ${entityname?cap_first}Dao {

def insert = ${insert}

def delete = ${delete}

def update = ${update}

def int insert(entity){

def Object[] params = [${insertParameter}]

def int[] types=[TypesVARCHAR] return DataSourceFactorygetJdbcTemplate()update(insert params types)

}

def int update(entity){

def Object[] params = [${updateParameter}]

return DataSourceFactorygetJdbcTemplate()update(update params)

}

def int delete(String entityId){

def Object[] params =[entityId]

return DataSourceFactorygetJdbcTemplate()update(delete params)

}

def search(entity){

${query}

println(query)

return DataSourceFactorygetJdbcTemplate()queryForList(query)

}

}

以上代码示意了如何利用 freemarker 生成 Groovy 和 hibernate 相关代码以及如何利用Groovy动态的对数据库进行创建和增删改查操作了解以上的原理后就可以方便的在运行时利用freemarker生成表示层页面以及代码来进行展示

上一篇:软件设计:色彩化的设计

下一篇:JVM 命令行标志您不知道的5件事