上海专业网站制作开发/长沙seo网络营销推广
刚完成的项目需求:一个全省范围内的项目,所有市访问同一个网站,所有市对自身的数据有管理权限;在这些数据中,一公告这么一个实体,所有管理员均可向这张表中写入数据,每个月的数据都会超过万条。为避免公告表变成巨无霸,现将公告表按区域、公告类型分表。
主要代码就一个类:
/*** */
package com.hbcgs.notice.interceptor;import org.hibernate.EmptyInterceptor;/*** @author Geloin* */
@SuppressWarnings("serial")
public class NoticeInfoInterceptor extends EmptyInterceptor {private String targetTableName;// 目标母表名private String tempTableName;// 操作子表名public NoticeInfoInterceptor() {}// 为其在spring好好利用 我们生成公用无参构造方法@Overridepublic java.lang.String onPrepareStatement(java.lang.String sql) {sql = sql.replaceAll(targetTableName, tempTableName);return sql;}public String getTargetTableName() {return targetTableName;}public void setTargetTableName(String targetTableName) {this.targetTableName = targetTableName;}public String getTempTableName() {return tempTableName;}public void setTempTableName(String tempTableName) {this.tempTableName = tempTableName;}}
在控制分表时,在管理数据层,假设是Dao层,进行以下处理:
/*** 保存公告信息,分表保存* * @param info*/public void save(NoticeInfo info) {SessionFactory sf = super.getHibernateTemplate().getSessionFactory();NoticeInfoInterceptor interceptor = new NoticeInfoInterceptor();// 要拦截的目标表名interceptor.setTargetTableName("noticeinfo");String realTableName = "NOTICEINFO_" + info.getArea().getAreaId() + "_"+ info.getType();// 要替换的子表名interceptor.setTempTableName(realTableName);try {if (!existsTableNames.contains(realTableName)) {checkTable(sf.openSession(), realTableName);existsTableNames.add(realTableName);}} catch (Exception e) {e.printStackTrace();}Session session = sf.openSession(interceptor);try {// 获取事务Transaction tx = session.beginTransaction();// 开启事务tx.begin();// 保存和更新session.saveOrUpdate(info);// 提交tx.commit();} catch (Exception e) {e.printStackTrace();} finally {session.close();}}
Dao层继承了org.springframework.orm.hibernate3.support.HibernateDaoSupport类,checkTable方法主要是为了检查表是否存在,不存在时需要建表:
/*** 检查表是否存在,不存在时创建* * @param session* @param tableName* @throws Exception*/private void checkTable(Session session, String tableName) throws Exception {try {// 测试查询String testSql = "select * from " + tableName;Query query = session.createSQLQuery(testSql);query.setFirstResult(0);query.setMaxResults(1);query.uniqueResult();} catch (HibernateException e) {// Connection conn = session.connection();// Statement stmt = conn.createStatement();StringBuilder builder = new StringBuilder();builder.append("create table ");builder.append(tableName);builder.append("(");builder.append("ID NUMBER(10) not null,");builder.append("STR1 VARCHAR2(255),");builder.append("STR2 VARCHAR2(255),");builder.append("STR3 VARCHAR2(255),");builder.append("STR4 VARCHAR2(255),");builder.append("STR5 VARCHAR2(255),");builder.append("STR6 VARCHAR2(255),");builder.append("STR7 VARCHAR2(255),");builder.append("STR8 VARCHAR2(255),");builder.append("STR9 VARCHAR2(255),");builder.append("STR10 VARCHAR2(255),");builder.append("PYEAR NUMBER(10),");builder.append("PMONTH NUMBER(10),");builder.append("TYPE NUMBER(10),");builder.append("AREA_ID NUMBER(10)");builder.append(")");Query query = session.createSQLQuery(builder.toString());query.executeUpdate();} finally {session.flush();session.close();}}
实现方法显然比较粗糙,不过暂时够解决问题,Mark一下。