Hibernate传入Java对象创建动态表并录入数据
看到Hibernate你给一个对象,他就能动态的创建配置文件里面指定的表名,然后把数据录入到数据库,当初感觉是很神奇,不过,好像Hibernate不能动态的分表创建表和录入数据
我这里写了一个公用的类,你给一个对象,告诉我按年还是按月生成表,并告诉我那个字段是不需要在表中创建的,该类就可以动态的分表创建需要的表,并录入数据
注意:
由于业务需要,这里对于字段的支持只有int和Integer,double和Double
还有String,同时对于String统一创建为了Varchar(100)的字段
表会统一创建一个id自增主键
packagecom.xd.nms.util;
importjava.lang.reflect.Field;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.Map;
importjava.util.Set;
importorg.apache.commons.logging.Log;
importorg.apache.commons.logging.LogFactory;
importorg.springframework.jdbc.core.JdbcTemplate;
/**
*@说明动态插入数据和创建表
*@author崔素强
*@version1.0
*@since
*/
publicclassCommonTableInsert{
publicstaticLoglogger=LogFactory.getLog(CommonTableInsert.class);
/**
*入口方法
*@paramtableName表前缀
*@paramdateFormat格式化方法
*@paramobj保存的对象
*@return
*/
@SuppressWarnings("unchecked")
publicstaticintinsertObject(StringtableName,StringdateFormat,Objectobj,MapnoCol){
intre=0;
try{
JdbcTemplatejt=(JdbcTemplate)SpringFactory.getObject("jdbcTemplate");
SimpleDateFormatformat=newSimpleDateFormat(dateFormat);
Stringtname=tableName+"_"+format.format(newDate());
if(CommonDBUtil.getAllTableName(jt,tname)){//如果有某表
re=saveObj(jt,tname,obj,noCol);//保存数据
}else{
re=createTable(jt,tname,obj,noCol);//动态创建表
if(re==1){
re=saveObj(jt,tname,obj,noCol);//保存数据
}
}
}catch(Exceptione){
logger.error("公用方法插入数据入口方法错误",e);
}
returnre;
}
/**
*保存方法,注意这里传递的是实际的表的名称
*/
@SuppressWarnings("unchecked")
privatestaticintsaveObj(JdbcTemplatejt,StringtableName,Objectobj,MapnoCol){
intre=0;
StringBuffersb=newStringBuffer("");
try{
sb.append("insertinto"+tableName+"(");
Mapmap=ObjectUtil.getProAndValMap(obj);//对象的属性和属性值
MapmapType=ObjectUtil.getProTypeMap(obj);//对象的属性类型列表
Setset=map.keySet();
for(Stringkey:set){
//如果该列不是非处理列
if(noCol.get(key)==null){
sb.append(key+",");
}
}
sb.append("tableName)");
sb.append("values(");
for(Stringkey:set){
if(noCol.get(key)==null){
if(mapType.get(key).equals("classjava.lang.String")){
sb.append("'"+(map.get(key)+"',"));
}else{
sb.append(map.get(key)+",");
}
}
}
sb.append("'"+tableName+"');");
re=jt.update(sb.toString());
}catch(Exceptione){
logger.error("公用方法录入数据时错误",e);
logger.error("公用方法录入数据语句:"+sb.toString());
}
returnre;
}
/**
*根据表名称和实体属性创建一张表
*@paramtableName
*@paramobj具体生成什么样的表看该对象
*/
@SuppressWarnings("unchecked")
privatestaticintcreateTable(JdbcTemplatejt,StringtableName,Objectobj,MapnoCol){
StringBuffersb=newStringBuffer("");
sb.append("CREATETABLE`"+tableName+"`(");
sb.append("`id`int(11)NOTNULLAUTO_INCREMENT,");
Classc=obj.getClass();
Fieldfield[]=c.getDeclaredFields();
for(Fieldf:field){
if(noCol.get(f.getName())==null){
Stringtype=f.getType().toString();
if(type.equals("classjava.lang.String")){//Str
sb.append("`"+f.getName()+"`varchar(100)DEFAULTNULL,");
}elseif(type.equals("int")||type.equals("classjava.lang.Integer")){//int
sb.append("`"+f.getName()+"`int(11)DEFAULTNULL,");
}elseif(type.equals("double")||type.equals("classjava.lang.Double")){//double
sb.append("`"+f.getName()+"`doubleDEFAULTNULL,");
}
}
}
sb.append("`tableName`varchar(255)DEFAULTNULL,");
sb.append("PRIMARYKEY(`id`)");
sb.append(")ENGINE=InnoDBDEFAULTCHARSET=utf8;");
try{
jt.update(sb.toString());
return1;
}catch(Exceptione){
logger.error("公用方法生成表时错误",e);
logger.error("公用方法生成表语句:"+sb.toString());
}
return0;
}
}
这个对于之前写的那个动态建表,新增了过滤不需要在表中创建的字段
原理就是读取对象的各个字段属性,如果能加以配置文件或者读取对象属性的标记,那其实能做到基本和Hibernate一致,不但能支持多种类型,还能做字段校验等
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。