动态表单及动态建表实现原理
来源:互联网 发布:excel03显示重复数据 编辑:程序博客网 时间:2024/05/22 23:34
项目中往往需要动态的创建一个表单,或者添加一个新的数据模板,这时候因为需要在运行时动态的创建表以及动态的维护表字段甚至表关系 使得普通java解决方案变得困难重重。
2实现工具
Hibernate + Spring + Groovy +Freemarker
Hibernate 作用很简单负责创建数据库表这样可以避免我们自己去写复杂的sql和判断。
Spring 作为桥梁起到连接纽带的作用。
Groovy做为动态语言,在项目运行时根据模板创建访问数据库,或者控制层代码。
Freamker 可以根据提前定义好的模板生成 hibernate配置文件,以及Groovy代码。
3实现原理
首先创建Form 和 FromAttribute 两张表关系一对多。Form表记录表单的名称,类别,甚至是作为在动态生成表单时的css样式信息。FromAttribute记录表单字段信息,如名称,类别等。有了表单以及表单项的信息后就可以创建数据库表了。
测试代码:
public void testGenerator(){
Form form = formService.getAll()。get(0);
List list = formAttributeService
。getAttributeListByFormId(form.getId());form.setFormAttributeList(list);DbGenerator dg = new DbGenerator(form, dataSource);dg.generator();
}
DbGenerator
import java.io.IOException;import java.io.StringWriter;import java.io.Writer;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.tool.hbm2ddl.SchemaExport;import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import freemarker.template.Configuration;import freemarker.template.Template;import freemarker.template.TemplateException;
public class DbGenerator {
private DataSource dataSource;
protected Map root = new HashMap();
private static Logger log = LoggerFactory.getLogger(FormGenerator.class);
protected String path;
protected String packageName;
private Form form;
protected Configuration getConfig(String resource){
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("UTF-8");cfg.setClassForTemplateLoading(this.getClass(), resource);
return cfg;
}
public DbGenerator(Form form ,DataSource dataSource) { this.form = form;this.dataSource = dataSource;
}
public void generator(){
if(null == form.getFormAttributeList() || form.getFormAttributeList()。size() == 0){
return;
}
Template t;
try {
t = getConfig("/template")。getTemplate("hibernate.ftl");
Writer out = new StringWriter();
t.process(getMapContext(), out);String xml = out.toString();
createTable(xml);
log.debug(xml);
} catch(IOException e){
e.printStackTrace();
} catch(TemplateException e){
e.printStackTrace();
}
@SuppressWarnings("unchecked")
Map getMapContext(){
root.put("entity", form);
return root;
}
public void createTable(String xml){
org.hibernate.cfg.Configuration conf = new org.hibernate.cfg.Configuration();nfigure("/hibernate/hibernate.cfg.xml");
Properties extraProperties = new Properties();
extraProperties.put("hibernate.hbm2ddl.auto", "create");conf.addProperties(extraProperties);
conf.addXML(xml);
SchemaExport dbExport;
try {
dbExport = new SchemaExport(conf, dataSource.getConnection());// dbExport.setOutputFile(path);dbExport.create(false, true);
} catch(SQLException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class hibernateGenerator {
}hibernate.ftl
hibernate.cfg.xml
org.hibernate.dialect.SQLServerDialect
net.sourceforge.jtds.jdbc.Driver
jdbc:jtds:sqlserver://127.0.0.1:1433;databasename=struts;SelectMethod=cursor
sa
sa
true
update
——>
创建好数据库后就要利用groovy动态创建访问代码了:先看测试代码再看具体实现:
public void testGroovy(){
Form form = formService.get("1");
List list = formAttributeService
。getAttributeListByFormId(form.getId());form.setFormAttributeList(list);
FormGenerator fg = new FormGenerator(form);
String groovycode = fg.generator();ClassLoader parent = getClass()。getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
Class groovyClass = loader.parseClass(groovycode);
GroovyObject groovyObject = null;
try {
groovyObject = (GroovyObject) groovyClass.newInstance();
} catch(InstantiationException e){
e.printStackTrace();
} catch(IllegalAccessException e){
e.printStackTrace();
}
// map中key为formAttribute中描述该表单字段在数据库中的名称c_columnName
//具体情况根据formAttribute而定
Map map = new HashMap();
map.put("name", "limq");
//调用insert方法插入数据
int c = (Integer) groovyObject.invokeMethod("insert", map);
//调用getAll方法获得所有动态表中的数据
Object o = groovyObject.invokeMethod("getAll", null);
List list2 =(List)o;
Object obj = list2.get(0);
try {
String tname = (String) BeanUtils.getDeclaredProperty(obj, "name");System.out.println(tname);
} catch(IllegalAccessException e){
e.printStackTrace();
} catch(NoSuchFieldException e){
e.printStackTrace();
}
//调用search方法查询动态表
List returnList = (List) groovyObject.invokeMethod("search", map);
for(Map map2:returnList){
//同理此处根据FromAttribute而定
System.out.println(map2.get("id"));System.out.println(map2.get("name"));System.out.println(map2.get("type"));
}
}FormGenerator:创建访问数据库Groovy代码
public class FormGenerator {
protected Map root = new HashMap();
private static Logger log = LoggerFactory.getLogger(FormGenerator.class);
protected String path;
protected String packageName;
private Form form;
protected Configuration getConfig(String resource){
Configuration cfg = new Configuration();
cfg.setDefaultEncoding("UTF-8");cfg.setClassForTemplateLoading(this.getClass(), resource);
return cfg;
}
public FormGenerator(Form form){
this.form = form;
}
public String generator(){
String returnstr = null;
Template t;
try {
t = getConfig("/template")。getTemplate("FormService.ftl");//Writer out = new OutputStreamWriter(new FileOutputStream(new File(path)),"UTF-8");
Writer out = new StringWriter();
t.process(getMapContext(), out);returnstr = out.toString();log.debug(returnstr);
} catch(IOException e){
e.printStackTrace();
} catch(TemplateException e){
e.printStackTrace();
}
return returnstr;
}
@SuppressWarnings("unchecked")
Map getMapContext(){
root.put("entity", form);root.put("insert", SqlHelper.buildInsertStatement(form));root.put("update", SqlHelper.buildUpdateStatement(form));
root.put("insertParameter", SqlHelper.buildInsertparameter(form));root.put("updateParameter", SqlHelper.buildUpdateparameter(form));
root.put("delete", SqlHelper.buildDeleteStatement(form));root.put("query", SqlHelper.buildQueryStatement(form));
return root;
}
}FormService.ftl import java.sql.ResultSet import java.sql.SQLException import java.sql.Types import org.sprire.RowMapper import org.sprire.RowMapperResultSetExtractor import re.dao.DataSourceFactory import mons.lang.builder.ToStringBuilder;import mons.lang.builder.ToStringStyle;
class ${entity.name?cap_first}Dao {
def insert = '${insert}'
def delete = '${delete}'
def update = '${update}'
def int insert(entity){
def Object[] params = [${insertParameter}]
def int[] types=[Types.VARCHAR,] return DataSourceFactory.getJdbcTemplate()。update(insert, params, types)
}
def int update(entity){
def Object[] params = [${updateParameter}]
return DataSourceFactory.getJdbcTemplate()。update(update, params)
}
def int delete(String entityId){
def Object[] params =[entityId]
return DataSourceFactory.getJdbcTemplate()。update(delete, params)
}
def search(entity){
${query}
println(query);
return DataSourceFactory.getJdbcTemplate()。queryForList(query);
}
}
以上代码示意了如何利用 freemarker 生成 Groovy 和 hibernate 相关代码,以及如何利用Groovy动态的对数据库进行创建和增删改查操作,了解以上的原理后就可以方便的在运行时利用freemarker生成表示层页面以及代码来进行展示。
原文地址:http://www.educity.cn/java/504830.html
- 动态表单及动态建表实现原理
- 动态表单及动态建表实现原理
- 动态数据窗创建原理及实现
- CGLib动态代理原理及实现
- CGLib动态代理原理及实现
- 动态代理类实现原理及实例
- CGLib动态代理原理及实现
- 【转载】CGLib动态代理原理及实现
- CGLib动态代理原理及实现
- CGLib动态代理原理及实现
- CGLib动态代理原理及实现
- 【转载】CGLib动态代理原理及实现
- JDK动态代理原理及实现
- JDK动态代理实现及原理分析
- CGLib动态代理原理及实现
- C语言动态数组原理及实现
- CGLib动态代理原理及实现
- CGLib动态代理原理及实现
- 朴素的UNIX之-调度器前传
- 怎么用jquery检查图片是否已经加载即加载是否成功
- eclipse如何自动提示
- 朴素的UNIX之-调度器细节
- 今日半价 3.6.0 开发总结
- 动态表单及动态建表实现原理
- STM32中关于串口通信的printf()函数重定向问题
- x4412开发板&ibox卡片电脑项目实战14-linux驱动的编写步骤
- 用Emacs muse制作幻灯片
- 高性能网络编程(一)----accept建立连接
- 代码流程分析
- 在N9使用TabGround进行页面导航(02)
- malloc,free的简单实现
- Mina、Netty、Twisted一起学(九):异步IO和回调函数