Ibatis和Hibernate 數據庫分表(動態表名映射)的實現方法
自從ibatis 2.0.9以后,ibatis支持動態表名。
以下為用Map做參數的動態表名實現方法:
示例代碼如下:
Sample :
< select id ="getRighe"
remapResults ="true"
resultMap ="resultRighe"
parameterClass ="java.util.Map" >
select * from
$tablePrefix$_righe
where IDUser = #IDUser#
</ select >
and java code :
param.put("IDUser", IDUser);
param.put("tablePrefix", "NAG");
utente = (Riga)getSqlMapClientTemplate().queryForObject("getRighe", param);
但 如果我們要插入一個對象,我們需傳進一個POJO對象,由于Ibatis 只能接受一個參數,這時用Map來傳對象,會比較麻煩
可不可以用POJO對象里的一個屬性來決定表名呢?
答案是肯定的。
在分表設計的數據庫中,一般存在許多結構相同,但表名后綴不同的表。
我們在插入一個新對象到表中里,由自己制定的路由規則是可以得到這個對象要插到那個表里的。即程序知道插到哪個表里,那么
怎么讓Ibatis也知道呢?
當然你可以把Pojo對象屬性全放到Map里,再在Map里加一個表名的屬性,傳給Ibatis,但這樣比較麻煩
我們可以為每一個POJO對象增加一個表名后綴的屬性(或表名),在Ibatis里直接用這個屬性做表名。
不過,且記,用“$”來界定這個屬性的名字,而不是“#”
因為,在Ibatis里,每一個#,除了替換值,它都會加上一個單引號'.
如下例所示:(假設,你在Pojo對象里,增加了一個suffix的屬性,就可以這樣來決定插入表名)
INSERT INTO myTable$suffix$
(column1,column2)
VALUES (#column1#,#column2#)
這時的parameterClass仍為你的Pojo類。
Ibatis能比較方便地實現數據庫的分表問題,Hibernate可以用NamingStrategy實現動態表名映射
以下內容引自:http://jinguo.javaeye.com/blog/209642
用一個配置文件,一個類去映射多個表,(每個表的結構相同)。按照平時的做法,有多少個表就要
寫多少個配置文件,豈不是很麻煩。怎樣才能只寫一個配置文件就能達到上述目的呢?
經過研究,發現Hibernate中的NamingStrategy可以達到這個目的。它是用來定義表名和列名映射規
則的一個接口。我們要通過實現這個接口來實現自己的命名策略。這個接口中包含的十個方法,其中的
public String classToTableName(String className)是通過類名來映射表名的。實現我們的想法就要用
到這個方法。好了,下面來看怎么做:
1、自定義一個類MyNamingStrategy來實現NamingStrategy。(這樣你要實現10個方法,如果其他方法
不需要,我們可以通過繼承它的一個適配器類DefaultNamingStrategy來只實現我們需要的方法)好了,我
們就繼承DefaultNamingStrategy 吧。
2、實現public String classToTableName(String className)方法來實現自己命名策略。
例如業務需要是每隔一個月就要換一個表。比如1月用biz_1,那么2月就用biz_2....但是這些表的結構是相同的。我們要做的就是通過獲得月份來動態的選擇表。我們從這個方法中這樣寫:
public class MyNamingStrategy extends DefaultNamingStrategy {
public static final MyNamingStrategy INSTANCE = new MyNamingStrategy();
public String classToTableName(String className) {
return "biz_" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
}
好了,這樣就可以根據月份來動態的選擇表名了。
3、使用命名策略。
要使用這個命名策略可以這樣:
Configuration cfg = new Configuration()
.setNamingStrategy(MyNamingStrategy.INSTANCE)
.configure("hibernate.cfg.xml")
.addFile("biz.hbm.xml");
----------------------------------
for exemple
package com.etong.common.hibernate;
import net.sf.hibernate.cfg.NamingStrategy;
import net.sf.hibernate.util.StringHelper;
/**
* <p>Title: TNamingStrategy</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* <p>Created on 2005-5-30 </p>
* @author jinguo
* @version 1.0
*
*/
public class TNamingStrategy implements NamingStrategy {
/**
* @see net.sf.hibernate.cfg.NamingStrategy#classToTableName(java.lang.String)
*/
public String classToTableName(String className) {
return tableName(StringHelper.unqualify(className).toUpperCase());
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToColumnName(java.lang.String)
* @todo
*/
public String propertyToColumnName(String arg0) {
return null;
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#tableName(java.lang.String)
*/
public String tableName(String tableName) {
return "TBL_" + tableName.toUpperCase();
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#columnName(java.lang.String)
*/
public String columnName(String columnName) {
return "COL_" + columnName;
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToTableName(java.lang.String, java.lang.String)
* @todo
*/
public String propertyToTableName(String arg0, String arg1) {
return null;
}
}
以下為用Map做參數的動態表名實現方法:
示例代碼如下:
Sample :
< select id ="getRighe"
remapResults ="true"
resultMap ="resultRighe"
parameterClass ="java.util.Map" >
select * from
$tablePrefix$_righe
where IDUser = #IDUser#
</ select >
and java code :
param.put("IDUser", IDUser);
param.put("tablePrefix", "NAG");
utente = (Riga)getSqlMapClientTemplate().queryForObject("getRighe", param);
但 如果我們要插入一個對象,我們需傳進一個POJO對象,由于Ibatis 只能接受一個參數,這時用Map來傳對象,會比較麻煩
可不可以用POJO對象里的一個屬性來決定表名呢?
答案是肯定的。
在分表設計的數據庫中,一般存在許多結構相同,但表名后綴不同的表。
我們在插入一個新對象到表中里,由自己制定的路由規則是可以得到這個對象要插到那個表里的。即程序知道插到哪個表里,那么
怎么讓Ibatis也知道呢?
當然你可以把Pojo對象屬性全放到Map里,再在Map里加一個表名的屬性,傳給Ibatis,但這樣比較麻煩
我們可以為每一個POJO對象增加一個表名后綴的屬性(或表名),在Ibatis里直接用這個屬性做表名。
不過,且記,用“$”來界定這個屬性的名字,而不是“#”
因為,在Ibatis里,每一個#,除了替換值,它都會加上一個單引號'.
如下例所示:(假設,你在Pojo對象里,增加了一個suffix的屬性,就可以這樣來決定插入表名)
INSERT INTO myTable$suffix$
(column1,column2)
VALUES (#column1#,#column2#)
這時的parameterClass仍為你的Pojo類。
Ibatis能比較方便地實現數據庫的分表問題,Hibernate可以用NamingStrategy實現動態表名映射
以下內容引自:http://jinguo.javaeye.com/blog/209642
用一個配置文件,一個類去映射多個表,(每個表的結構相同)。按照平時的做法,有多少個表就要
寫多少個配置文件,豈不是很麻煩。怎樣才能只寫一個配置文件就能達到上述目的呢?
經過研究,發現Hibernate中的NamingStrategy可以達到這個目的。它是用來定義表名和列名映射規
則的一個接口。我們要通過實現這個接口來實現自己的命名策略。這個接口中包含的十個方法,其中的
public String classToTableName(String className)是通過類名來映射表名的。實現我們的想法就要用
到這個方法。好了,下面來看怎么做:
1、自定義一個類MyNamingStrategy來實現NamingStrategy。(這樣你要實現10個方法,如果其他方法
不需要,我們可以通過繼承它的一個適配器類DefaultNamingStrategy來只實現我們需要的方法)好了,我
們就繼承DefaultNamingStrategy 吧。
2、實現public String classToTableName(String className)方法來實現自己命名策略。
例如業務需要是每隔一個月就要換一個表。比如1月用biz_1,那么2月就用biz_2....但是這些表的結構是相同的。我們要做的就是通過獲得月份來動態的選擇表。我們從這個方法中這樣寫:
public class MyNamingStrategy extends DefaultNamingStrategy {
public static final MyNamingStrategy INSTANCE = new MyNamingStrategy();
public String classToTableName(String className) {
return "biz_" + Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
}
}
好了,這樣就可以根據月份來動態的選擇表名了。
3、使用命名策略。
要使用這個命名策略可以這樣:
Configuration cfg = new Configuration()
.setNamingStrategy(MyNamingStrategy.INSTANCE)
.configure("hibernate.cfg.xml")
.addFile("biz.hbm.xml");
----------------------------------
for exemple
package com.etong.common.hibernate;
import net.sf.hibernate.cfg.NamingStrategy;
import net.sf.hibernate.util.StringHelper;
/**
* <p>Title: TNamingStrategy</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Company: </p>
* <p>Created on 2005-5-30 </p>
* @author jinguo
* @version 1.0
*
*/
public class TNamingStrategy implements NamingStrategy {
/**
* @see net.sf.hibernate.cfg.NamingStrategy#classToTableName(java.lang.String)
*/
public String classToTableName(String className) {
return tableName(StringHelper.unqualify(className).toUpperCase());
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToColumnName(java.lang.String)
* @todo
*/
public String propertyToColumnName(String arg0) {
return null;
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#tableName(java.lang.String)
*/
public String tableName(String tableName) {
return "TBL_" + tableName.toUpperCase();
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#columnName(java.lang.String)
*/
public String columnName(String columnName) {
return "COL_" + columnName;
}
/**
* @see net.sf.hibernate.cfg.NamingStrategy#propertyToTableName(java.lang.String, java.lang.String)
* @todo
*/
public String propertyToTableName(String arg0, String arg1) {
return null;
}
}