zoukankan      html  css  js  c++  java
  • 2013年2月6日星期三小结

    今天再次纠结于数据库设计是否要预留备用字段,当定制人员跟我说java以后扩展字段会很麻烦时,需要修改表结构后,还要domain下相关类及映射文件,我犹豫了。不过后来看到Hibernate正向工程可以自动生成表结构我坚定了不预留备用字段的想法。备用字段,它们的作用是什么呢?就是以防万一,防备可能的情况。

    这似乎可以叫做防患于未然,等到时候需要的时候,就不需要在表中增加新的字段了,而且这样做的话,一个表的数据应该会被存储在相邻的物理空间中,这对于性能也是有好处的。

    另外的原因就是,在古老的数据库中,如果改变数据库的定义(包括增加字段、改变字段的类型、删除字段等等),那么其中所有的数据就会丢失,所以这项工作非常麻烦,我们需要先建立临时表,将数据备份出来,然后创建新表,将数据导入其中,最后再删除原来的表。

    问题所在:

    这样的做法对于项目会导致很多问题,而且原先想要解决的问题并不一定能够解决,不信的话,请往下看。

    问题一:增加大量备用字段,必定会浪费很多空间,尽管其中可能都没有具体的数据,但是仅仅是空字段也会占据一定的空间的。

    问题二:由于命名的特点,如果没有完善的文档管理流程,用不了多久(可能也就是两三年),就没有人能够说清楚到底哪个字段代表的是什么意义了。就算有文档管理,这些管理工作也会比较麻烦,而且在每次使用的时候都需要申请,还有可能会出现冲突的情况。

    问题三:增加了这些备用字段就真的会够用吗?不一定,因为我们只是每个类型的字段留出几个备用,如果数量超过,或者要使用特殊的、不常用的类型的时候,还是需要增加新的字段。比方说在上述的Person表中,我们要存储照片,那么可能就要增加一个blob类型的photo字段,这在初期设计的时候可不一定会留出这样的备用字段。而且如果没有完善的管理,谁又能说清楚倒底哪个字段已经被使用,哪个字段还可以使用呢?到时候还不是要增加新的字段。

    解决方案:

    其实上面的这种设计方式就是一种"过度设计",我们应该做的就是"按需设计",在经过详细有效的分析之后,在数据表中只放置必要的字段,而不要留出大量的备用字段。

    当需要增加相关的信息的时候,就要具体情况具体分析:

    如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上增加字段,并将相关的数据更新进去。

    如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来。

    对于表的数据的存储位置所导致的性能问题,我们可以通过在特定时间对数据库的数据进行重组来解决,而这项工作对于长期运行的数据库来说,也是需要定期进行的。

    今天再次发现findbugs的功能真的很好很强大,代码审核时帮助我发现了同事好几个代码漏洞,发现现在代码审核经常出现的问题有以下几类:

    1. 代码不规范,长度超过120个字符,空格不对等
    2. 没有做空值判断
    3. 不同类型的值判断,尤其是int与Integer之类的
    4. 注释不规范等问题

     

     

    hibernate能动态生成数据库表

    如果你是单独使用hibernate的,请在hibernate.cfg.xml里面的sessionfactory下配置<property name="hbm2ddl.auto"></property>这个属性如果你是使用SSH组合框架的,而且由SPRING管理sessionfactory的,请在applicationContext.xml里面配置<property name="hibernateProperties"><props><prop key="hibernate.dialect">数据库方言</prop><prop key="hibernate.show_sql">是否打印SQL</prop><prop key="hibernate.hbm2ddl.auto">建表语句(参考值:validate | update | create | create-drop ,一般用update)</prop></props></property>

    hibenate.hbm2ddl.auto属性详解
    hibernate 配置属性中,hibernate.hbm2ddl.auto可以帮助你实现正向工程,即由java代码生成数据库脚本,进而生成具体的表结构.
    &在hibernate.cfg.xml中:
    Java代码 复制代码

    1. <property name="hibernate.hbm2ddl.auto">
    2. </property>

    <property name="hibernate.hbm2ddl.auto">
    </property>


    它包含4个属性:

    * create : 会根据你的model类来生成表,但是每次运行都会删除上一次的表,重新生成表,哪怕2次没有任何改变


    * create-drop : 根据model类生成表,但是sessionFactory一关闭,表就自动删除


    * update : 最常用的属性,也根据model类生成表,即使表结构改变了,表中的行仍然存在,不会删除以前的行


    * validate : 只会和数据库中的表进行比较,不会创建新表,但是会插入新值


    在hibernate中,如果在hibernate.cfg.xml文件中,将hibernate.hbm2ddl.auto设置为update(或者cretae-drop)也可以,如下
    <property name="hibernate.hbm2ddl.auto">update</property>
    则在运行应用程序时(第一次),会自动建立起表的结构(前提是先建立好数据库)。要注意的是,
    当部署到服务器后,表结构是不会被马上建立起来的,是要等应用第一次运行起来后才会

    如果是spring配置文件中配置则为
    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
    <ref bean="dataSource" />
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    org.hibernate.dialect.Oracle9Dialect
    </prop>

    <prop key="hibernate.connection.autocommit">true</prop>

    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.hbm2ddl.auto">update</prop>
    </props>
    </property>

    使用Hibernate自动生成表不能正确创建表的问题

    hibernate使用了jdbc默认的databasemeta来寻找相应表数据信息,当使用默认的配置时,由于某种原因(并不是每次都能发生,取决于数据库本身以及相应的驱动)。当使用当前用户连接到数据库时,使用databasemeta寻找数据库表信息时,会查询出其它用户的数据表信息(即使当前用户没有相应的权限)。
    解决此问题的方法很简单,只需要在hibernate.cfg.xml中配置一句:

    1 <property name="default_schema">当前连接用户</property>

    这样,使用databasemeta时,就会强制性地在当前用户空间中寻找数据库信息了,这样就能正确的创建出表结构了。

  • 相关阅读:
    刷链表的题都不要用Python
    [踩坑] @RequestBody注解转换modal报400错误问题排查与解决
    netty学习笔记二——ByteBuf类原理
    netty学习笔记一:TCP粘包拆包
    OkHttp3出现java.io.IOException: Hostname was not verified解决方案
    nginx学习笔记(一) 用nginx实现本地https请求转http请求
    zookeeper启动失败排查
    spring boot升级到2.0.0.M7后报错ConverterNotFoundException for java.time.Duration的解决方案
    JpaRepository QueryByExample方法使用详解
    JavaScript面向对象编程
  • 原文地址:https://www.cnblogs.com/doit8791/p/2908204.html
Copyright © 2011-2022 走看看