---Hibernate的局限性:如果我的表结构需要动态改变怎么办?--- --- 为什么这么做?当然是有需求啊。--- 什么可以做到这一点呢?使用最原始的jdbc就可是实现啊。而且我们的产品已经作到了。呵呵。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 chinaraul(楚哥) :Hibernate该如何去做?多谢! 你也可以利用工具动态生成印象有什么需求就用什么好的处理方式,如果你已经有了好的处理方式,为什么一定要用hibernate呢?我想客户是不会强行要求你选择什么技术吧,再说你也可以在其他地方用hibernate实现 Hibernate仅仅是一个工具而已,一个工具不可能是万能的,也不需要是万能的。 动态字段不是hb的强项,建议使用jdbc直接去做 Hibernate 也没什么不可以啊!你先生成XML 然后用 xml 生成表不就得了.bean也可以动态生成的,java 的代码也可以自己生成,自己调用是否装载的. 把字段都加进去不就得了?干嘛要做动态添加?就算你有java解决方案,数据库碰到你这种想法也要短路。 sql复杂的语句都用sql.其实jdbc挺好的. jdbc肯定是可以。hb就不知道了。对于楼主的问题,在设计上有没有可能换一种思路:比如用记录的变动来替代字段的变动。 hibernate也行,但没这个必要呀........................................ 楼主你的设计严重严重严重有问题关系数据库的理论可以使用关系运算确定表的结构,在运行过程中更改表结构根本不可取,即便可行速度也严重无法接受,jdbc提供更改表是为工具软件准备的,不是为应用准备的你的问题应该分析表的关系然后设计更合理的表结构,一定能确定下表的结构而不需在运行中更改 asklxf(xuefeng):你认为不需要是因为你没有碰到类似的问题。就象许多大学生认为学习离散数学没有什么用似的。 hibernate调用存储过程来做就可以了啊hibernate3.0很好的支持存储过程,而且功能强大了很多,建议楼主一起学习下 还是不明白为什么要设计成动态表结构,Design Principles里提到坏的设计特征之一就是:Viscosity,意思就是当需求发生变化时,已有的设计(动态表结构)会使得保持构架清晰合理的方法变难,而破坏构架的方法却比较容易。其实Hibernate不是不愿意做,而是不想做吧,如果表结构变来变去,PO,VO也必须跟着变来变去,业务层也要做相应的变化,真是晕啊 employee表-------------ID 员工号 pkName 姓名...salary_type表---------------ID 工资类型 pkName 工资名称...为了关联这两个表,创建第三个employee_salary表----------------------------------------------EMPLOYEE_IDSALARY_IDHOW_MUCH_$比如,小张下个月新增交通补贴一项,首先在salary_type中添加纪录(如果没有): {交通补贴ID, "交通补贴"}然后,在employee_salary表添加{小张的ID, 交通补贴ID, $700 }这样怎么会更改表的结构?要查询小张的所有收入项目,在employee_salary中select * where employee_id=小张的id然后,获得小张对应的所有salary_id,对照salary_type表便知到底是什么类型收入 Hibernate处理的是对象和关系型数据库的连接问题。如果一个数据表字段数目变化,意味着一个对象的属性个数发生改变,这样的变化在java中怎么实现呢?很显然不可能直接增加类的属性的个数。而是用一个key-value的对应值来表示属性,key表示属性名称,value表示属性值,比如:public MyClass { private Map properties = new HashMap(); public setProperty(String key) { ... } public getProperty(String key) { ... }} 我们也做了一个东东!www.htok.net tx18(www.htok.net)如果我猜得不错的话,你们几乎所有的产品都应该是基于opensource的。 可以是可以,但是你要付出更高的代价。1、些一个后台线程或是一个类,在你的表结构变化后,调用这个操作类完成一个类似middlegen完成的操作来生成hbm.xml映射文件和相应的类。2、Configuration重新加载映射文件3、重新建立sessionfactory4、取得session5、………………开销很大吧,我没有尝试过,但我想只要想要的,总有途径实现来满足。 在设计库结构的时候是可以避免动态改变的,但是一个项目如果为了符合某个规则的话,难免会使设计有点僵硬。 数据库实际上最重要的是查询,我想大家并不反对! 在查询的时候往往要借助临时表,再经过动态的表结构改变,加入一些辅助的字段,这样会使查询出来的结果更加符合客户的习惯!我是支持Hibernate可以动态改变表结构的! 可以参考"属性容器模式",这是属于gof模式之外的一种模式。可以解决对象属性可动态扩展的问题。实际上就是另外再建立一张表做一个一对多的关联。在这个表中用名称/值对的方式保存对象可扩展的属性。映射到对象中就是用一个Hashtable来保存这些属性 动态改变表结构不是一个好办法。asklxf(xuefeng)说的那种表结构,和redv(upas) 说的那种类设计方式,结合到Hibernate中,就完全可以解决你的这个问题。 你只要分析清楚各个实体的关系,使用关系运算,就能确定出要几个表,以及每个表的结构。关系数据库是以数学模型为基础的(其实所有软件都是),只不过简单的几个实体稍微想一下就能想出来,要是有100多个实体,那就要借助PowerBuilder之类的软件来建立关系模型。因为表结构的更改需要巨大的开销,在一个有几万行纪录的表上,添加一个字段怎么也得几十秒,因为涉及到磁盘文件结构的大改变,这种IO操作非常耗资源,这种功能只能在数据库管理软件中实现。 动态生成的表使用hibernate实现还是比较麻烦了,开销太大了,并且也不灵活,完全没有用到hibernate的优点,建议楼主不要采用Hibernate,我做过一个有大量动态生成的项目,经过分析后最终没有采用Hibernate. 我们已经实现了这样一个项目: 某个表完全动态(除了主键等几个关键字段)前提:A表既然动态,那么肯定得有个限制:只能增字段不能减字段,否则会引起一致性问题;(本来这样动态增加就是不合理的设计,动态删除就更完蛋了)分析:1、只有这一个表A需要动态,那么我们使用标准sql对它进行操作,中介仍然是hibernate,但没有pojo对象,这样可以不必担心字段变了,pojo对象也得变; 2、其他表不需要动态,完全使用pojo对象,由hibernate进行读/存; 3、对于动态表,我们创建一个属性表B来描述它,属性表里的每一条记录,就是表A的一个字段的描述,如字段名,字段属性,最大长度,默认值等等。这样,当要读取A表的字段时,先读取B表,B表有多少记录,A表就有多少字段,反过来也一样,而且属性也知道了。 写一个基础方法,读B然后再对A操作,问题就可以解决,当然,不必每次都读B表,你可以将B表记录作为静态量保存在内存中,只有A表改表时才再重新读B表。 4、对于A表字段的增加,需要另外写一个程序,这个程序将是你开发产品的一个功能,它对A表增加字段的同时,同时向描述它的B表增加一条记录。我们是成功实现了的,希望对你有所帮助! phoenix_zd(天马行空) 其实我们的产品是跨数据库的,而db2根本就是不允许动态删除表的字段。设计思路和你的颇为相似,只是我们用的是jdbc。呵呵谢谢! java将excel、doc、pdf转换为图片 org.springframework.orm.hibernate3.HibernateQueryException: Expected positional 急急急!struts2标签用不了!一用就报错! hibernate 问题 初学java EE,请教大牛一个问题 连接表,多对一双向关联 关于CMT和BMT的难题 请推荐几本EJB的书 weblogic+jb9初高级问题,关于jndi的 熟悉J2EE并有创业冲动的朋友请联系 关于C++和Java用Socket进行通讯的问题? 请问我错在哪,该怎样解决这问题啊?
有什么需求就用什么好的处理方式,如果你已经有了好的处理方式,为什么一定要用hibernate呢?我想客户是不会强行要求你选择什么技术吧,再说你也可以在其他地方用hibernate实现
bean也可以动态生成的,java 的代码也可以自己生成,自己调用是否装载的.
对于楼主的问题,在设计上有没有可能换一种思路:比如用记录的变动来替代字段的变动。
你认为不需要是因为你没有碰到类似的问题。
就象许多大学生认为学习离散数学没有什么用似的。
-------------
ID 员工号 pk
Name 姓名
...salary_type表
---------------
ID 工资类型 pk
Name 工资名称
...为了关联这两个表,创建第三个employee_salary表
----------------------------------------------
EMPLOYEE_ID
SALARY_ID
HOW_MUCH_$比如,小张下个月新增交通补贴一项,首先在salary_type中添加纪录(如果没有): {交通补贴ID, "交通补贴"}然后,在employee_salary表添加{小张的ID, 交通补贴ID, $700 }这样怎么会更改表的结构?要查询小张的所有收入项目,在employee_salary中select * where employee_id=小张的id
然后,获得小张对应的所有salary_id,对照salary_type表便知到底是什么类型收入
如果一个数据表字段数目变化,意味着一个对象的属性个数发生改变,这样的变化在java中怎么实现呢?
很显然不可能直接增加类的属性的个数。而是用一个key-value的对应值来表示属性,key表示属性名称,value表示属性值,比如:public MyClass {
private Map properties = new HashMap();
public setProperty(String key) {
...
}
public getProperty(String key) {
...
}
}
www.htok.net
如果我猜得不错的话,你们几乎所有的产品都应该是基于opensource的。
1、些一个后台线程或是一个类,在你的表结构变化后,调用这个操作类完成一个类似middlegen完成的操作来生成hbm.xml映射文件和相应的类。
2、Configuration重新加载映射文件
3、重新建立sessionfactory
4、取得session
5、………………
开销很大吧,我没有尝试过,但我想只要想要的,总有途径实现来满足。
数据库实际上最重要的是查询,我想大家并不反对!
在查询的时候往往要借助临时表,再经过动态的表结构改变,加入一些辅助的字段,这样会使查询出来的结果更加符合客户的习惯!我是支持Hibernate可以动态改变表结构的!
asklxf(xuefeng)说的那种表结构,和redv(upas) 说的那种类设计方式,结合到Hibernate中,就完全可以解决你的这个问题。
1、只有这一个表A需要动态,那么我们使用标准sql对它进行操作,中介仍然是hibernate,但没有pojo对象,这样可以不必担心字段变了,pojo对象也得变;
2、其他表不需要动态,完全使用pojo对象,由hibernate进行读/存;
3、对于动态表,我们创建一个属性表B来描述它,属性表里的每一条记录,就是表A的一个字段的描述,如字段名,字段属性,最大长度,默认值等等。这样,当要读取A表的字段时,先读取B表,B表有多少记录,A表就有多少字段,反过来也一样,而且属性也知道了。 写一个基础方法,读B然后再对A操作,问题就可以解决,当然,不必每次都读B表,你可以将B表记录作为静态量保存在内存中,只有A表改表时才再重新读B表。
4、对于A表字段的增加,需要另外写一个程序,这个程序将是你开发产品的一个功能,它对A表增加字段的同时,同时向描述它的B表增加一条记录。我们是成功实现了的,希望对你有所帮助!