[原创]基于 Hibernate 的自定义表单 实现方案申明:本方案只是初步的解决思路,供大家参考、讨论。关于自定义
[原创]基于 Hibernate 的自定义表单 实现方案
申明:本方案只是初步的解决思路,供大家参考、讨论。
关于自定义表单网上讨论的很多,个人比较偏向于基于Hibernate的解决方式,原因很简单,如果能够将用户自定义的字段信息通过Hibernate的方式存储,那么具备了Hibernate所带来的一切方便,比如:跨数据库等等。
但是有难度:
1、我们通常是先写一个静态的POJO,然后把它的属性映射到数据库表,那么,在字段不确定的情况下,如果把这些不确定的字段映射到数据库呢?当然可以通过cglib或javassist等等字节码工具动态生成class文件。
2、我们知道Hibernate是在服务器启动的时候,根据hbm映射文件创建表,那么在我们启动时候并不知道表信息的时候,如果在运行时,创建表呢?
第一个问题答案:
我们不一定要做POJO到数据库的映射,Hibernate的实体类型也可以是xml文档、Map,也就是说我们可以用户的表单信息做为xml文档或则Map提交给Hibernate处理。
第二个问题答案:
通过分析Hibernate源代码,我们可以在服务器运行中,请求Hibernate动态创建表,代码如下:
从 SessionFactory中拿到配置信息(不要去创建新的实例),增加HBM映射文件到Configuration ,请求Hibernate更新数据库。
/** * @author Li Tonggang * @email love4ajax@gmail.com */public class CustomAction extends BaseAction{ public String execute() throws MappingException, IOException{ SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) Service.getService("sessionFactory"); LocalSessionFactoryBean localSessionFactory = (LocalSessionFactoryBean) Service.getService("&sessionFactory"); // 从localSessionFactory拿到配置信息Configuration ,并且增加HBM映射文件到Configuration Configuration config = localSessionFactory.getConfiguration(); Resource mappingLocation = new ClassPathResource("custom.hbm.xml"); config.addInputStream(mappingLocation.getInputStream()); // 从SessionFactory中拿到属性配置信息 Settings settings = sessionFactory.getSettings(); // 请求 Hibernate 创建表 if ( settings.isAutoUpdateSchema() ) { new SchemaUpdate( config, settings ).execute( false, true ); } return super.SUCCESS; }} 强烈支持楼主~!

2 楼 love4ajax 2007-08-23 有兴趣的朋友可以留下意见,继续交流一下。 3 楼 chenxu 2007-08-27 <p>关于这个问题我非常的有兴趣。早在2005年低的一个项目中我们就遇到了这种需求:系统实用hibernate作为持久层,但是有这种动态建表并访问的需求。当时我就想到了利用Configuration中提供的方法来动态的更新持久化对象。但是因为项目中考虑到这样做的事务 和缓存的问题,以及可能遇到的风险 ,最后还是放弃了这种做法。最后采用了比较可靠的方式:不更新持久化类,利用动态拼装jdbc来实现对动态增加的库表的访问。<br/>
????? 最后这种做法也效果不错,唯一不足的地方是:因为没有持久化,所以不能利用hibernate的二级缓存,并且在代码中动态拼装了很多sql语句。<br/>
???? 你的这种做法不知道在具体的项目实践中应用过没有?! 有没有验证过对于事务和缓存的影响!如果都验证过的话,那不失为一个比较好的方案!</p> 4 楼 chenxu 2007-08-27 不过此典型问题我想在javaeye中的许多大牛中应该有遇到过吧!
希望有对此问题好的解决方案的朋友给点意见哦? 5 楼 wenxiaogen 2007-08-27 chenxu 写道不过此典型问题我想在javaeye中的许多大牛中应该有遇到过吧!
希望有对此问题好的解决方案的朋友给点意见哦?牛人
6 楼 love4ajax 2007-08-27 测试通过map代替pojo以及运行中加载hbm文件动态生成表,更深入的东西还没来得及研究。 7 楼 chinapr 2007-09-03 <br/>
<strong>chenxu 写道:</strong><br/>
<div class='quote_div'>
<p>关于这个问题我非常的有兴趣。早在2005年低的一个项目中我们就遇到了这种需求:系统实用hibernate作为持久层,但是有这种动态建表并访问的需求。当时我就想到了利用Configuration中提供的方法来动态的更新持久化对象。但是因为项目中考虑到这样做的事务 和缓存的问题,以及可能遇到的风险 ,最后还是放弃了这种做法。最后采用了比较可靠的方式:不更新持久化类,利用动态拼装jdbc来实现对动态增加的库表的访问。<br/>
????? 最后这种做法也效果不错,唯一不足的地方是:因为没有持久化,所以不能利用hibernate的二级缓存,并且在代码中动态拼装了很多sql语句。<br/>
???? 你的这种做法不知道在具体的项目实践中应用过没有?! 有没有验证过对于事务和缓存的影响!如果都验证过的话,那不失为一个比较好的方案!</p>
</div>
<br/>
<br/>
<br/>
<br/>
我也是用同样的方法来实现.hibernate弄这个是有难度啊! 8 楼 wangweij 2007-09-04 我们上一个项目就是这样做的.后来总结时得出个结果!!!!!! 要struts的Form何用????????? 9 楼 casheen 2007-09-04 我已经做个一个动态表单,现在正在规划实现第二个版本。
我们的思路是,一个Form关联多个Field,分别存放在两张表中。逻辑较复杂,特别是更新字段时比较难以实现,但方案确实可行。 10 楼 casheen 2007-09-04 总共四个对象,Form,Field,FormData,FieldData。其中Form中存放动态表单信息,相当于一个规则;FormData中存放的是由Form这个规则生成表单;Field是动态表单中的字段规则,与动态表单是多对一关联关系,指定字段的类型,长度,最大值,最小值,默认值等;FieldData是由Field这个规则生成的字段信息。
关系如下:
Form 1 ---- n Field
1| 1|
| |
| |
n| n|
FormData 1 ---- n FieldData
11 楼 wangweij 2007-09-04 不好意思.刚没看懂楼主说的.不知道你说的自定义表单具体指的是什么.理解能力有问题:) 12 楼 love4ajax 2007-09-04 wangweij 写道不好意思.刚没看懂楼主说的.不知道你说的自定义表单具体指的是什么.理解能力有问题:)就是用户填写的表单不是由程序员预先设计好的,而是有用户自己设计表单。 13 楼 wangweij 2007-09-04 那是要存用户定义的表单.还是表单中的数据? 14 楼 braveheartcc 2007-09-24 楼主 这样 不用更新sessionfactory就可以 实现动态映射了吗 15 楼 Wallian_hua 2007-09-29 学习了.. 看来个人经验还是不够吖...
期待有更好的文章. 16 楼 foxgst 2007-09-30 自定义表单,说的应该是系统运行过程中用户(有一定开发能力的技术人员?)自定义的映射于新创建的POJO(或者新的实体)的表单。