该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-10-28
但是如果按照同样的命名规范运到数据库的时候, 由于很多数据库对于表名, 字段名是大小写不敏感的, 所以最常见的策略是加下划线作为断词的依据: OrderItem -> order_item maxPrice -> max_price 这样运用Hibernate的时候, 偶们就得手工在mapping文件里面指明: <class name="OrderItem" table="order_item"> <property name="maxPrice" column="max_price"/> 每个mapping关系都得手工这样写, 是不是很不爽? 现在来介绍一下net.sf.hibernate.cfg.NamingStrategy的用处, 看看它是怎么修理这个问题的, 代码如下: import net.sf.hibernate.cfg.NamingStrategy; import net.sf.hibernate.util.StringHelper; /** * An improved naming strategy that prefers embedded underscores to mixed case * names, base on DefaultNamingStrategy and ImprovedNamingStrategy * */ public class UnderscoreNamingStrategy implements NamingStrategy { public static final NamingStrategy INSTANCE = new UnderscoreNamingStrategy();; protected UnderscoreNamingStrategy(); { } public String classToTableName(String className); { return addUnderscores(StringHelper.unqualify(className););; } public String propertyToColumnName(String propertyName); { return addUnderscores(StringHelper.unqualify(propertyName););; } public String tableName(String tableName); { return tableName; } public String columnName(String columnName); { return columnName; } public String propertyToTableName(String className, String propertyName); { return classToTableName(className); + '_' + propertyToColumnName(propertyName);; } private String addUnderscores(String name); { StringBuffer buf = new StringBuffer(name.replace('.', '_'););; for (int i = 1; i < buf.length(); - 1; i++); { if ('_' != buf.charAt(i - 1); && Character.isUpperCase(buf.charAt(i);); && !Character.isUpperCase(buf.charAt(i + 1););); { buf.insert(i++, '_');; } } return buf.toString();.toLowerCase();; } } 在初始化配置的时候, 把这个NamingStrategy加上: Configuration config = new Configuration();; config.setNamingStrategy(UnderscoreNamingStrategy.INSTANCE);; 这样mapping文件就变得简单多了: <class name="OrderItem"> <property name="maxPrice"/> NamingStrategy还可以用在其他方面, 比如有些数据库设计规范统一要求Table前面加上模块名称 (如, 属于Order模块的统一加上ORDER_ ), 比如还有些恶心规范统一要求表名和字段名采用4码缩写 (如, OrderItem -> orde_item, maxPrice -> max_pric), 这些都是NamingStrategy可以解决的脏活累活. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-10-30
谢谢!
楼主的文章让我了解了NamingStrategy 并且专门查看相关的代码 |
|
返回顶楼 | |
发表时间:2004-11-15
我照楼主的方法试了一下,可是发现UnderscoreNamingStrategy.INSTANCE并没有起作用,我的passWord,数据库里是pass_word,运行提示:
Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]列名 'passWord' 无效。 能否告诉什么原因呢?谢谢! |
|
返回顶楼 | |
发表时间:2004-11-15
把你的相关代码贴出来......
|
|
返回顶楼 | |
发表时间:2005-01-24
我在spring里试了一下
<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"> <ref local="dataSource"/> </property> <property name="mappingResources"> <list> <value>com/wl/dao/hibernate/model/FgglParent.hbm.xml</value> <value>com/wl/dao/hibernate/model/FgglChilds.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.Provider</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="namingStrategy"><ref bean="nameStrategy"/></property> </bean> <!-- Hibernate NamingStrategy--> <bean id="namingStrategy" class="net.sf.hibernate.cfg.ImprovedNamingStrategy"/> 在这个 <bean id="namingStrategy" class="net.sf.hibernate.cfg.ImprovedNamingStrategy"/> 里我实验了用ImprovedNamingStrategy或者楼主的UnderscoreNamingStrategy 都会得到spring 的包错: org.springframework.beans.factory.BeanDefinitionStoreException: Error registering bean with name 'namingStrategy' defined in class path resource [applicationContext.xml]: Validation of bean definition with name failed; nested exception is org.springframework.beans.factory.support.BeanDefinitionValidationException: No public constructor in class [class net.sf.hibernate.cfg.ImprovedNamingStrategy] org.springframework.beans.factory.support.BeanDefinitionValidationException: No public constructor in class [class net.sf.hibernate.cfg.ImprovedNamingStrategy] at org.springframework.beans.factory.support.RootBeanDefinition.validate(RootBeanDefinition.java:334) at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:210) at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.registerBeanDefinition(DefaultXmlBeanDefinitionParser.java:188) at org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser.registerBeanDefinitions(DefaultXmlBeanDefinitionParser.java:155) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:161) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:127) at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:125) at org.springframework.context.support.AbstractXmlApplicationContext.refreshBeanFactory(AbstractXmlApplicationContext.java:65) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:226) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:58) at com.wl.test.dao.hibernate.TestDAOToSpring.setUp(TestDAOToSpring.java:15) at junit.framework.TestCase.runBare(TestCase.java:125) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186) ---------------------------------------------------------------------- org.springframework.beans.factory.support.BeanDefinitionValidationException: No public constructor in class [class net.sf.hibernate.cfg.ImprovedNamingStrategy] spring要求要public的构造方法才可以吗? |
|
返回顶楼 | |
发表时间:2005-01-25
看到ReadOnly提到不爽,想起一个问题。
如果pojo放得比较深,如com.xxx.wap.Book,在写hql的时候要把类的完整package+classname写进去,如"select book.name from com.xxx.wap.Book book",也是N不爽。有没有办法给他一个alias什么的,精简为"select book.name from Book book"?(不过自己感觉希望好像不大。。。。) |
|
返回顶楼 | |
发表时间:2005-01-25
引用 在写hql的时候要把类的完整package+classname写进去
不需要,只写类的classname就可以了。除非你关掉auto-import,你才需要写packagename |
|
返回顶楼 | |
发表时间:2005-01-25
doninox 写道 spring要求要public的构造方法才可以吗?
Yes, 你可以写一个Class extends org.springframework.orm.hibernate.LocalSessionFactoryBean 复写newConfiguration方法: protected Configuration newConfiguration(); throws HibernateException { Configuration config = new Configuration();; config.setNamingStrategy(UnderscoreNamingStrategy.INSTANCE);; return config; } |
|
返回顶楼 | |
发表时间:2005-01-25
明白了 谢谢!
|
|
返回顶楼 | |
发表时间:2005-03-14
可以在xdoclet生成.hbm.xml时也使用NamingStrategy嘛?不知道各位如果用了NamingStrategy后,*.hbm.xml怎么生成,特别是
<property name="postalCode" type="java.lang.String" update="true" column="postalCode" insert="true" length="45" /> 类似上面这种情况,数据库中的列名其实是postal_code。 |
|
返回顶楼 | |