- 浏览: 25290 次
- 性别:
- 来自: 重庆
文章分类
最新评论
-
guanfj:
了解一下,你以目前的修改的方案做的系统目前还在运行着吗?
Hibernate自定义表单完全解决方案(无需重置SessionFactory) -
zhushaolong:
问一下你用的hibernate的版本是多少啊?我怎么没有在Pe ...
Hibernate自定义表单解决方案补遗 -
firmgoal:
<div class="quote_title ...
Hibernate自定义表单完全解决方案(无需重置SessionFactory) -
bribin:
不得不对LZ说一句,你太牛了,怎么连Configuration ...
Hibernate自定义表单完全解决方案(无需重置SessionFactory) -
onlydo:
还有下文么?我对这个很感兴趣阿。用jpa的话要怎么实现?
另外 ...
Hibernate自定义表单完全解决方案(无需重置SessionFactory)
Hibernate自定义表单完全解决方案(无需重置SessionFactory)
最近开发的一个系统,需要在不更改代码和重启系统的情况下提供对用户自动建表的支持,由于系统应用了hibernate,所以在建表同时也要建立持久化对象以及对这些对象注册,人渣我首先想倒的是 baidu和google,哪知一番搜索下来,发现都不尽入人意,于是乎,造轮子之路开始了
数据库我是采用的oracle9i,目前在比如数据库类型支持,还有对象关系支持上都很简单,不过在现有基础上进行扩展,都是可以实现的
实现步骤如下
建立class->生成hbm.xml->在Hibernate'config里面注册持久化类->通知SessionFactory持久化类的新增
1 准备
首先准备基础数据,我建立了几个类来对生成的表和属性做描述 这些描述都将作为传输传递给class生成方法和hbm.xml的生成方法
RenderClass 描述要生成的实体类 属性如下
RenderProperty 就是properties集合的内容 属性如下
2 生成class
采用ASM 生成
3 生成hbm.xml
生成这种事情,当然是交给模板了,我这里用的是Freemarker,在这里,我要感谢freemarker的开发组,感谢webwork 感谢XXCMS系统对freemarker以及其他模板语言的大力推广,,感谢。。。。(省略100字)
模板嘛,肯定不仅仅是应用在web环境的,看看源代码下的freemarker.cache包,恩,不错,freemarker团队确实是有一定“野心”的 首先是渲染的实现
然后就是准备模板了,首先声明,我这个模板写得简单粗陋之极,不过粗陋简单不正是人渣偶的终极处世之道么,何况只实现几个简单功能,仅仅是针对测试而已嘛,何必搞得那么正规严肃了,嘿嘿
4 注册
首先是对生成的hbm.xml的注册,比如,我获取倒Hibernate的一个config以后
然后就是要通知sessionFactory,新增了持久类,目前很多方法都是重启sessionfactory,就是关闭当前 sessionFactory ,然后根据config build一个新的sessionFactory出来,但是,这种情况感觉总不那么完美,虽然这个过程持续不到多长时间,但用户每增一个表就close然后build一个,单说用户体验,人家正在提交数据了,你把这个给close了....
但目前hibernate包的 sessionFactory 确实没提供这种对持久类的add支持,XX伟人说过:没有条件 创造条件也要上,于是乎,拿起你的键盘,启动 editplus,向hibernate3的源码砍去。。
其实,改动地方也不大。
然后是SessionFactoryImpl 我们要让他知道,这个世界上还存在很多未知的来客,需要你去主动了解。。。。
增加代码如下
最后遗留的是hbm.xml在cfg.xml的注册,以保证系统重启后可以顺利加载新增的持久化配置
最后是总结测试,写个junit 搞定 代码如下:
同意楼上这位老兄的话。POJO/MAP/DOM4J这三种模型,最适合Hibernate来做自定义表单的是DOM4J,不需要生成实体类,输入、输出是XML,能够直接用Freemarker或者XSLT进行页面操作处理。完全可以屏蔽掉Class生成的问题。至于SessionFactory的新加入映射,可能如果没有如底层代码研究得太多的,贸然去改,会引起不少问题,比如新的映射和以前映射的关联等等。
喜欢简单可以考虑看看iBatis,值得一看
动态创建列的实在是司空见惯的事情。
楼主能否列一下,你研究过哪些商用产品的数据库结构呢?都研究什么样的功能了呢?有没有自定义实体的啊?
能否麻烦LZ抽时间列出来,让javaeyer们开开眼界?
说个还有点印象的,有一个XXXXX软件,这个系统安装完只是个骨架不能立刻给用户使用,需要针对客户的业务配置和开发,配置就是自定义实体,自定义字段,开发就是用它自带的DSL语言写规则,这个过程是用dev角色登陆进去一切都在WEB界面上完成。
实体结构表和实体值是分开存放的。实体结构:字段名,字段类型,所属实体,实体值表里是字段主键,字符型值,数字型值,XML值,公式值,TREE值,用户输入的值根据数据类型保存到不同的列,和其它的实体交互用系统提供的DSL语言完成。
感觉系统维护一个元数据结构,结构还是算清晰。
当时也有过疑问,为什么不通过动态建物理表实现这功能。
动态创建列的实在是司空见惯的事情。
楼主能否列一下,你研究过哪些商用产品的数据库结构呢?都研究什么样的功能了呢?有没有自定义实体的啊?
能否麻烦LZ抽时间列出来,让javaeyer们开开眼界?
哥们啊,你真是给我找事干。
介于本主题的纯洁性问题,本人另开一贴,有兴趣的过来拍砖
http://www.iteye.com/topic/241508
确实不一定是动态建表,自定义对象,字段可以通过设计来实现
很多内容管理系统的设计思路都是基于表结构的变化来适应复杂的非结构化数据的,像IBM的CM,EMC2的Documental(可能拼错了),相比于扩展属性的表结构设计,大数据量的情况下动态建表的方法可以减少数据行数。也更利于优化查询
拜托!!我所知道的排在前几名的开源内容管理系统,都没有动态建表!!
CMS了解不多,不过你去看看Salesforce、Microsoft Dynamics CRM、Oracle CRM/ERP、SAP CRM/ERP 应用型产品,哪个不是需要动态建立实体的
数据库我是采用的oracle9i,目前在比如数据库类型支持,还有对象关系支持上都很简单,不过在现有基础上进行扩展,都是可以实现的
实现步骤如下
建立class->生成hbm.xml->在Hibernate'config里面注册持久化类->通知SessionFactory持久化类的新增
1 准备
首先准备基础数据,我建立了几个类来对生成的表和属性做描述 这些描述都将作为传输传递给class生成方法和hbm.xml的生成方法
RenderClass 描述要生成的实体类 属性如下
- className 类名
- tableName 对应表名
- properties 属性集合
RenderProperty 就是properties集合的内容 属性如下
- name 属性名称
- type java类型
- field 字段名
- primary 是否主键
- sequence 对应ID生成的sequence
- length 对应长度
2 生成class
采用ASM 生成
/** * 根据传入参数创建CLASS文件 * * @param 类名 * @param 保存路径 * @param 属性描述 * @return Class */ public Class build(String clsname,String savepath,Collection properties) { Class cls = null; try { String classname = BuildUtil.transferClassName(clsname); ClassWriter cw = new ClassWriter(false); //建立构造函数 cw.visit(V1_1, ACC_PUBLIC, classname, null, "java/lang/Object", null); MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mw.visitVarInsn(ALOAD, 0); mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mw.visitInsn(RETURN); mw.visitMaxs(1, 1); mw.visitEnd(); BuildProperty property = null; String propertytype = null; String propertyname = null;; //建立属性 Iterator iterator = properties.iterator(); while (iterator.hasNext()) { //建立属性对应的类变量 property = (BuildProperty)iterator.next(); propertytype = BuildUtil.transferClassName(property.getType()); propertyname = WordUtils.capitalize(property.getName()); cw.visitField(ACC_PRIVATE, property.getName(), "L"+propertytype+";", null, null).visitEnd(); //建立get方法 mw = cw.visitMethod(ACC_PUBLIC, "get"+propertyname, "()L"+propertytype+";", null, null); mw.visitCode(); mw.visitVarInsn(ALOAD, 0); mw .visitFieldInsn(GETFIELD, classname, property.getName(), "L"+propertytype+";"); mw.visitInsn(ARETURN); mw.visitMaxs(1, 1); mw.visitEnd(); //建立set方法 mw = cw.visitMethod(ACC_PUBLIC, "set"+propertyname, "(L"+propertytype+";)V", null, null); mw.visitCode(); mw.visitVarInsn(ALOAD, 0); mw.visitVarInsn(ALOAD, 1); mw .visitFieldInsn(PUTFIELD, classname, property.getName(), "L"+propertytype+";"); mw.visitMaxs(2, 2); mw.visitInsn(RETURN); mw.visitEnd(); } cw.visitEnd(); byte[] code = cw.toByteArray(); if (savepath!=null) { Assistant.createNewFile(savepath); FileOutputStream fos = new FileOutputStream(savepath); fos.write(code); fos.close(); } cls = this.defineClass(clsname, code, 0, code.length); return cls; } catch (Throwable e) { e.printStackTrace(); } return cls; }
3 生成hbm.xml
生成这种事情,当然是交给模板了,我这里用的是Freemarker,在这里,我要感谢freemarker的开发组,感谢webwork 感谢XXCMS系统对freemarker以及其他模板语言的大力推广,,感谢。。。。(省略100字)
模板嘛,肯定不仅仅是应用在web环境的,看看源代码下的freemarker.cache包,恩,不错,freemarker团队确实是有一定“野心”的 首先是渲染的实现
package com.mit.cooperate.core.asm.render; import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; import java.io.StringWriter; import javax.servlet.ServletContext; import com.mit.cooperate.core.util.Assistant; import freemarker.cache.ClassTemplateLoader; import freemarker.template.Configuration; import freemarker.template.ObjectWrapper; import freemarker.template.SimpleHash; import freemarker.template.Template; import freemarker.template.TemplateExceptionHandler; /** * freeMarker模板渲染 * @author courser.tijichen */ public class FreemarkerRender implements Render{ private Configuration templateconfig; public FreemarkerRender() { this.initialize(); } /** * 初始化freemarker配置 * */ public void initialize() { try { if (templateconfig==null) { templateconfig = new Configuration(); templateconfig.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER); templateconfig.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER); templateconfig.setTemplateLoader(new ClassTemplateLoader(this.getClass(),"/")); templateconfig.setTemplateUpdateDelay(1200); templateconfig.setDefaultEncoding("gb2312"); templateconfig.setLocale(new java.util.Locale("zh_CN")); templateconfig.setNumberFormat("0.##########"); } } catch (Exception e) {} } /** * 渲染 * */ public void render(RenderClass target,String template,String outpath) { try { StringWriter writer = new StringWriter(); Template tl = templateconfig.getTemplate( template, templateconfig.getLocale()); SimpleHash root = new SimpleHash(); root.put("entity", target); tl.process(root, writer); Assistant.createNewFile(outpath); FileOutputStream fos = new FileOutputStream(outpath); PrintWriter pwriter = new PrintWriter(fos); pwriter.write(writer.toString()); pwriter.close(); fos.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
然后就是准备模板了,首先声明,我这个模板写得简单粗陋之极,不过粗陋简单不正是人渣偶的终极处世之道么,何况只实现几个简单功能,仅仅是针对测试而已嘛,何必搞得那么正规严肃了,嘿嘿
<?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.className}" table="${entity.tableName}"> <#if entity.properties?exists> <#list entity.properties as property> <#if property.primary> <id name="${property.name}" type="${property.type}"> <#else> <property name="${property.name}" type="${property.type}"> </#if> <#if property.type=="java.lang.String"> <column name="${property.field?upper_case}" <#if property.length?exists>length="${property.length}"</#if>></column> <#elseif property.type=="java.util.Date"> <column name="${property.field?upper_case}" length=7></column> <#elseif property.type=="java.lang.Long" || property.type=="java.lang.Integer" || property.type=="java.lang.Short"> <column name="${property.field?upper_case}" <#if property.length?exists>precision="${property.length}"</#if> scale="0"></column> </#if> <#if property.primary==true> <#if property.sequence?exists> <generator class="sequence"> <param name="sequence">${property.sequence}</param> </generator> </#if> </id> <#else> </property> </#if> </#list> </#if> </class> </hibernate-mapping>
4 注册
首先是对生成的hbm.xml的注册,比如,我获取倒Hibernate的一个config以后
URL url = this.getClass().getResource("/com/mit/test/person.hbm.xml"); config.addURL(url);
然后就是要通知sessionFactory,新增了持久类,目前很多方法都是重启sessionfactory,就是关闭当前 sessionFactory ,然后根据config build一个新的sessionFactory出来,但是,这种情况感觉总不那么完美,虽然这个过程持续不到多长时间,但用户每增一个表就close然后build一个,单说用户体验,人家正在提交数据了,你把这个给close了....
但目前hibernate包的 sessionFactory 确实没提供这种对持久类的add支持,XX伟人说过:没有条件 创造条件也要上,于是乎,拿起你的键盘,启动 editplus,向hibernate3的源码砍去。。
其实,改动地方也不大。
一是,改动Configuration,三句话 public Mapping getMapping() { return this.mapping; }
然后是SessionFactoryImpl 我们要让他知道,这个世界上还存在很多未知的来客,需要你去主动了解。。。。
增加代码如下
public void addPersistentClass(PersistentClass model,Mapping mapping) { if ( !model.isInherited() ) { IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator( settings.getDialect(), settings.getDefaultCatalogName(), settings.getDefaultSchemaName(), (RootClass) model ); if (!identifierGenerators.containsKey(model.getEntityName())) identifierGenerators.put( model.getEntityName(), generator ); } model.prepareTemporaryTables( mapping, settings.getDialect() ); String cacheRegion = model.getRootClass().getCacheRegionName(); CacheConcurrencyStrategy cache = CacheFactory.createCache( model.getCacheConcurrencyStrategy(), cacheRegion, model.isMutable(), settings, properties ); if (cache!=null) allCacheRegions.put( cache.getRegionName(), cache.getCache() ); EntityPersister cp = PersisterFactory.createClassPersister(model, cache, this, mapping); if ( cache != null && cache.getCache() instanceof OptimisticCache ) { ( ( OptimisticCache ) cache.getCache() ).setSource( cp ); } entityPersisters.put( model.getEntityName(), cp ); }
最后遗留的是hbm.xml在cfg.xml的注册,以保证系统重启后可以顺利加载新增的持久化配置
/** * 把hbm.xml的路径加入到cfg.xml的mapping结点 * * @param cfg.xml的路径 * @param hbm.xml的路径 */ public static void updateHbmCfg(URL url,String hbm) { try { SAXReader reader = new SAXReader(); Document doc = reader.read(url); Element element = (Element)doc.getRootElement() .selectSingleNode("session-factory"); Element hbmnode = element.addElement("mapping"); hbmnode.addAttribute("resource", hbm); String filepath = url.getFile(); if (filepath.charAt(0)=='/') filepath = filepath.substring(1); FileOutputStream outputstream = new FileOutputStream(filepath); XMLWriter writer = new XMLWriter(outputstream); writer.write(doc); outputstream.close(); } catch (Exception e) { e.printStackTrace(); } }
大功告成 ,先运行一个小周天
最后是总结测试,写个junit 搞定 代码如下:
package com.mit.cooperate.core.hibernate; import junit.framework.TestCase; import java.net.URL; import java.util.ArrayList; import org.apache.commons.beanutils.PropertyUtils; import org.hibernate.Session; import org.hibernate.cfg.Configuration; import org.hibernate.SessionFactory; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.impl.SessionFactoryImpl; import org.hibernate.mapping.PersistentClass; import org.hibernate.Transaction; import com.mit.cooperate.core.asm.*; import com.mit.cooperate.core.asm.render.*; public class HibernateTest extends TestCase { private Configuration config; private SessionFactory factory; public void setUp() { URL url = this.getClass().getResource("/com/mit/cooperate/core/hibernate/hibernate.cfg.xml"); config = new Configuration().configure(url); factory = config.buildSessionFactory(); } public void testBuild() throws Exception { //持久类对象描述 RenderClass rc = new RenderClass(); ArrayList list = new ArrayList(); RenderProperty property = new RenderProperty(); //添加主键 property.setName("oid"); property.setField("oid"); property.setLength(new Integer(15)); property.setPrimary(true); property.setType(Long.class.getName()); property.setSequence("SEQ_PERSON"); list.add(property); //添加一个name字段 property = new RenderProperty(); property.setName("name"); property.setType(String.class.getName()); property.setField("name"); property.setLength(new Integer(20)); list.add(property); rc.setProperties(list); //类名 rc.setClassName("com.mit.test.Person"); rc.setTableName("person"); //开始生成class POBuildUtil util = new POBuildUtil(); util.build(rc.getClassName(),"E:\\cpc\\source\\cooperateCore\\com\\mit\\test\\Person.class",list); //实例化一个person Object person = Class.forName("com.mit.test.Person").newInstance();//hbmcls.newInstance(); //开始生成hbm.xml FreemarkerRender render = new FreemarkerRender(); render.render(rc, Templates.TEMPLATE_HIBERNATE3, "E:\\cpc\\source\\cooperateCore\\com\\mit\\test\\person.hbm.xml"); URL url = this.getClass().getResource("/com/mit/test/person.hbm.xml"); config.addURL(url); //更新hibernate.cfg.xml HibernateUtil.updateHbmCfg( this.getClass().getResource("/com/mit/cooperate/core/hibernate/hibernate.cfg.xml"), "com/mit/test/person.hbm.xml"); PersistentClass model = config.getClassMapping("com.mit.test.Person"); //sessionFactory哪下子,快接纳person爷爷进去 ((SessionFactoryImpl)factory).addPersistentClass(model, config.getMapping()); //生成数据库 SchemaExport export = new SchemaExport(config,((SessionFactoryImpl)factory).getSettings()); export.execute(true, true,false,true); //测试一下,随便给个名字什么的 PropertyUtils.setProperty(person, "name", "chenzhi"); Session session = factory.openSession(); Transaction tran = session.beginTransaction(); try { //保存 session.save(person); tran.commit(); } catch (Exception e) { e.printStackTrace(); tran.rollback(); } finally { session.close(); } } public void tearDown() { factory.close(); } }
评论
60 楼
guanfj
2015-06-02
了解一下,你以目前的修改的方案做的系统目前还在运行着吗?
59 楼
firmgoal
2008-11-10
hantsy 写道
为什么还生成类和映射文件。。。
hibernate 支持pojo, map, jdom三种模型。我们最常用的是pojo的方式。
为什么要死盯着用pojo的方式呢?
hibernate 支持pojo, map, jdom三种模型。我们最常用的是pojo的方式。
为什么要死盯着用pojo的方式呢?
同意楼上这位老兄的话。POJO/MAP/DOM4J这三种模型,最适合Hibernate来做自定义表单的是DOM4J,不需要生成实体类,输入、输出是XML,能够直接用Freemarker或者XSLT进行页面操作处理。完全可以屏蔽掉Class生成的问题。至于SessionFactory的新加入映射,可能如果没有如底层代码研究得太多的,贸然去改,会引起不少问题,比如新的映射和以前映射的关联等等。
58 楼
bribin
2008-11-09
不得不对LZ说一句,你太牛了,怎么连Configuration与SessionFactoryImpl的代码都改了。。。。太暴力了吧!
有空看看我的问题,看看有没有办法解。。。。解法要温柔点的。。。。
http://www.iteye.com/problems/6520
有空看看我的问题,看看有没有办法解。。。。解法要温柔点的。。。。
http://www.iteye.com/problems/6520
57 楼
onlydo
2008-10-09
还有下文么?我对这个很感兴趣阿。用jpa的话要怎么实现?
另外问一句:行变列,列变行的做法对性能有多大影响?有关联属性的话,查询的时候够呛阿。
另外问一句:行变列,列变行的做法对性能有多大影响?有关联属性的话,查询的时候够呛阿。
56 楼
aidsag
2008-10-02
太牛了 那个ASM也是个框架吗?
55 楼
tq04q5k
2008-09-20
还是没搞懂,按照LZ这个解释若不重新做SessionFactory,若新增了实体类,是肯定要重启系统的,重启之后才会生成正真的表或者字段,不知道我这样理解对不对?
显示开发中应该没这种重启系统的可能。
显示开发中应该没这种重启系统的可能。
54 楼
。。。
2008-09-15
以前对Freemarker的认识停留在Web上面,认为那玩艺就是个视图表现的东西, 前段时间作了个小的分析规则的东西,用它来生成规则模板, 对Freemarker的模板引擎实在是感动的想哭.....
言归正传, 我很希望了解到LZ在实际生产环境中这样做有没有出过什么问题? 稳定性如何?
言归正传, 我很希望了解到LZ在实际生产环境中这样做有没有出过什么问题? 稳定性如何?
53 楼
。。。
2008-09-15
panlw 写道
Spring的JDBC封装即简单又灵活,还有S2Dao也不错的。
喜欢简单可以考虑看看iBatis,值得一看
52 楼
soci
2008-09-14
重复了
51 楼
soci
2008-09-14
comeon 写道
soci 写道
研究过几个商用产品的数据库结构,动态建实体的没见过,
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
动态创建列的实在是司空见惯的事情。
楼主能否列一下,你研究过哪些商用产品的数据库结构呢?都研究什么样的功能了呢?有没有自定义实体的啊?
能否麻烦LZ抽时间列出来,让javaeyer们开开眼界?
说个还有点印象的,有一个XXXXX软件,这个系统安装完只是个骨架不能立刻给用户使用,需要针对客户的业务配置和开发,配置就是自定义实体,自定义字段,开发就是用它自带的DSL语言写规则,这个过程是用dev角色登陆进去一切都在WEB界面上完成。
实体结构表和实体值是分开存放的。实体结构:字段名,字段类型,所属实体,实体值表里是字段主键,字符型值,数字型值,XML值,公式值,TREE值,用户输入的值根据数据类型保存到不同的列,和其它的实体交互用系统提供的DSL语言完成。
感觉系统维护一个元数据结构,结构还是算清晰。
当时也有过疑问,为什么不通过动态建物理表实现这功能。
50 楼
comeon
2008-09-14
soci 写道
研究过几个商用产品的数据库结构,动态建实体的没见过,
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
动态创建列的实在是司空见惯的事情。
楼主能否列一下,你研究过哪些商用产品的数据库结构呢?都研究什么样的功能了呢?有没有自定义实体的啊?
能否麻烦LZ抽时间列出来,让javaeyer们开开眼界?
49 楼
comeon
2008-09-14
关于自定义实体功能(公司没有用HIBERNATE来做ORM,软件构建那时Hibernate,对数据库的横切,竖切支持有限)。
LZ的文章写的不错,看过了。谢谢分享。
有句话叫:没有调查就没有发言权!
无论是动创建表还是动态创建视图,都是一种改变或保存数据集的方式。
至于是否动态创建表,请自定义一个实体之后进入CRM的DB去查看是否有新表或者新的视图产生。
个人观点动态创建表或动态创建视图均可做为一种解决问题的手段,据不同情况应用而生。
比如:客户要创建一个公司的内部考勤表,这个表只与用户关联,与其他的表不再关联的时候,就可以创建表啊。
动态创建表,是指可以动态创建表,在需要的时候创建,来存储相关数据,并非每次都动态创建。
楼上有人争辨说一定要看到动态创建的语句,那么请先自行试验一下,当在自定义实体的时候,看看动态创建语句是否出现在 MS CRM 的 DB 的事件探查器中。我想应该可以看到的(个人判断,不方便装MS CRM,请见谅)。其次,个人觉得,自定义实体的相关信息(实体名,字段,字段类型等)应该存储在另一张(些)自定义实体的表中。
我想楼上觉得有争议的javaeyer肯定没有自己研究或者实现过自定义实体。
其实这些思路,已经说的相当清晰了。你可以借着我的思路实现你的自定义实体功能。
至于LZ的主题,以及各楼的发言,《Java Persistence with Hibernate》上有这么一句话"Java developers blame relateional technology for the mismatch; data professionals blame object technology." 对于楼上的争议形容的如此准确(一个从SQL的角度讲动态创建表不是建议做的,一个从开发的角度来讲动态创建表帮助我们实现了某种重要的功能)。
if you have good choice, please write it out!
LZ的文章写的不错,看过了。谢谢分享。
有句话叫:没有调查就没有发言权!
无论是动创建表还是动态创建视图,都是一种改变或保存数据集的方式。
至于是否动态创建表,请自定义一个实体之后进入CRM的DB去查看是否有新表或者新的视图产生。
个人观点动态创建表或动态创建视图均可做为一种解决问题的手段,据不同情况应用而生。
比如:客户要创建一个公司的内部考勤表,这个表只与用户关联,与其他的表不再关联的时候,就可以创建表啊。
动态创建表,是指可以动态创建表,在需要的时候创建,来存储相关数据,并非每次都动态创建。
楼上有人争辨说一定要看到动态创建的语句,那么请先自行试验一下,当在自定义实体的时候,看看动态创建语句是否出现在 MS CRM 的 DB 的事件探查器中。我想应该可以看到的(个人判断,不方便装MS CRM,请见谅)。其次,个人觉得,自定义实体的相关信息(实体名,字段,字段类型等)应该存储在另一张(些)自定义实体的表中。
我想楼上觉得有争议的javaeyer肯定没有自己研究或者实现过自定义实体。
其实这些思路,已经说的相当清晰了。你可以借着我的思路实现你的自定义实体功能。
至于LZ的主题,以及各楼的发言,《Java Persistence with Hibernate》上有这么一句话"Java developers blame relateional technology for the mismatch; data professionals blame object technology." 对于楼上的争议形容的如此准确(一个从SQL的角度讲动态创建表不是建议做的,一个从开发的角度来讲动态创建表帮助我们实现了某种重要的功能)。
if you have good choice, please write it out!
48 楼
javaTo
2008-09-13
jacklondon 写道
"添加自定义对象和活动" 不等于运行时创建表啊!!
不要故意混淆概念!!请给出 Microsoft Dynamics CRM 3.0 运行时创建表的步骤!
不要故意混淆概念!!请给出 Microsoft Dynamics CRM 3.0 运行时创建表的步骤!
哥们啊,你真是给我找事干。
介于本主题的纯洁性问题,本人另开一贴,有兴趣的过来拍砖
http://www.iteye.com/topic/241508
47 楼
soci
2008-09-13
javaTo 写道
呵呵,ls挺不服气啊,看来要拿点铁证出来了
引用Microsoft Dynamics CRM 3.0产品特性上的一段话,http://www.microsoft.com/china/dynamics/product/crm3.mspx
来自salesforce,他们提供试用,你可以申请个帐号去看看
引用Microsoft Dynamics CRM 3.0产品特性上的一段话,http://www.microsoft.com/china/dynamics/product/crm3.mspx
引用
方便的自定义,可针对您的业务工作流程来自定义 Microsoft Dynamics CRM,方法如下:添加自定义对象和活动、为不同用户设计自定义视图,以及将业务逻辑应用到 CRM 中。
来自salesforce,他们提供试用,你可以申请个帐号去看看
确实不一定是动态建表,自定义对象,字段可以通过设计来实现
46 楼
javaTo
2008-09-13
呵呵,ls挺不服气啊,看来要拿点铁证出来了
引用Microsoft Dynamics CRM 3.0产品特性上的一段话,http://www.microsoft.com/china/dynamics/product/crm3.mspx
来自salesforce,他们提供试用,你可以申请个帐号去看看
引用Microsoft Dynamics CRM 3.0产品特性上的一段话,http://www.microsoft.com/china/dynamics/product/crm3.mspx
引用
方便的自定义,可针对您的业务工作流程来自定义 Microsoft Dynamics CRM,方法如下:添加自定义对象和活动、为不同用户设计自定义视图,以及将业务逻辑应用到 CRM 中。
来自salesforce,他们提供试用,你可以申请个帐号去看看
45 楼
javaTo
2008-09-12
已经实现无需修改源码,无需POJO的自定义方式
忍不住要提一下《Java Persistence with Hibernate中文版Hibernate实战》这本书,写的非常好,翻译质量也不错。
虽然有点贵(公司买的),但绝对是值的
忍不住要提一下《Java Persistence with Hibernate中文版Hibernate实战》这本书,写的非常好,翻译质量也不错。
虽然有点贵(公司买的),但绝对是值的
44 楼
soci
2008-09-11
研究过几个商用产品的数据库结构,动态建实体的没见过,
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
一般属性都是是做把列存成记录的方式。金钱、数字的都是冗余列,T1,T2,T3这样。
43 楼
javaTo
2008-09-11
jacklondon 写道
gblyh 写道
jacklondon 写道
"最近开发的一个系统,需要在不更改代码和重启系统的情况下提供对用户自动建表的支持"----就冲这句话,很多时候就可以直接枪毙掉这个系统了。
很多内容管理系统的设计思路都是基于表结构的变化来适应复杂的非结构化数据的,像IBM的CM,EMC2的Documental(可能拼错了),相比于扩展属性的表结构设计,大数据量的情况下动态建表的方法可以减少数据行数。也更利于优化查询
拜托!!我所知道的排在前几名的开源内容管理系统,都没有动态建表!!
CMS了解不多,不过你去看看Salesforce、Microsoft Dynamics CRM、Oracle CRM/ERP、SAP CRM/ERP 应用型产品,哪个不是需要动态建立实体的
42 楼
sunsong
2008-07-18
先作为知识库做个记号,慢慢再看。
41 楼
cm4ever
2008-07-17
我06年写过hibernate延迟加载模块,基于hibernate 2.1.6的。
楼主的一些方法扩展和我那个模块重合。
http://blog.csdn.net/cm4ever/archive/2006/06/14/795833.aspx
当时也发到这里来过,无人问津,时代8同啊。
楼主的一些方法扩展和我那个模块重合。
http://blog.csdn.net/cm4ever/archive/2006/06/14/795833.aspx
当时也发到这里来过,无人问津,时代8同啊。
相关推荐
Hibernate是一款强大的对象关系映射(ORM)框架,它允许开发者使用Java对象来操作数据库,而无需直接编写SQL语句。在Hibernate中,自定义查询是扩展其功能的重要方式,能够帮助我们实现更复杂的数据库交互需求。本文...
4. **配置SessionFactory**:在Hibernate配置文件(hibernate.cfg.xml)中,添加自定义类型的相关配置。 ```xml <hibernate-configuration> ... <!-- 添加自定义类型 --> ... </hibernate-configuration...
HibernateSessionFactory.java
这篇博客"JPA + Hibernate 3 CRUD操作历史审计日志的解决方案"将深入探讨如何实现这一需求。 首先,我们需要理解JPA和Hibernate的基础概念。JPA定义了一组用于持久化Java对象的API,它允许开发者通过面向对象的方式...
在Java的持久化框架Hibernate中,`SessionFactory`是核心组件之一,它负责管理数据库会话并提供对象-关系映射(ORM)的功能。本篇文章将深入探讨`SessionFactory`的使用,以及如何创建和操作它。 `SessionFactory`...
Spring会自动将SessionFactory注入到Repository中,无需手动创建Session。在上述代码中,`getCurrentSession()`返回了一个与当前线程绑定的Session,简化了事务管理。 此外,为了处理事务,还需要在Spring配置文件...
本篇文章将深入探讨`HibernateSessionFactory`及其在Hibernate中的作用,以及如何使用它来实现增、删、查、改(CRUD)操作。 `SessionFactory`是Hibernate的核心组件,它是线程安全的,负责管理数据库连接和会话。`...
在此背景下,《很不错的Hibernate解决方案》一文介绍了一种基于Hibernate框架的物流系统持久层解决方案,旨在解决当前物流系统中存在的问题,并提升整体性能。 #### Hibernate框架简介 Hibernate是一种开放源代码的...
总结一下,实现Spring与Hibernate的多数据库解决方案,主要涉及以下几个步骤: 1. 配置多个数据源,分别用于读和写操作。 2. 创建与数据源相对应的Hibernate SessionFactory,确保数据流向正确的数据库。 3. 可选地...
Session s= HibernateSessionFactory.getSession(); 就是Hibernate的工具java类
用于获得Session会话及关闭Session会话
在Java Web开发中,Spring和Hibernate是两个非常重要的框架,它们常常被联合使用来处理数据库操作,如增、删、改、查(CRUD)。本文将深入探讨如何利用Spring与Hibernate整合,通过两种不同的方式来实现这些基本操作...
标题提到的"新Hibernate SessionFactory().getCurrentSession()猫腻"揭示了一个常见的使用误区或者说是陷阱,即不正确地使用SessionFactory的getCurrentSession()方法。这篇文章可能探讨了这个方法在实际应用中的...
然而,实际上,通过适当的技术手段,我们可以有效地解决Hibernate在批量处理时可能出现的性能问题。以下是一些关于如何在Hibernate环境下优化批量数据处理的策略。 首先,了解问题的根源。在上述例子中,当尝试向...
在本文中,我们将深入探讨如何将Spring Boot框架与Hibernate ORM集成,特别是在不使用JPA(Java Persistence API)的情况下。Spring Boot以其便捷的自动配置和简化Java应用开发而广受欢迎,而Hibernate作为Java领域...
### Hibernate 实现动态表查询的多种解决方案 #### 一、前言 在使用Hibernate进行数据库操作时,我们经常需要根据不同的需求对不同的表进行查询。特别是在处理多表、多库等复杂场景时,如何实现动态表查询就显得尤...