Hibernate进修(三)Hibernate给表和字段配置前后缀及脱离符
副标题#e#
在《一口一口吃掉Hibernate(一)——利用SchemaExport生成数据表》中先容了如何生成数据表。可是这只是最根基的。Hibernate在生成可能操纵数据库时,会受一些限制。好比一开始设计表的时候,直接写成了user(id,name,password,createTime) 这种名目标。可是客户厥后要求表名称要以“t_”开头,字段名要以“stu_”开头,可以是一些数据库的要害字,单词之间以“_”离隔,利便他们维护.譬喻:T_User(stu_Id,stu_Name,stu_Create_Time)。
对付上面的问题,通例的要领就是去修改Hibernate_cfg.xml中的表,为每个表添加“t_”,可能写table属性,字段也从头利用column属性来修改。假如你有100张表,每个表平均有10个字段,你还会去一个一个修改么?尚有大概遗漏可能改错。最“可恶”的是,假如客户再让你改成其他的呢,是不是还要全部修改一次?
有没有一种要领,不修改原先的设置,添加并设置一下表和字段的前后缀及脱离符等等,既可以完成呢??颠末实验,终于被我拿下了,此刻拿出来与各人分享。
针对上述问题,我主要用的是NamingStrategy接口。这个接口很有意思,可以作为业务类类型和数据库表类型的桥梁,它可以表和列的映射干系的转变和处理惩罚。譬喻一个数据工具User,对应数据库表是T_USER,假如所有映射干系都是这样的环境,可以利用NamingStrategy做为一个桥梁跟尾,而不消再hbm.xml映射文件中指定class对应的物理table。
先说一下Hibernate读取映射文件的扼要进程:轮回读取class标签,判定class标签的table属性值是否为null,若为null,则挪用NamingStrategy接口的classToTableName要领将class值转换并处理惩罚(按定名计策NamingStrategy处理惩罚)的表名。若不为null,则说明配置了table,那么挪用NamingStrategy接口的tableName要领获取处理惩罚过的表名。轮回遍历property,判定property标签的column属性值是否为null,若为null,则首先挪用propertyToColumnName要领,将属性值转化为列名,再挪用logicalColumnName要领。若不为null,则直接挪用NamingStrategy接口的logicalColumnName要领,再挪用columnName要领举办处理惩罚(按定名计策NamingStrategy处理惩罚)。
相识了上面说的这个进程,只要我们实现NamingStrategy这个接口,就可以随心所欲的修改表映射了。不多说了,直接上代码吧:
【MyNamingStrategy】自界说的定名计策,可对表、字段举办统一处理惩罚。
package com.tgb.hibernate.neatlyDB;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.NamingStrategy;
import org.hibernate.util.StringHelper;
/**
* 数据库定名计策,可定制表、字段等的前后缀
*
* @author Longxuan
*
*/
public class MyNamingStrategy implements NamingStrategy {
/**
* 数据库定名计策单一实例
*/
private static MyNamingStrategy instance = null;
/**
* 数据库设置信息类
*/
private static DatabaseConfiguration dbcfg = null;
/**
* 私有化结构要领
*/
private MyNamingStrategy() {
}
/**
* 利用单利模式,获取数据库定名计策的独一实例
*
* @return
*/
public static synchronized MyNamingStrategy getInstance() {
// 默认读取hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
return getInstance(cfg);
}
/**
* 利用单利模式,获取数据库定名计策的独一实例,同时利用默认Hibernate.cfg.xml更新定名计策信息
*
* @param cfg
* 设置文件信息
* @return
*/
public static synchronized MyNamingStrategy getInstance(Configuration cfg) {
if (instance == null) {
instance = new MyNamingStrategy();
}
MyNamingStrategy.dbcfg = new DatabaseConfiguration(cfg);
return instance;
}
/**
* 利用单利模式,获取数据库定名计策的独一实例,同时更新定名计策信息
*
* @param cfg
* 设置文件信息
* @return
*URL:http://www.bianceng.cn/Programming/Java/201410/45829.htm
*/
public static synchronized MyNamingStrategy getInstance(
DatabaseConfiguration dbcfg) {
if (instance == null) {
instance = new MyNamingStrategy();
}
MyNamingStrategy.dbcfg = dbcfg;
return instance;
}
/**
* 配置或更新数据库设置信息
*
* @param dbcfg
*/
public void setDBConfig(DatabaseConfiguration dbcfg) {
MyNamingStrategy.dbcfg = dbcfg;
}
/**
* 转化为物理表名
*
* @param className hbm.xml中的对应表的class值
*/
@Override
public String classToTableName(String className) {
if(className == null ) return null;
//改变巨细写
String str =UpdateStyle(className,dbcfg.getTableStyle().name());
//添加前后缀
str = addPrefixORStuffix(str, dbcfg.getTablePrefix(),dbcfg.getTableSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getTableSeparator());
return str;
}
@Override
public String collectionTableName(String ownerEntity,
String ownerEntityTable, String associatedEntity,
String associatedEntityTable, String propertyName) {
return null;
}
/**
* 将读取到的列名通报过来举办加工处理惩罚,变为物理表的字段名
*
* @param columnName logicalColumnName要领读取到的列名
*/
@Override
public String columnName(String columnName) {
//先挪用logicalColumnName要领,拿处处理惩罚过的值,
//再通报到该要领中,所以可以在这两个要领中任一选择修改。
//return columnName;
if(columnName == null ) return null;
//改变巨细写
String str =UpdateStyle(columnName,dbcfg.getColumnTyle().name());
//添加前后缀
str = addPrefixORStuffix(StringHelper.unqualify(str), dbcfg.getColumnPrefix(),dbcfg.getColumnSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getColumnSeparator());
return str;
}
/**
* 处理惩罚外键列名
*
*/
@Override
public String foreignKeyColumnName(String propertyName,
String propertyEntityName, String propertyTableName,
String referencedColumnName) {
if(referencedColumnName == null ) return null;
//改变巨细写
String str =UpdateStyle(referencedColumnName,dbcfg.getColumnTyle().name());
//添加前后缀
str = addPrefixORStuffix(StringHelper.unqualify(str), dbcfg.getColumnPrefix(),dbcfg.getColumnSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getColumnSeparator());
return str;
}
/**
* 关联键的名称
*/
@Override
public String joinKeyColumnName(String joinedColumn, String joinedTable) {
if(joinedColumn == null ) return null;
//改变巨细写
String str =UpdateStyle(joinedColumn,dbcfg.getColumnTyle().name());
//添加前后缀
str = addPrefixORStuffix(StringHelper.unqualify(str), dbcfg.getColumnPrefix(),dbcfg.getColumnSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getColumnSeparator());
return str;
}
@Override
public String logicalCollectionColumnName(String columnName,
String propertyName, String referencedColumn) {
return null;
}
@Override
public String logicalCollectionTableName(String tableName,
String ownerEntityTable, String associatedEntityTable,
String propertyName) {
return null;
}
/**
* 处理惩罚逻辑列名
* <b>若配置了column属性,会直接挪用挪用该要领</b>
*
* @param columnName 列名
* @param propertyName 实体列名
*/
@Override
public String logicalColumnName(String columnName, String propertyName) {
//name值对应propertyName,column值对应columnName
//判定columnName是否配置,若配置了,则返回column值,不然返回propertyName值
return columnName == null || columnName =="" ? propertyName:columnName;
}
/**
* 处理惩罚逻辑列名
* <b>若未配置column属性,则先挪用该要领,再挪用logicalColumnName要领</b>
*
* @param propertyName 实体列名
*/
@Override
public String propertyToColumnName(String propertyName) {
if(propertyName == null ) return null;
//改变巨细写
String str =UpdateStyle(propertyName,dbcfg.getColumnTyle().name());
//添加前后缀
str = addPrefixORStuffix(StringHelper.unqualify(str), dbcfg.getColumnPrefix(),dbcfg.getColumnSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getColumnSeparator());
return str;
}
/**
* 处理惩罚表名
* <b>若配置了table属性,才会挪用该要领</b>
*/
@Override
public String tableName(String tableName) {
if(tableName == null ) return null;
//改变巨细写
String str =UpdateStyle(tableName,dbcfg.getTableStyle().name());
//添加前后缀
str = addPrefixORStuffix(StringHelper.unqualify(str), dbcfg.getTablePrefix(),dbcfg.getTableSuffix());
//添加脱离符
str = addSeparator(str,dbcfg.getTableSeparator());
return str;
}
/**
* 单词脱离符
*
* @param name
* @return
*/
private String addSeparator(String str, String flag) {
StringBuffer buf = new StringBuffer(str.substring(str.lastIndexOf(".")+1));
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++, '_');
buf.insert(i++, flag);
}
}
return buf.toString();
}
/**
* 添加前后缀
*
* @param str
* 字符串
* @param prefix
* 前缀
* @param suffix
* 后缀
* @return
*/
private String addPrefixORStuffix(String str, String prefix, String suffix) {
StringBuffer buf = new StringBuffer(str.substring(str.lastIndexOf(".")+1));
buf.insert(buf.length(), suffix).insert(0, prefix);
return buf.toString();
}
/**
* 更新样式
* @param str
* @param style
* @return
*/
private String UpdateStyle(String str, String style) {
if ("AU".equals(style)) {
str = str.toUpperCase();
} else if ("AL".equals(style)) {
str = str.toLowerCase();
} else if ("FU".equals(style)) {
StringBuffer buf = new StringBuffer(str.substring(str.lastIndexOf(".")+1));
String upper =buf.substring(0,1).toUpperCase();
buf.delete(0, 1).insert(0, upper);
str = buf.toString();
} else if ("FL".equals(style)) {
StringBuffer buf = new StringBuffer(str.substring(str.lastIndexOf(".")+1));
String lower =buf.substring(0,1).toLowerCase();
buf.delete(0, 1).insert(0, lower);
str = buf.toString();
} else{
}
return str;
}
}
#p#副标题#e#
#p#分页标题#e#
【DatabaseConfiguration】数据库样式设置,包罗前后缀、脱离符、巨细写等
package com.tgb.hibernate.neatlyDB;
import org.hibernate.cfg.Configuration;
/**
* 数据库模式设置
* @author Longxuan
*
*/
public final class DatabaseConfiguration {
/**
* 列名样式
* AU-all upper case
* AL-all lower case
* FU-first upper case per word
* FL-first lower case ,Other first letter upper case
*/
public static enum ColumnTyle {
AU,AL,FU,FL;
}
/**
* 表名称样式
* AU-all upper case
* AL-all lower case
* FU-first upper case per word
* FL-first lower case ,Other first letter upper case
*/
public static enum TableStyle{
AU,AL,FU,FL;
}
/**
* 列名样式
* AU-all upper case
* AL-all lower case
* FU-first upper case per word
* FL-first lower case ,Other first letter upper case
*/
private ColumnTyle columnTyle = ColumnTyle.FL;
/**
* 表名称样式
* AU-all upper case
* AL-all lower case
* FU-first upper case per word
* FL-first lower case ,Other first letter upper case
*/
private TableStyle tableStyle = TableStyle.FU;
/**
* 表名称前缀
*/
private String tablePrefix = "";
/**
* 表名称后缀
*/
private String tableSuffix = "";
/**
* 表名称脱离符
*/
private String tableSeparator = "";
/**
* 列名前缀
*/
private String columnPrefix = "";
/**
* 列名后缀
*/
private String columnSuffix = "";
/**
* 列名脱离符
*/
private String columnSeparator = "";
public ColumnTyle getColumnTyle() {
return columnTyle;
}
public void setColumnTyle(ColumnTyle columnTyle) {
this.columnTyle = columnTyle;
}
public TableStyle getTableStyle() {
return tableStyle;
}
public void setTableStyle(TableStyle tableStyle) {
this.tableStyle = tableStyle;
}
public String getTablePrefix() {
return tablePrefix;
}
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
public String getTableSuffix() {
return tableSuffix;
}
public void setTableSuffix(String tableSuffix) {
this.tableSuffix = tableSuffix;
}
public String getTableSeparator() {
return tableSeparator;
}
public void setTableSeparator(String tableSeparator) {
this.tableSeparator = tableSeparator;
}
public String getColumnPrefix() {
return columnPrefix;
}
public void setColumnPrefix(String columnPrefix) {
this.columnPrefix = columnPrefix;
}
public String getColumnSuffix() {
return columnSuffix;
}
public void setColumnSuffix(String columnSuffix) {
this.columnSuffix = columnSuffix;
}
public String getColumnSeparator() {
return columnSeparator;
}
public void setColumnSeparator(String columnSeparator) {
this.columnSeparator = columnSeparator;
}
/**
* 初始化,读取设置参数,默认读取Hibernate.cfg.xml
* @param cfg
*URL:http://www.bianceng.cn/Programming/Java/201410/45829.htm
*/
public DatabaseConfiguration(){
ReadConfig(new Configuration().configure());
}
/**
* 初始化,读取设置文件
* @param cfg
*/
public DatabaseConfiguration(Configuration cfg){
ReadConfig(cfg);
}
/**
* 自动读取设置信息
* @param cfg
*/
private void ReadConfig(Configuration cfg){
tableStyle = cfg.getProperty("tablestyle")==""?TableStyle.FU:TableStyle.valueOf(cfg.getProperty("tablestyle"));
tablePrefix = cfg.getProperty("tablePrefix");
tableSuffix = cfg.getProperty("tablesuffix");
tableSeparator = cfg.getProperty("tableseparator");
columnTyle = cfg.getProperty("columntyle")==""?ColumnTyle.FL:ColumnTyle.valueOf(cfg.getProperty("columntyle"));
columnPrefix = cfg.getProperty("columnPrefix");
columnSuffix = cfg.getProperty("columnsuffix");
columnSeparator = cfg.getProperty("columnseparator");
}
}
#p#分页标题#e#
【hibernate.cfg.xml】配置数据库样式设置信息
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="foo">
<!--
name: 设置的名称
style: 范例 列举AU-all upper case
AL-all lower case
FU-first letter upper case per word
FL-first letter lower case ,Other first letters upper case
befix: 前缀
suffix: 后缀
separator: 脱离符
-->
<property name="tablestyle">FU</property>
<property name="tablePrefix" >T_</property>
<property name="tablesuffix" ></property>
<property name="tableseparator" >_</property>
<property name="columntyle">FU</property>
<property name="columnPrefix">[stu_</property>
<property name="columnsuffix">]</property>
<property name="columnseparator">_</property>
<property name="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property><!-- 配置是否显示生成sql语句 -->
<property name="hibernate.format_sql">false</property><!-- 配置是否名目化sql语句-->
<mapping resource="com/bjpowernode/hibernate/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
#p#分页标题#e#
【User.hbm.xml】映射文件可以较量随意的修改可能设定了
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="Users">
<id name="id" column="pid">
<generator class="uuid" />
</id>
<property name="name" column="userName"></property>
<property name="password" column="pwd"></property>
<property name="createTime"></property>
<property name="expireTime"></property>
</class>
</hibernate-mapping>
#p#分页标题#e#
最后修改一下【ExportDB】,主要是修改必需先配置NamingStrategy,在挪用configure要领
package com.bjpowernode.hibernate;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import com.tgb.hibernate.neatlyDB.DatabaseConfiguration;
import com.tgb.hibernate.neatlyDB.MyNamingStrategy;
/**
* 将hbm生成ddl
* @author Longxuan
*
*/
public class ExportDB {
/**
* @param args
*/
public static void main(String[] args) {
//默认读取hibernate.cfg.xml文件,并凭据定名计策修改表、字段的名称
//Configuration cfg = new Configuration().configure();
//留意,必需先配置NamingStrategy,在挪用configure要领
Configuration cfg = new Configuration().setNamingStrategy(MyNamingStrategy.getInstance()).configure();
SchemaExport export = new SchemaExport(cfg);
//true 在节制台打印ddl语句,true 导入ddl语句到数据库,即可执行
export.create(true, true);
}
}
看一下功效图吧:表名,字段名都已经修悔改了。

上面演示的是生成数据表。在对数据库的增删改查时,只要同样配置NamingStrategy即可。
为了各人更为利便的利用,已经做成jar包分享给各人了:http://pan.baidu.com/share/link?shareid=1107664883&uk=1259218556