hibernage命名策略

关于使用Hibernate annotation注解映射和命名策略的方式及相关问题解决
    一、首先引出以下几个观点:
    1).开发项目时,不管是否使用Hibernate,都应该为项目所涉及到的表名取个前缀(如果还有特别需要也可以再加个后缀[通常在处理大数量需要动态建表的时候有加后缀的必要]),这样也能保证与他人共享数据库时不至于发生表名冲突的问题,同时方便自己维护所有相关的表。
    2).在每个表中为每个字段都加个前缀也是挺有好处的:比如能避免和SQL语句关键字发生冲突的问题;在连接查询时也能方便地判断某某字段是属于某个表的。
    3).使用Hibernate annotation注解映射可以减少实体类相对应的.hbm.xml文件的维护(纯粹一体力活,能省则省),只需要针对实体类进行Annotation的方式配置即可。
   
    二、程序实验环境说明
        1.导入相关jar包
            1).hibernate必须用到的包(其实是3.2版本)
                    antlr-2.7.6.jar
                    asm-attrs.jar
                    asm.jar
                    cglib-2.1.3.jar
                    commons-collections-2.1.1.jar
                    commons-logging-1.0.4.jar
                    dom4j-1.6.1.jar
                    ehcache-1.2.3.jar
                    hibernate3.jar
                    jta.jar
                    log4j-1.2.11.jar
            2).hibernate annotations相关包:
                ejb3-persistence-1.0.2.GA.jar (用以持久化映射)
                hibernate-annotations.jar
                hibernate-commons-annotations-3.1.0.GA.jar
                slf4j-api-1.5.8.jar, slf4j-log4j12-1.5.8.jar(此两个jar是写相关日志需要用到的)
            3).Oracle驱动包
                classes12.jar
        2.开发环境
            Eclipse3.5
        3.数据库环境: Oracle9i
       
    三、相关文件
        1).实体类:
            package com.temp.domain;
   
            import java.io.Serializable;
            import java.util.Date;
           
            import javax.persistence.Column;
            import javax.persistence.Entity;
            import javax.persistence.GeneratedValue;
            import javax.persistence.Id;
            import javax.persistence.Table;
           
            import org.hibernate.annotations.GenericGenerator;
           
           
            @Entity
            @Table
            public class BasicCar implements Serializable{
                //Table注释标识和各个成员变量的Column注释标识都未指定name属性,是为了使命名策略中相关方法生效
           
                private static final long serialVersionUID = 6961767068555866935L;
               
                @Id
                @Column(nullable=false,length=32)
                @GeneratedValue(generator="hibernate-uuid")
                @GenericGenerator(name="hibernate-uuid",strategy="uuid")
                private String id;
               
                @Column(nullable=false,length=30,unique=false)
                private String name;
               
                @Column (nullable=true,length=50)
                private String factory;
               
                @Column(nullable=false)
                private Date date;
               
                /**
                 * 默认构造函数(做映射的必须)
                 */
                public BasicCar() {
                }
               
               
                public BasicCar(String name, String factory, Date date){
                    this.name=name;
                    this.factory=factory;
                    this.date=date;
                }
               
                public BasicCar(String id, String name, String factory, Date date){
                    this(name,factory,date);
                    this.id=id;
                }
               
           
                public String toString(){
                    return  "id="+id+
                            ",name="+name+
                            ",factory="+factory+
                            ",date="+date;
                }
            }
       
       
        2).命名策略类
            package com.temp;
   
            import java.text.SimpleDateFormat;
            import java.util.Date;
            import org.hibernate.cfg.NamingStrategy;
            import org.hibernate.util.StringHelper;
           
            public class MyNamingStrategy implements NamingStrategy {
           
                private static MyNamingStrategy namingStrategy;
                private String currentClassName="";
                private String currentColumnName="";
                private String needDatePostfixTables[]={"ServiceVisitLog","BasicCar"}; //需要添加时间后缀的实体类名
           
                private MyNamingStrategy() {
                }
               
                public static MyNamingStrategy getInstance(){
                    if(namingStrategy==null){
                        namingStrategy = new MyNamingStrategy();
                    }
                    return namingStrategy;
                }
               
                //实现NamingStrategy接口方法(为每个实体映射成数据库表名时添加一个前缀)
                public String classToTableName(String className) {
                    className = StringHelper.unqualifyEntityName(className); // 先去包名(如果有的话),取类名
                    this.currentClassName=className;
                    String tablePrefix="Test_"; //表名前缀
                    String tableName=tablePrefix+className;
                    int dptLength=needDatePostfixTables.length;
                    for(int i=0;i<dptLength;i++){
                        //根据需要进行表名后缀的添加
                        if(needDatePostfixTables[i].equals(className)){
                            tableName=tableName + getPostfixCurrentyyyyMMdd();
                        }
                    }
                    return tableName;
                }
           
                public String tableName(String tableName) {
                    return tableName;
                }
           
                //实现NamingStrategy接口方法(为每个属性映射成数据库表字段时添加一个前缀,提取每个类各单词首字母并加一个下划线做为前缀)
                public String propertyToColumnName(String propertyName) {
                    char[] chars = this.currentClassName.toCharArray();
                    String columnPrefix = ""; //字段名前缀
                    for (int i = 0; i < chars.length; i++) {
                        if (Character.isUpperCase(chars[i])) {
                            columnPrefix=columnPrefix+chars[i];
                        }
                    }
                    String columnName=propertyName;
                    if(columnPrefix.length()>0){
                        columnName=columnPrefix+"_"+columnName;
                    }
                    this.currentColumnName=columnName;
                    return columnName;
                }
           
                public String columnName(String columnName) {
                    //System.out.println("columnName="+columnName);
                    return columnName;
                }
           
                public String logicalColumnName(String columnName, String propertyName) {
                    if (this.currentColumnName != null) {
                        return this.currentColumnName;
                    } else {
                        return propertyName;
                    }
                }
           
                public String collectionTableName(String string, String string1,
                        String string2, String string3, String string4) {
                    return "";
                }
           
                public String foreignKeyColumnName(String string, String string1,
                        String string2, String string3) {
                    return "";
                }
           
                public String joinKeyColumnName(String string, String string1) {
                    return "";
                }
           
                public String logicalCollectionColumnName(String string, String string1,
                        String string2) {
                    return "";
                }
           
                public String logicalCollectionTableName(String string, String string1,
                        String string2, String string3) {
                    return "";
                }
               
                //得到一个形如"_20100331"之类的字符串
                private String getPostfixCurrentyyyyMMdd(){
                    Date date=new Date();
                    SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
                    String yyyyMMdd=df.format(date);
                    return "_" +yyyyMMdd;
                }
            }
       

        3).hibernate.cfg.xml文件
            <?xml version='1.0' encoding='utf-8'?>
            <!DOCTYPE hibernate-configuration PUBLIC
                    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
           
            <hibernate-configuration>
                <session-factory>
                    <!-- OracleDriver Database connection settings-->
                    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
                    <property name="connection.url">jdbc:oracle:thin:@192.168.10.116:1521:test</property>
                    <property name="connection.username">temp</property>
                    <property name="connection.password">temp</property>
                    <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property>
                   
                    <!-- Disable the second-level cache  -->
                    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
           
                    <!-- Echo all executed SQL to stdout -->
                    <property name="show_sql">true</property>
                    <property name="format_sql">false</property>
           
                    <!-- Drop and re-create the database schema on startup -->
                    <property name="hbm2ddl.auto">update</property>
           
                    <mapping class="com.temp.domain.BasicCar"/>
                </session-factory>
            </hibernate-configuration>
       
       
        4).测试类Test.java
            package com.temp.test;
           
            import java.util.Date;
            import java.util.List;
           
            import org.hibernate.Query;
            import org.hibernate.Session;
            import org.hibernate.SessionFactory;
            import org.hibernate.Transaction;
            import org.hibernate.cfg.AnnotationConfiguration;
           
            import com.temp.MyNamingStrategy;
            import com.temp.domain.BasicCar;
           
            public class Test {
                AnnotationConfiguration cfg;
               
                SessionFactory sf;
               
                Session session;
               
               
                void doConfiguration(){
                    cfg = new AnnotationConfiguration(); //使用了注释的方式则创建此类
                    //必须放在configure语句之前命名策略才有效(同时需要注意在实体类配置时不能显示指定Table的名称和Column的名称)
                    cfg.setNamingStrategy(MyNamingStrategy.getInstance());
                    cfg.configure("/hibernate.cfg.xml");
                    sf=cfg.buildSessionFactory();
                }
               
                public static void main(String[] args) {
                    Test t=new Test();
                    t.doConfiguration();
                    t.insert();
                    t.query();
                }
               
                public void insert(){
                    session=sf.openSession();
                    BasicCar bc=new BasicCar("paul", "easymap", new Date());
                    Transaction tx=session.beginTransaction();
                    session.save(bc);
                    tx.commit();
                    session.close();
                }
               
                @SuppressWarnings(value = { "unchecked" })
                public void query(){
                    session=sf.openSession();
                    Query query=session.createQuery("from BasicCar");
                    List list=query.list();
                    int cnt=list.size();
                    System.out.println("当前共有"+cnt+"条记录,最后一条记录是:"+list.get(cnt-1));
                    session.close();
                }
           
            }
   
    四、相关问题说明及解决方法
        如果明明在hibernate.cfg.xml文件中配置了<property name="hbm2ddl.auto">update</property>却仍然不能自动建表,则有可能是当前连接至数据库中的用户(如本例中的temp)的配额(此处的配额不是指表空间的配额)不足所造成的(这种问题本人也是在使用plsql进行create table时发现说"Ora-01536:超出了表空间users的空间限量"时才发现的),因此特别建议当使用了Hibernate或其它ORM框架之后出现了一些诡异的问题时,建议直接到数据库的控制台或plsql进行相关操作或SQL语句的执行,以找到真正的问题!

         Ora-01536 是指的你建表的那个user所能使用的空间没有了,不是那个表所在的tablespace没有free space 了。你需要做的是给那个user对那个tablespace 有更多的space可以使用。
                解决方法:在plsql中执行 "ALTER USER temp QUOTA UNLIMITED ON users;" 语句使得temp用户对于表空间Users无限制配额存取.

你可能感兴趣的:(oracle,sql,Hibernate,xml,jdbc)