日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時間:2025/3/17 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态表单及动态建表实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? 1 應(yīng)用場景
? 項目中往往需要動態(tài)的創(chuàng)建一個表單,或者添加一個新的數(shù)據(jù)模板,這時候因為需要在運行時動態(tài)的創(chuàng)建表以及動態(tài)的維護(hù)表字段甚至表關(guān)系 使得普通java解決方案變得困難重重。?

????2 實現(xiàn)工具

Hibernate + Spring + Groovy +Freemarker

Hibernate 作用很簡單負(fù)責(zé)創(chuàng)建數(shù)據(jù)庫表這樣可以避免我們自己去寫復(fù)雜的sql和判斷。

Spring 作為橋梁起到連接紐帶的作用。

Groovy做為動態(tài)語言,在項目運行時根據(jù)模板創(chuàng)建訪問數(shù)據(jù)庫,或者控制層代碼。

Freamker 可以根據(jù)提前定義好的模板生成 hibernate配置文件,以及Groovy代碼。

?

????3?實現(xiàn)原理

??首先創(chuàng)建Form 和 FromAttribute 兩張表關(guān)系一對多。Form表記錄表單的名稱,類別,甚至是作為在動態(tài)生成表單時的css樣式信息。FromAttribute記錄表單字段信息,如名稱,類別等。有了表單以及表單項的信息后就可以創(chuàng)建數(shù)據(jù)庫表了。

測試代碼:
public?void?testGenerator()?{
????????Form?form?=?formService.getAll().get(0);
????????List<FormAttribute>?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();
????????conf.configure(
"/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
<?xml?version="1.0"?encoding="UTF-8"?>

<!DOCTYPE?hibernate-mapping?
??PUBLIC?"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"
?????????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

<hibernate-mapping>
????
<class
????????
name="${entity.name}"
????????table="`${entity.tableName}`"
????????dynamic-update="false"
????????dynamic-insert="false"
????????select-before-update="false"
????????optimistic-lock="version">
????????
<id
????????????
name="id"
????????????column="id"
????????????type="java.lang.String"
????????????unsaved-value="null">
????????????
<generator?class="uuid"?/>
????????
</id>
????????
<#if?entity.formAttributeList?exists>
????????????
<#list?entity.formAttributeList?as?attr>
????????????????
<#if?attr.name?==?"id">????????????????
????????????????
<#else>
????????
<property
????????????
name="${attr.name}"
????????????type="java.lang.String"
????????????update="true"
????????????insert="true"
????????????access="property"
????????????column="`${attr.columnName}`"
????????????length="${attr.length}"
????????????not-null="false"
????????????unique="false"
????????/>
????????
????????????????
</#if>
????????????
</#list>
????????
</#if>
???????
????
</class>

</hibernate-mapping>
hibernate.cfg.xml
<!DOCTYPE?hibernate-configuration
????PUBLIC?"-//Hibernate/Hibernate?Configuration?DTD?3.0//EN"
????"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"
>

<hibernate-configuration>
<session-factory>
????????
<property?name="dialect">org.hibernate.dialect.SQLServerDialect</property>
????
<property?name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
????
<property?name="connection.url">jdbc:jtds:sqlserver://127.0.0.1:1433;databasename=struts;SelectMethod=cursor</property>
????
<property?name="connection.username">sa</property>
????
<property?name="connection.password">sa</property>
????
????
<property?name="show_sql">true</property>
????
<property?name="hibernate.hbm2ddl.auto">update</property>

<!--??
????<mapping?resource="hibernate/FormAttribute.hbm.xml"?/>
????<mapping?resource="hibernate/Form.hbm.xml"?/>
????
-->
</session-factory>

</hibernate-configuration> ? 創(chuàng)建好數(shù)據(jù)庫后 就要利用groovy動態(tài)創(chuàng)建訪問代碼了:先看測試代碼 再看具體實現(xiàn):
public?void?testGroovy()?{
????????Form?form?
=?formService.get("1");
????????List
<FormAttribute>?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中描述該表單字段在數(shù)據(jù)庫中的名稱c_columnName
????????
//?具體情況根據(jù)formAttribute而定
????????Map?map?=?new?HashMap();
????????map.put(
"name",?"limq");
????????
//?調(diào)用insert方法插入數(shù)據(jù)
????????int?c?=?(Integer)?groovyObject.invokeMethod("insert",?map);

????????
//?調(diào)用getAll方法獲得所有動態(tài)表中的數(shù)據(jù)
????????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();
????????}

????????
//?調(diào)用search方法查詢動態(tài)表
????????List<Map>?returnList?=?(List)?groovyObject.invokeMethod("search",?map);
????????
for?(Map?map2?:?returnList)?{
????????????
//?同理此處根據(jù)FromAttribute而定
????????????System.out.println(map2.get("id"));
????????????System.out.println(map2.get(
"name"));
????????????System.out.println(map2.get(
"type"));
????????}

????}
FormGenerator : 創(chuàng)建訪問數(shù)據(jù)庫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.springframework.jdbc.core.RowMapper
import?org.springframework.jdbc.core.RowMapperResultSetExtractor
import?com.glnpu.sige.core.dao.DataSourceFactory
import?org.apache.commons.lang.builder.ToStringBuilder;
import?org.apache.commons.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}]
????????
<#assign?size?=?entity.formAttributeList?size/>
????????def?
int[]?types=[<#list?1..size+1?as?p>Types.VARCHAR,<#rt/></#list>]
????????
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 相關(guān)代碼,以及如何利用Groovy動態(tài)的對數(shù)據(jù)庫進(jìn)行創(chuàng)建和增刪改查操作,了解以上的原理后就可以方便的在運行時利用freemarker生成表示層頁面以及代碼來進(jìn)行展示。
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎!定制產(chǎn)品紅包拿不停!

總結(jié)

以上是生活随笔為你收集整理的动态表单及动态建表实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。