<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    limq

    rainman
    隨筆 - 19, 文章 - 2, 評(píng)論 - 115, 引用 - 1
    數(shù)據(jù)加載中……

    動(dòng)態(tài)表單及動(dòng)態(tài)建表實(shí)現(xiàn)原理

     

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

        2 實(shí)現(xiàn)工具

    Hibernate + Spring + Groovy +Freemarker

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

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

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

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

     

        3 實(shí)現(xiàn)原理

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

    測(cè)試代碼:
    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(falsetrue);
            }
     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ù)庫(kù)后 就要利用groovy動(dòng)態(tài)創(chuàng)建訪問(wèn)代碼了:先看測(cè)試代碼 再看具體實(shí)現(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ù)庫(kù)中的名稱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方法獲得所有動(dòng)態(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方法查詢動(dòng)態(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)建訪問(wèn)數(shù)據(jù)庫(kù)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動(dòng)態(tài)的對(duì)數(shù)據(jù)庫(kù)進(jìn)行創(chuàng)建和增刪改查操作,了解以上的原理后就可以方便的在運(yùn)行時(shí)利用freemarker生成表示層頁(yè)面以及代碼來(lái)進(jìn)行展示。

    posted on 2009-09-19 21:12 limq 閱讀(8536) 評(píng)論(4)  編輯  收藏 所屬分類: 編程技巧

    評(píng)論

    # re: 動(dòng)態(tài)表單及動(dòng)態(tài)建表實(shí)現(xiàn)原理  回復(fù)  更多評(píng)論   

    有時(shí)間試試 我們公司也有表單定義 但是確實(shí)在開發(fā)過(guò)程中使用
    正式發(fā)布后不能定義表單了
    沒(méi)有多態(tài)性可言
    2009-09-19 23:06 | wangchangbing

    # re: 動(dòng)態(tài)表單及動(dòng)態(tài)建表實(shí)現(xiàn)原理  回復(fù)  更多評(píng)論   

    表、代碼生成其實(shí)不難,關(guān)鍵點(diǎn)就是Groovy避免了熱部署問(wèn)題
    2009-09-20 08:54 | 路人甲

    # re: 動(dòng)態(tài)表單及動(dòng)態(tài)建表實(shí)現(xiàn)原理  回復(fù)  更多評(píng)論   

    sdkf睡得很死都會(huì)發(fā)生地方
    2009-09-20 11:39 | 99讀書人

    # re: 動(dòng)態(tài)表單及動(dòng)態(tài)建表實(shí)現(xiàn)原理[未登錄](méi)  回復(fù)  更多評(píng)論   

    這個(gè)解決方案非常好。
    2010-04-27 18:21 | adam
    主站蜘蛛池模板: 久久免费精彩视频| 久久精品国产亚洲av高清漫画| 看免费毛片天天看| 国产精品色午夜免费视频| 亚洲国产精品日韩av不卡在线| 国产成人免费高清激情视频| 亚洲第一成人在线| 最近最好的中文字幕2019免费| 亚洲a视频在线观看| 两个人的视频高清在线观看免费| 精品亚洲AV无码一区二区| 免费无码又黄又爽又刺激| 中文日韩亚洲欧美制服| 日韩一区二区在线免费观看| 亚洲AV综合永久无码精品天堂| 在线观看免费精品国产| 羞羞漫画登录页面免费| 亚洲欧洲国产成人综合在线观看| 72pao国产成视频永久免费| 亚洲精品一品区二品区三品区| 免费国产在线视频| 自怕偷自怕亚洲精品| 99久久99久久精品免费看蜜桃| 亚洲精品天堂在线观看| 永久免费毛片手机版在线看| 日日摸日日碰夜夜爽亚洲| 亚洲精品无码AV中文字幕电影网站| 久99久无码精品视频免费播放| 亚洲AV无码国产精品麻豆天美| 最近免费视频中文字幕大全| 亚洲a级片在线观看| 宅男666在线永久免费观看| 日本激情猛烈在线看免费观看 | 国产啪精品视频网站免费尤物| 亚洲AV无码久久精品成人| 91高清免费国产自产| 亚洲日韩av无码中文| 亚洲成a人片在线观看日本麻豆| 99免费精品视频| 亚洲日韩乱码久久久久久| 全免费一级毛片在线播放|