hibernate实现动态表名

来源:互联网 发布:金融炼金术知乎 编辑:程序博客网 时间:2024/06/05 18:13

起因:

mysql数据库中生成的表有的名字是大写,有的是小写,有的和类名相同,有的后面加了日期,也就是所谓的动态表名,每月都会自动产生一个新的表。

环境:

mysql5.5+hibernate3

分析:

当然我是菜鸟,直接不知道原因,通过对比发现了原因。需要解决的问题其实有以下几个:

类怎么和表名对应
表名大小写怎么产生的
如何产生动态的表名
解决:

第一个问题类怎么和表名对应:

hibernate.cfg.xml 中添加类对应的配置文件,在这个Player.hbm.xml的配置最重要。

<mapping resource="com/joyfort/nova/persist/hibernate/game/model/Player.hbm.xml" />

看一下Player.hbm.xml内容,这个里面的table指定的就是表名,如果这里你不指定表名,则class标签对应的类名就是表名

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.joyfort.nova.persist.hibernate.game.model.Player" table="player">
        <id name="uid" type="java.lang.String">
            <column name="uid" />
            <generator class="uuid.hex" />
        </id>
        <property name="username" type="java.lang.String">
            <column name="username" length="50" unique="true" />
        </property>
    </class>
</hibernate-mapping>

第二个问题表名大小写怎么产生的:
在第一个里面,假如我们在Player.hbm.xml配置文件里边没有指定table,那么表名就是你的类名,我们用的系统是Win7,mysql的配置也是默认的,这个时候产生的表名是Player。

也就是说表名大小写和三个因素有关:你的系统,mysql配置,你的类名。

大写的表名对我们的程序调用肯定会用影响,我们最好全部变为小写的,便于在任何操作系统下使用。

关于这个的解决方法http://hi.baidu.com/virackt/item/ec94abd780b60f1fe0f46f1c 这篇文章说的比较详细。

简单来说就是:

       在MySQL的配置文件中my.ini [mysqld] 中增加一行

  lower_case_table_names = 1

  参数解释:

  0:区分大小写

  1:不区分大小写

第三个问题如何产生动态的表名

这个问题,是第一个和第二个的升华我觉得。我们已经明白如果在Player.hbm.xml配置文件里边已经指定table了,那肯定产生的是一个固定名称的表了。

所以要产生动态表名的前提肯定是我们不在配置文件中指定table值。那我们就需要了解hibernate产生表的原理了。

Hibernate中的NamingStrategy可以实现这个功能,它是用来定义表名和列名映射规则的一个接口。我们可以通过实现这个接口实现生成动态表名的这个命名策略。这个接口包含十个方法,其中的classToTableName(String className)是通过类名来映射表名的。我们实现这个方法就可以了。

1、自定义一个类LogsNamingStrategy继承适配器类DefaultNamingStrategy。

2、实现public String classToTableName(String className)方法来实现自己命名策略,这个方法里面的内容我们根据自己的需求随便设定即可。

public class LogsNamingStrategy extends DefaultNamingStrategy {
    /**
  *
  */
 private static final long serialVersionUID = 1L;
 public static final LogsNamingStrategy INSTANCE = new LogsNamingStrategy();
 public static List<String> SUBMETER_TABLE = new ArrayList<String>();
 static{
  SUBMETER_TABLE.add(LogBuy.class.toString());
  SUBMETER_TABLE.add(LogChat.class.toString());
  SUBMETER_TABLE.add(LogBattleresult.class.toString());
  SUBMETER_TABLE.add(LogMsgAction.class.toString());
 }
 private static String  TABLE_NAME = DateUtil.getDateStr(new Date(), "yyyy_MM");
 @Override
    public String classToTableName(String className) {
  if(SUBMETER_TABLE.contains("class "+className)){
   return  super.classToTableName(className)+"_"+TABLE_NAME.toLowerCase();
  }
   return  super.classToTableName(className).toLowerCase();
    }  
}


 

3、将这个策略即LogsNamingStrategy配置进程序,即在创建hibernate的Configuration对象时调用我们自己实现的LogsNamingStrategy命名策略。

Configuration configuration = new Configuration().setNamingStrategy(LogsNamingStrategy.INSTANCE)

不过还有一点不明白,现在我能看到的是,服务器启动时,假如没这个表,hibernate配置文件中是这样的:

<property name="hibernate.hbm2ddl.auto">create</property>
那么,启动服务器的时候,classToTableName方法就会被调用。

那么,如果服务器一直运行的好好的,到了新的月,得生成新表名了吧,这个时候难道需要重启服务器,难道每个月都重启一下服务器?我觉得很二。
于是我测了一下,很悲剧的发现,果然只在服务器启动的时候调用。不知道是不是我测得有问题,反正我觉得很二。

 

 

那这样其实也无法满足每个月动态更换表名的需求,需要建一个比较完善的建表策略了,等我们有了好的解决方案再发表上来吧。

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 合同写错了字怎么办 农行卡转工行卡怎么办 外地人在北京交社保退休怎么办 身份证掉了单位宿舍怎么办居住证 广州租住单位宿舍怎么办居住证 公司u盾丢了怎么办 北京办了居住卡怎么办延期 商铺被陌生人注册左公司怎么办 营业执照年检登录密码忘了怎么办 欠人家钱没钱还怎么办 欠钱实在没钱还怎么办 党关系丢了10年怎么办? 离婚后生孩子怎么办出生证明 注册公司没有注册地址怎么办 银行流水不够2倍怎么办 个体户小店怎么办五险 姓和名五行相克怎么办? 三星s7刷机后计算器没有了怎么办 线雕鼻子山根鼓怎么办 在日本没有日币怎么办 明知合同回扣特别高怎么办 医院药品断货了怎么办 空腹吃菠萝胃疼怎么办 小孩黑户口怎么办上户 别人说名字起大了怎么办? 念佛号时心老是不集中怎么办 扑lv期嗓子痛头痛怎么办 公众号忘记了账号怎么办 公众号账号密码忘记了怎么办 现实生活被小人缠上怎么办 五行缺木和水怎么办 八字火旺的人怎么办 综合旺衰得分负怎么办 妈妈误打死一只黄鼠狼怎么办 油笔画在白墙上怎么办 壁纸上的水彩笔怎么办 隐形拉链头脱了怎么办 拉链的一边掉了怎么办 帝豪gs加了乙醇汽油怎么办 命理五行缺木怎么办 微信改名含有特殊符号怎么办