传入Java对象 自动创建动态表 并录入数据
2017-10-27 10:17
417 查看
看到Hibernate你给一个对象,他就能动态的创建配置文件里面指定的表名,然后把数据录入到数据库,当初感觉是很神奇,不过,好像Hibernate不能动态的分表创建表和录入数据
我这里写了一个公用的类,你给一个对象,告诉我按年还是按月生成表,并告诉我那个字段是不需要在表中创建的,该类就可以动态的分表创建需要的表,并录入数据
注意:
由于业务需要,这里对于字段的支持只有int和Integer,double和Double
还有String,同时对于String统一创建为了Varchar(100)的字段
表会统一创建一个id自增主键
Java代码
package com.xd.nms.util;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @说明 动态插入数据和创建表
* @author 崔素强
* @version 1.0
* @since
*/
public class CommonTableInsert {
public static Log logger = LogFactory.getLog(CommonTableInsert.class);
/**
* 入口方法
* @param tableName 表前缀
* @param dateFormat 格式化方法
* @param obj 保存的对象
* @return
*/
@SuppressWarnings("unchecked")
public static int insertObject(String tableName,String dateFormat,Object obj, Map noCol){
int re = 0;
try {
JdbcTemplate jt = (JdbcTemplate) SpringFactory.getObject("jdbcTemplate");
SimpleDateFormat format = new SimpleDateFormat(dateFormat);
String tname = tableName + "_" + format.format(new Date());
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 (Exception e) {
logger.error("公用方法插入数据入口方法错误", e);
}
return re;
}
/**
* 保存方法,注意这里传递的是实际的表的名称
*/
@SuppressWarnings("unchecked")
private static int saveObj(JdbcTemplate jt,String tableName,Object obj, Map noCol){
int re = 0;
StringBuffer sb = new StringBuffer("");
try{
sb.append(" insert into " + tableName + " (");
Map<String,String> map = ObjectUtil.getProAndValMap(obj); // 对象的属性和属性值
Map<String,String> mapType = ObjectUtil.getProTypeMap(obj); // 对象的属性类型列表
Set<String> set = map.keySet();
for(String key : set){
// 如果该列不是 非处理列
if(noCol.get(key) == null){
sb.append(key + ",");
}
}
sb.append(" tableName ) ");
sb.append(" values ( ");
for(String key : set){
if(noCol.get(key) == null){
if(mapType.get(key).equals("class java.lang.String")){
sb.append("'" + (map.get(key) + "',"));
}else{
sb.append(map.get(key) + ",");
}
}
}
sb.append("'" + tableName + "'); ");
re = jt.update(sb.toString());
} catch (Exception e) {
logger.error("公用方法录入数据时错误", e);
logger.error("公用方法录入数据语句:" + sb.toString());
}
return re;
}
/**
* 根据表名称 和 实体属性 创建一张表
* @param tableName
* @param obj 具体生成什么样的表看该对象
*/
@SuppressWarnings("unchecked")
private static int createTable(JdbcTemplate jt,String tableName,Object obj, Map noCol){
StringBuffer sb = new StringBuffer("");
sb.append("CREATE TABLE `" + tableName + "` (");
sb.append(" `id` int(11) NOT NULL AUTO_INCREMENT,");
Class c = obj.getClass();
Field field[] = c.getDeclaredFields();
for (Field f : field) {
if(noCol.get(f.getName()) == null){
String type = f.getType().toString();
if(type.equals("class java.lang.String")){// Str
sb.append("`" + f.getName() + "` varchar(100) DEFAULT NULL,");
}else if(type.equals("int") || type.equals("class java.lang.Integer")){// int
sb.append("`" + f.getName() + "` int(11) DEFAULT NULL,");
}else if(type.equals("double") || type.equals("class java.lang.Double")){// double
sb.append("`" + f.getName() + "` double DEFAULT NULL,");
}
}
}
sb.append(" `tableName` varchar(255) DEFAULT NULL,");
sb.append(" PRIMARY KEY (`id`)");
sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
try {
jt.update(sb.toString());
return 1;
} catch (Exception e) {
logger.error("公用方法生成表时错误", e);
logger.error("公用方法生成表语句:" + sb.toString());
}
return 0;
}
}
这个对于之前写的那个动态建表,新增了过滤不需要在表中创建的字段
原理就是读取对象的各个字段属性,如果能加以配置文件或者读取对象属性的标记,那其实能做到基本和Hibernate一致,不但能支持多种类型,还能做字段校验等
我这里写了一个公用的类,你给一个对象,告诉我按年还是按月生成表,并告诉我那个字段是不需要在表中创建的,该类就可以动态的分表创建需要的表,并录入数据
注意:
由于业务需要,这里对于字段的支持只有int和Integer,double和Double
还有String,同时对于String统一创建为了Varchar(100)的字段
表会统一创建一个id自增主键
Java代码
package com.xd.nms.util;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* @说明 动态插入数据和创建表
* @author 崔素强
* @version 1.0
* @since
*/
public class CommonTableInsert {
public static Log logger = LogFactory.getLog(CommonTableInsert.class);
/**
* 入口方法
* @param tableName 表前缀
* @param dateFormat 格式化方法
* @param obj 保存的对象
* @return
*/
@SuppressWarnings("unchecked")
public static int insertObject(String tableName,String dateFormat,Object obj, Map noCol){
int re = 0;
try {
JdbcTemplate jt = (JdbcTemplate) SpringFactory.getObject("jdbcTemplate");
SimpleDateFormat format = new SimpleDateFormat(dateFormat);
String tname = tableName + "_" + format.format(new Date());
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 (Exception e) {
logger.error("公用方法插入数据入口方法错误", e);
}
return re;
}
/**
* 保存方法,注意这里传递的是实际的表的名称
*/
@SuppressWarnings("unchecked")
private static int saveObj(JdbcTemplate jt,String tableName,Object obj, Map noCol){
int re = 0;
StringBuffer sb = new StringBuffer("");
try{
sb.append(" insert into " + tableName + " (");
Map<String,String> map = ObjectUtil.getProAndValMap(obj); // 对象的属性和属性值
Map<String,String> mapType = ObjectUtil.getProTypeMap(obj); // 对象的属性类型列表
Set<String> set = map.keySet();
for(String key : set){
// 如果该列不是 非处理列
if(noCol.get(key) == null){
sb.append(key + ",");
}
}
sb.append(" tableName ) ");
sb.append(" values ( ");
for(String key : set){
if(noCol.get(key) == null){
if(mapType.get(key).equals("class java.lang.String")){
sb.append("'" + (map.get(key) + "',"));
}else{
sb.append(map.get(key) + ",");
}
}
}
sb.append("'" + tableName + "'); ");
re = jt.update(sb.toString());
} catch (Exception e) {
logger.error("公用方法录入数据时错误", e);
logger.error("公用方法录入数据语句:" + sb.toString());
}
return re;
}
/**
* 根据表名称 和 实体属性 创建一张表
* @param tableName
* @param obj 具体生成什么样的表看该对象
*/
@SuppressWarnings("unchecked")
private static int createTable(JdbcTemplate jt,String tableName,Object obj, Map noCol){
StringBuffer sb = new StringBuffer("");
sb.append("CREATE TABLE `" + tableName + "` (");
sb.append(" `id` int(11) NOT NULL AUTO_INCREMENT,");
Class c = obj.getClass();
Field field[] = c.getDeclaredFields();
for (Field f : field) {
if(noCol.get(f.getName()) == null){
String type = f.getType().toString();
if(type.equals("class java.lang.String")){// Str
sb.append("`" + f.getName() + "` varchar(100) DEFAULT NULL,");
}else if(type.equals("int") || type.equals("class java.lang.Integer")){// int
sb.append("`" + f.getName() + "` int(11) DEFAULT NULL,");
}else if(type.equals("double") || type.equals("class java.lang.Double")){// double
sb.append("`" + f.getName() + "` double DEFAULT NULL,");
}
}
}
sb.append(" `tableName` varchar(255) DEFAULT NULL,");
sb.append(" PRIMARY KEY (`id`)");
sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
try {
jt.update(sb.toString());
return 1;
} catch (Exception e) {
logger.error("公用方法生成表时错误", e);
logger.error("公用方法生成表语句:" + sb.toString());
}
return 0;
}
}
这个对于之前写的那个动态建表,新增了过滤不需要在表中创建的字段
原理就是读取对象的各个字段属性,如果能加以配置文件或者读取对象属性的标记,那其实能做到基本和Hibernate一致,不但能支持多种类型,还能做字段校验等
相关文章推荐
- 传入Java对象 自动创建动态表 并录入数据
- 传入Java对象 自动创建动态表 并录入数据
- protobuf在java应用中通过反射动态创建对象
- 【JAVA学习】java基本数据类型与字符串之间的转换(基本数据类型、对象封装类、自动装箱、自动拆箱)
- java 反射创建对象并传入参数
- 编写程序从标准输入设备读入的元素数据建立一个int型vector对象,然后动态创建与该vector大小一致的数组,把vector对象的所有元素复制给该数组
- 利用DB2数据字典自动创建表对应的Java Model
- 学习android JNI的那些事儿--------6. 在java中传入引用数据类型(对象)作为参数
- 自己在项目中的学习总结:利用工厂模式+反射机制+缓存机制,实现动态创建不同的数据层对象接口
- 简单数据访问类,生成简单SQL,自动转换成java对象
- java中使用字符串或者动态创建对象的三种方法(Class,Constructor,Proxy)
- java动态代理对象实例的创建
- [Java]利用反射机制动态加载并创建包含参数的对象
- SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(上)
- 关于使用动态代理创建代理对象是报错 java.lang.ClassCastException: $Proxy0 cannot be cast to 的解决办法
- Spring 框架下,用数组作为参数 传入到 存储过程,或存储过程返回动态数组到java程序 ,BLOB等大对象类似
- 利用Java反射机制和Javassist实现Java对象及其属性的动态创建生成
- 思路,GV 动态绑定数据,(自动适应创建行与列)
- thinkphp自动创建数据对象分析
- 如何创建一个动态的数据窗口对象