hibernate如何实现多个表结构相同的表对应同一个实体类

关于hibernate的使用这里就不多说了,

我们都知道在使用hibernate提供的框架时,我们只需要写好相关配置文件,对应好映射关系,在代码中运用好SQL语句就可以很好地与数据库进行交互,往往我们都是在数据已经建好的基础上进行一系列操作的,但是我们也可以在xml文件中配置

<property name="hibernate.hbm2ddl.auto">
   update
 </property>

即使在数据库中没有此表最终也会自动生成一个表,但是这个表名在配置时就已经被确定了,即使在运用的时候也必须使用该表名,一般情况确实是这样的。

现在有这样一个需求,根据传递的参数可以动态生成一张表,表名即为传递的参数,目前这个建表过程我使用了一个最原始的方法
public String createTable(){
  try {
   HttpServletRequest request = ServletActionContext.getRequest();
   String name = request.getParameter("name");
   Session session = HibernateSessionFactory.getSession();
   Connection con = (Connection) HibernateSessionFactory.getConnection();
   Statement stmt = (Statement) con.createStatement();

   //判断数据库中是否已经存在这个表

   ResultSet tabs = null;
   DatabaseMetaData dbMetaData = conn.getMetaData();
   String[]   types   =   { "TABLE" };
   tabs = dbMetaData.getTables(null, null, name, types);
   if (tabs.next()) {
      stmt.execute("create table "+name+"(id int primary key,username varchar(45),password varchar(45))");
   }
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   HibernateSessionFactory.closeSession();
  }
  return SUCCESS;
 }

其中HibernateSessionFactory是一个自己写的工厂类,用于创建session对象;

下面就要使用hibernate进行数据库操作了,一般来说当我们创建了session对象,调用save(),update()等方法或者使用SQL语句得到Query对象,在这操作执行之后,他们都会向数据库发送一段sql语句,我们要做的就是在数据库执行这条语句之前改造这条语句,此时我们可以使用hibernate的的拦截器 EmptyInterceptor

我们写一个类只要继承这个类,重写@Override
 public String onPrepareStatement(String sql) {
  return sql;
 }

这个方法,其中方法内的参数就是要发送给数据库的sql语句,我们只需要分析这个语句将其中的table名替换掉就可以了,至于具体规则可以将自己想项目中可能出现的sql语句打印出来分析替换即可

例如对于一个普通的查询语句"select * from table"

String newSQL = "";
 String str = "select * from table";
  String[] from = str.split(" ");
  boolean flag = false;
  for (int i = 0; i < from.length; i++) {
   if("from".equalsIgnoreCase(from[i])){
    newSQL += from[i]+" ";
    from[i+1] = tableName;
    newSQL += from[i+1]+" ";
    flag = true;
   }else{
    if(flag){
     flag = false;
     continue;
    }
    newSQL += from[i]+" ";
   }
  }

tableName为需要替换的表名

最后在使用的时候我们通过SessionFactory.openSession(Interceptor arg0)方法将拦截器作为参数获得session对象,接下来的操作就大体相似了

猜你喜欢

转载自baodaqin.iteye.com/blog/2307999